OIDC endpoints
The protocol surface. All endpoints listed below are also published in the
discovery document at /.well-known/openid-configuration — always read from there
rather than hard-coding URLs.
Discovery
The canonical entry point.
GET /.well-known/openid-configuration Returns the standard OIDC discovery JSON. Key fields:
- issuer
- Use this verbatim in any
id_tokenverification step. - authorization_endpoint
- Where you send the user to authorize. Hit with a
GET. - token_endpoint
- Auth-code-for-tokens exchange.
POST, form-encoded. - userinfo_endpoint
- Profile fetch using an access token.
GETorPOST. - jwks_uri
- Signing keys for
id_tokenverification. - scopes_supported
- Every scope this server knows. See Scopes reference.
- response_types_supported
- Only
code— authorization code flow, not implicit, not hybrid. - subject_types_supported
- Only
pairwise. See How it works. - id_token_signing_alg_values_supported
- Only
EdDSA. Choose a library that supports it. - code_challenge_methods_supported
S256. PKCE is mandatory for every flow, public or confidential.
Authorization
GET /oauth2/authorize Query parameters:
- response_type
- Must be
code. - client_id
- From the developer dashboard.
- redirect_uri
- Must exactly match one of the URIs you registered.
- scope
- Space-separated scope list. Always include
openid. - state
- Required. CSRF guard — verify on callback.
- code_challenge
- Required. SHA-256 of your code_verifier, base64url-encoded.
- code_challenge_method
- Must be
S256. - nonce
- Optional but recommended. Bound into the
id_tokenfor replay protection. - prompt
- Optional.
none= silent re-auth; fails withlogin_requiredif not signed in.consent= force re-prompt even if previously consented.
On success the user lands at your redirect_uri with ?code=…&state=…. On user denial or error,
with ?error=access_denied (or another error code)
plus the same state.
Token exchange
POST /oauth2/token
Content-Type: application/x-www-form-urlencoded Two grant types:
Authorization code
grant_type=authorization_code
&code=...
&redirect_uri=...
&code_verifier=... Confidential clients additionally authenticate via the Authorization: Basic base64(client_id:client_secret) header.
Public clients send client_id in the body.
Refresh
grant_type=refresh_token
&refresh_token=...
&client_id=... Successful response (both grants):
{
"access_token": "eyJhbGciOiJFZERTQSI...",
"id_token": "eyJhbGciOiJFZERTQSI...",
"refresh_token": "...",
"token_type": "Bearer",
"expires_in": 900
} Userinfo
GET /oauth2/userinfo
Authorization: Bearer ACCESS_TOKEN Returns a JSON object with the pairwise sub plus every claim
the user consented to. Fields they didn't consent to are absent (not null). See Token claims.
JWKS
GET /oauth2/jwks Returns the JWKS document with our public signing keys (EdDSA). Cache
per the response's Cache-Control header — we rotate keys
periodically and your library will pick up the new key when it fetches
on next cache miss.
Revocation
POST /oauth2/revoke
Content-Type: application/x-www-form-urlencoded
Authorization: Basic base64(client_id:client_secret)
token=THE_TOKEN
&token_type_hint=refresh_token Revokes the token (and any descendants for a refresh token). Always
returns 200 per RFC 7009.
Standards alignment
- OpenID Connect Core 1.0 — full subset for authorization-code flow
- OpenID Connect Discovery 1.0
- RFC 6749 OAuth 2.0 — authorization-code + refresh-token grants
- RFC 7636 PKCE — required for every flow
- RFC 7009 Token Revocation
- RFC 8414 OAuth 2.0 Authorization Server Metadata