Skip to developer documentation
Browse developer documentation
API documentation

Get started

OAuth for applications

Connect an application with account-holder approval, PKCE and rotating refresh tokens.

Discover the authorization server

These URLs use the site origin, not the /api/v1 base. MCP clients can discover the resource and authorization server automatically. The REST API accepts the resulting Bearer access token with the same approved workspace and scopes.

MethodPathPurpose
GET/.well-known/oauth-authorization-serverAuthorization, registration, token and revocation metadata
GET/.well-known/openid-configurationAuthorization metadata alias; do not assume an OIDC ID-token flow
GET/.well-known/oauth-protected-resourceMCP resource and authorization server
POST/api/oauth/registerRegister a client
GET/oauth/authorizeInteractive account-holder approval
POST/api/oauth/tokenExchange code or rotate refresh token
POST/api/oauth/revokeRevoke a token
bash
curl "https://www.attriboo.com/.well-known/oauth-authorization-server"

Register your application

POST /api/oauth/register accepts redirect_uris (required), client_name, client_uri, logo_uri and token_endpoint_auth_method. Public clients use none. Confidential clients can use client_secret_post or client_secret_basic; save the returned secret privately.

Redirects must be HTTPS, loopback HTTP or an allowed app scheme. Fragments and unsafe schemes are rejected. Success is HTTP 201 and includes client_id, redirect_uris, grant_types, response_types, token_endpoint_auth_method and scope. Registration does not grant access to customer data.

bash
curl -X POST "https://www.attriboo.com/api/oauth/register" \
  -H "Content-Type: application/json" \
  --data '{"client_name":"Example reporting app","redirect_uris":["https://app.example.com/callback"],"token_endpoint_auth_method":"none"}'

Request interactive approval with PKCE

Generate a cryptographically random code_verifier, compute its SHA-256 digest, and encode the digest as unpadded base64url for code_challenge. Store the verifier and an unpredictable state privately for this login attempt.

Open /oauth/authorize with response_type=code, client_id, the exact registered redirect_uri, scope=analytics:read, code_challenge, code_challenge_method=S256 and state. Request analytics:read sites:write only when website setup is needed. Validate the returned state and issuer against your saved attempt before exchanging the code.

The account holder signs in and chooses/approves the workspace. There is no anonymous account-creation API, device-code endpoint or unattended provider authorization. Authorization codes expire after ten minutes and can be used once.

text
https://www.attriboo.com/oauth/authorize?response_type=code&client_id=YOUR_CLIENT_ID&redirect_uri=https%3A%2F%2Fapp.example.com%2Fcallback&scope=analytics%3Aread&code_challenge=YOUR_S256_CHALLENGE&code_challenge_method=S256&state=YOUR_RANDOM_STATE

Exchange the authorization code

POST form-encoded parameters to /api/oauth/token. Include grant_type=authorization_code, client_id, code, redirect_uri and code_verifier. Confidential clients must also authenticate with their registered secret method.

The raw JSON result contains access_token, token_type: Bearer, expires_in: 3600, refresh_token and scope. These are sensitive credentials. Use access_token in the REST Authorization header or the MCP client.

bash
curl -X POST "https://www.attriboo.com/api/oauth/token" \
  --data-urlencode "grant_type=authorization_code" \
  --data-urlencode "client_id=$ATTRIBOO_CLIENT_ID" \
  --data-urlencode "code=$ATTRIBOO_CODE" \
  --data-urlencode "redirect_uri=https://app.example.com/callback" \
  --data-urlencode "code_verifier=$ATTRIBOO_CODE_VERIFIER"

Refresh and revoke

Refresh with grant_type=refresh_token, client_id and refresh_token at the same token endpoint. Authenticate a confidential client as registered. Each successful refresh returns a replacement refresh token: save it atomically. A consumed refresh token cannot be used again; keep the replacement to continue the connection.

POST token to /api/oauth/revoke to disconnect. It returns an empty HTTP 200 even for an unknown token. OAuth errors use raw error and error_description fields, not the report error envelope.

bash
curl -X POST "https://www.attriboo.com/api/oauth/token" \
  --data-urlencode "grant_type=refresh_token" \
  --data-urlencode "client_id=$ATTRIBOO_CLIENT_ID" \
  --data-urlencode "refresh_token=$ATTRIBOO_REFRESH_TOKEN"

curl -X POST "https://www.attriboo.com/api/oauth/revoke" \
  --data-urlencode "token=$ATTRIBOO_REFRESH_TOKEN"