POST
/token
Token
Summary
Exchanges an authorization code (+ PKCE verifier) for tokens, or rotates a refresh token. Form-encoded body (application/x-www-form-urlencoded).
Auth
Confidential clients: client_id + client_secret (client_secret_post). Public clients: client_id only (token_endpoint_auth_method=none).
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
grant_type |
body | yes | string | `authorization_code` or `refresh_token`. |
code |
body | no | string | One-time authorization code (code grant). |
redirect_uri |
body | no | string | Must match the authorize request (code grant). |
code_verifier |
body | no | string | PKCE verifier, 43–128 unreserved chars (code grant). |
refresh_token |
body | no | string | Previously issued refresh token. |
client_id |
body | yes | string | Registered client identifier. |
client_secret |
body | no | string | Required unless the client uses auth method none. |
Example request
POST /token HTTP/1.1
Host: <issuer-host>
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&code=CODE&redirect_uri=https%3A%2F%2Fapp.example%2Fcallback&client_id=CLIENT_ID&code_verifier=VERIFIER
Success
JSON with access_token, token_type (Bearer), expires_in, id_token (when openid), and refresh_token when offline_access was granted. Refresh uses rotation with reuse detection (compromised family is revoked).
Errors
| Code | Description |
|---|---|
invalid_client |
Unknown client or bad credentials (often HTTP 401). |
invalid_grant |
Bad/expired code, PKCE failure, or refresh reuse. |
invalid_request |
Missing required fields for the grant. |
unsupported_grant_type |
Only authorization_code and refresh_token. |
Notes
- Only authorization_code and refresh_token grants are supported.
- PKCE verification is required on the code grant (S256).