Reference
Endpoints, scopes, protocol errors and the settings that control the OAuth Server.
Everything the authorization server exposes, in one place. For SDK method
signatures see auth.oauth; for nulvless error codes see
Error codes.
All paths are relative to your issuer.
Endpoints
| Method | Path | Auth | What it does |
|---|---|---|---|
GET | /.well-known/openid-configuration | public | Discovery document |
GET | /.well-known/jwks.json | public | Public signing keys |
GET | /oauth/authorize | public | Starts the flow, redirects to your consent screen |
GET | /oauth/authorizations/:id | session | What a pending authorization is asking for |
POST | /oauth/authorizations/:id/consent | session | Records approve or deny |
POST | /oauth/token | client | Exchanges a code, or refreshes |
GET | /oauth/userinfo | bearer | Claims for the granted scopes |
POST | /oauth/register | public | Dynamic client registration, when enabled |
"Public" means no API key. The two authorization endpoints act on behalf of the signed-in user, which is what ties consent to a person.
GET /oauth/authorize
| Parameter | Required | Notes |
|---|---|---|
client_id | yes | |
redirect_uri | yes | Exact match against a registered URI |
response_type | yes | code |
code_challenge | yes | Base64url SHA-256 of the verifier |
code_challenge_method | yes | S256 |
scope | no | Space separated; defaults to email |
state | no | Returned untouched |
nonce | no | Echoed into the ID token |
resource | no | The API the token is for |
Answers 403 when the OAuth Server is disabled for the environment.
POST /oauth/token
| Parameter | authorization_code | refresh_token |
|---|---|---|
grant_type | required | required |
code | required | — |
redirect_uri | required | — |
code_verifier | required | — |
refresh_token | — | required |
client_id | required | required |
client_secret | confidential clients | confidential clients |
{
"access_token": "…",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "…",
"id_token": "…"
}id_token is present only when openid was granted.
Scopes
| Scope | Claims |
|---|---|
openid | Issues an ID token |
email | email, email_verified |
profile | name, picture |
phone | phone_number, phone_number_verified |
Protocol errors
These are OAuth 2.1 error strings, distinct from nulvless error codes. Where they surface depends on whether the redirect URI has been validated — see the flow.
| Error | Meaning |
|---|---|
invalid_request | Missing or malformed parameter |
invalid_client | Unknown client, or bad secret |
invalid_grant | Code expired, already used, or code_verifier does not match |
unauthorized_client | Client may not use this grant type |
unsupported_response_type | Anything other than code |
invalid_scope | Scope not in the supported set |
access_denied | The user pressed Deny |
server_error | Fault on our side |
The two worth handling specifically are invalid_grant — usually a replayed or
expired code, and always a restart of the flow — and access_denied, which is a
user decision and should be a calm message rather than an error page.
Settings
Found in the Console under OAuth Server, per environment.
Enabledboolean, default offOptionalWhile off, /oauth/authorize answers 403.
Consent screen URLdefaults to Site URLOptionalBase URL of your consent screen, for when it is not hosted on your Site URL.
Authorization pathdefault /oauth/consentOptionalPath of your consent screen, appended to the URL above.
Allow dynamic clientsboolean, default offOptionalEnables POST /oauth/register. See
the trade-off.
Site URL lives under the project's URL settings, not here — it is the same value used for confirmation links.
Caching
| Response | Header |
|---|---|
| Discovery document | Cache-Control: public, max-age=3600 |
| JWKS | Cache-Control: public, max-age=600 |
| Everything else | Cache-Control: no-store |
no-store on token responses is required by RFC 6749 §5.1 and OpenID Connect
Core §3.1.3.3. The two public documents opt out deliberately, because every
client fetches them constantly and they contain no secrets.