v1oauth context
Token exchange
POST /v1/oauth/token — three grant types, client authentication methods and response fields.
POST {issuer}/token, with an application/x-www-form-urlencoded body and a Cache-Control: no-store response.
This page covers the contract only; the full parameters and samples for each grant type are in Token exchange and refresh.
Client authentication
| Method | Applies to | How |
|---|---|---|
client_secret_basic | Confidential clients (recommended) | Authorization: Basic base64(client_id:client_secret) |
client_secret_post | Confidential clients | client_id and client_secret in the form body |
none | Public clients | Only client_id in the form body |
Grant types
grant_type | Scenario | Key parameters |
|---|---|---|
authorization_code | Exchange a code after user consent | code, redirect_uri, code_verifier |
refresh_token | Refresh | refresh_token; scope may only narrow |
client_credentials | Server-to-server (machine clients) | scope |
Response
{
"token_type": "Bearer",
"expires_in": 3600,
"access_token": "eyJ...",
"refresh_token": "eyJ...",
"scope": "openid profile email offline_access",
"id_token": "eyJ..."
}| Field | Notes |
|---|---|
access_token | The access token |
refresh_token | Returned only when the scope includes offline_access |
id_token | Returned when openid was requested |
scope | The scope actually granted, possibly narrowed |
expires_in | 3600 seconds for web_server, 1800 for public-client platforms |
Rules
| Rule | Notes |
|---|---|
| No caching | The response always carries no-store |
| Refresh means rotate | The old refresh token dies immediately; clients must overwrite it |
| Do not parse the refresh token | It is a signed JWT; clients must not depend on its internals |
| Refresh does not restore authorization details | authorization_details only holds for the original authorization |
| Rate limited | Per IP; over the limit returns 429, not 500 |
Related
- Full parameters and samples: Token exchange and refresh
- Revocation: Revocation
- Error codes: Error codes