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.
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_VERIFIERBind 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.