Skip to content
PuraPura Developers
Developers/OAuth and consent

OAuth and consent

Authorization Code with PKCE S256, scopes and verified identity.

Authorization flow

Generate a random code_verifier and its S256 code_challenge. Send the browser to GET /v1/integrations/oauth/authorize with response_type=code, client_id, redirect_uri, scope and random state. Pura validates the app before displaying login and consent. The user can accept or deny.

After consent the app receives code and state at the registered redirect. The code expires after five minutes and is single-use. Confidential clients must also present the correct code_verifier.

Scopes

inference authorizes service capability checks and chat/audio requests. usage:read authorizes GET /v1/integrations/usage. Request only necessary scopes; a grant does not authorize app or account payment management.

Code exchange

POST /v1/integrations/oauth/token uses application/x-www-form-urlencoded, not JSON. For authorization_code send client_id, code, redirect_uri and code_verifier; add client_secret only for confidential clients. The response includes access_token, refresh_token, token_type, expires_in, scope and pura_user_id.

bash
curl https://ai.puradigital.it/v1/integrations/oauth/token \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode grant_type=authorization_code \
  --data-urlencode client_id=YOUR_CLIENT_ID \
  --data-urlencode code=YOUR_AUTHORIZATION_CODE \
  --data-urlencode redirect_uri=https://your-app.example/pura/callback \
  --data-urlencode code_verifier=YOUR_PENDING_VERIFIER

Bind identity on the server

The Pura identity comes from the token endpoint response. Bind it to the local session that initiated the flow; do not accept pura_user_id from an unverified browser body. Webhooks must match this existing saved mapping.

Denial and errors

Denial returns error=access_denied and state at a valid redirect. Incorrect state, a different callback, expired code or incorrect verifier require a new Connect. The token endpoint uses OAuth error and error_description; other endpoints use their documented HTTP detail.