The OAuth2 surface follows OAuth 2.0 + OIDC conventions. Endpoints live at the tenant root (no /api/v1/ prefix) so they match the patterns from standard libraries and other IdPs.
The per-flow guides in OAuth & OIDC flows walk the user-facing usage. This topic is the per-endpoint reference.
/oauth2/authorize (public, browser-redirect)
Section titled “/oauth2/authorize (public, browser-redirect)”GET /oauth2/authorize ?response_type=code &client_id=app_01HZX... &redirect_uri=https://app.cymmetri.com/callback &scope=openid+profile+email+offline_access &state=<random> &code_challenge=<base64url-sha256> &code_challenge_method=S256 &nonce=<random>User-facing. The browser is sent here; the user signs in; the browser is redirected to redirect_uri?code=<auth-code>&state=<state>.
Required parameters: response_type, client_id, redirect_uri, scope, state.
For PKCE: code_challenge + code_challenge_method=S256. Without these, public clients (SPAs, native) get refused.
/oauth2/token (public, POST)
Section titled “/oauth2/token (public, POST)”The grant-type-multiplexed token endpoint.
POST /oauth2/tokenContent-Type: application/x-www-form-urlencoded
grant_type=<grant>&...other-paramsSupported grant_type values:
| Grant | Purpose |
|---|---|
authorization_code | Exchange an auth code for tokens (see PKCE web) |
refresh_token | Refresh an access token, with rotation |
client_credentials | Machine-to-machine (see Client credentials) |
urn:ietf:params:oauth:grant-type:device_code | Device code flow (see Device code) |
urn:ietf:params:oauth:grant-type:token-exchange | Token exchange / down-scoping (see Token exchange) |
Common response:
{ "access_token": "...", "refresh_token": "...", "id_token": "...", "token_type": "Bearer", "expires_in": 3600, "scope": "openid profile email offline_access"}refresh_token only present if the request included offline_access (for human flows) or if the grant type is refresh_token (in which case the new refresh token replaces the old).
/oauth2/revoke (public, POST)
Section titled “/oauth2/revoke (public, POST)”POST /oauth2/revokeContent-Type: application/x-www-form-urlencoded
token=<access-or-refresh-token>&token_type_hint=refresh_token&client_id=app_01HZX...Always returns 200 OK per RFC 7009 (even if the token didn't exist). See the token revocation guide for what each token type's revocation actually does.
/oauth2/device_authorization (public, POST)
Section titled “/oauth2/device_authorization (public, POST)”POST /oauth2/device_authorizationContent-Type: application/x-www-form-urlencoded
client_id=app_01HZX...&scope=openid+profile+emailResponse:
{ "device_code": "abc...long...", "user_code": "WDJB-MJHT", "verification_uri": "https://banking-cymmetri.intelliauth.local/activate", "verification_uri_complete": "https://banking-cymmetri.intelliauth.local/activate?user_code=WDJB-MJHT", "expires_in": 1800, "interval": 5}The device polls /oauth2/token with grant_type=urn:ietf:params:oauth:grant-type:device_code until the user signs in. See the device code guide.
/oauth2/userinfo (authenticated)
Section titled “/oauth2/userinfo (authenticated)”GET /oauth2/userinfoAuthorization: Bearer <access-token>Returns the user's claims:
{ "sub": "usr_01HZX...", "email": "user@cymmetri.com", "email_verified": true, "name": "User Name", "picture": "https://..."}The fields are determined by the scopes the access token carries. openid → sub only. profile adds the name fields. email adds the email pair.
/oauth2/logout (browser-redirect)
Section titled “/oauth2/logout (browser-redirect)”GET /oauth2/logout ?id_token_hint=<the-user's-id-token> &post_logout_redirect_uri=https://app.cymmetri.com/goodbye &state=<random>Standard OIDC end-session endpoint. Clears the IntelliAuth session cookie and redirects to post_logout_redirect_uri. The post_logout_redirect_uri must be registered on the application.
/oauth2/introspect (authenticated)
Section titled “/oauth2/introspect (authenticated)”POST /oauth2/introspectAuthorization: Basic <base64(client_id:client_secret)>Content-Type: application/x-www-form-urlencoded
token=<access-token>&token_type_hint=access_tokenReturns:
{ "active": true, "client_id": "app_01HZX...", "username": "user@cymmetri.com", "scope": "openid profile email", "sub": "usr_01HZX...", "aud": "https://api.cymmetri.com", "iss": "https://banking-cymmetri.intelliauth.local", "exp": 1715900400, "iat": 1715896800}Used by resource servers that want to validate tokens against the live platform (catches revocations immediately) instead of validating the JWT signature locally.
/.well-known/openid-configuration (public, GET)
Section titled “/.well-known/openid-configuration (public, GET)”Discovery document. See OIDC discovery for the full shape.
/.well-known/jwks.json (public, GET)
Section titled “/.well-known/jwks.json (public, GET)”The public key set used to sign id tokens. Refresh on kid miss.