OAuth 2.0 and OpenID Connect
Use authorization code with S256 PKCE for interactive login. Start with the OAuth integration guide. Tokens from this protocol are separate from the application tokens returned by /login/. Examples show possible response shapes; available identity fields depend on the grant and requested scopes.
API conventions · All endpoints · Schemas
/e/v1/auth/jwt-to-session/
Create a browser authentication session from an application JWT.
Availability note: standalone access with the credential described below has a known authentication limitation. Check integration availability before relying on this operation. If it returns an unexpected 401, contact support with the endpoint and sanitized response.
POST
Required JSON token (valid application JWT). Preserve the returned Set-Cookie for subsequent hosted OAuth requests. See the availability note before using this bridge.
Request fields (combine with the requirements and schema above):
| Location | Field | Fallback when absent |
|---|---|---|
| body | token | not supplied |
Example request body:
{
"token": "APPLICATION_JWT"
}
Success and error response examples
Illustrative values; conditional branches are alternatives. Fields vary with the operation and account configuration.
200 — json
{
"message": "Session created successfully",
"user_id": "EXAMPLE_USER_ID",
"session_key": "EXAMPLE_SESSION_KEY",
"session_expiry": "EXAMPLE_SESSION_EXPIRY",
"debug_info": {
"session_cookie_name": "EXAMPLE_SESSION_COOKIE_NAME",
"session_cookie_domain": "EXAMPLE_SESSION_COOKIE_DOMAIN",
"session_cookie_secure": "EXAMPLE_SESSION_COOKIE_SECURE",
"session_cookie_samesite": "EXAMPLE_SESSION_COOKIE_SAMESITE",
"current_cookies": "EXAMPLE_CURRENT_COOKIES"
}
}
400 — json
{
"error": "JWT token is required"
}
400 — json
{
"error": "Invalid token payload"
}
400 — json
{
"error": "User not found"
}
401 — json
{
"error": "Token expired"
}
401 — json
{
"error": "Invalid token"
}
500 — json
{
"error": "Internal server error: EXAMPLE"
}
/e/v1/oauth/consent/approve/
Approve or deny consent through the frontend JSON API.
POST
Required JSON consent_token; approved must be boolean true to approve. Requires live consent state in the matching session/cache. Returns redirect_url and status rather than issuing a redirect response.
Request fields (combine with the requirements and schema above):
| Location | Field | Fallback when absent |
|---|---|---|
| body | consent_token | not supplied |
| body | approved | not supplied |
Example request body:
{
"consent_token": "CONSENT_TOKEN",
"approved": true
}
Success and error response examples
Illustrative values; conditional branches are alternatives. Fields vary with the operation and account configuration.
200 — json
{
"redirect_url": "EXAMPLE_REDIRECT_URL",
"status": "denied"
}
200 — json
{
"redirect_url": "EXAMPLE_REDIRECT_URL",
"status": "approved"
}
400 — json
{
"error": "invalid_request",
"error_description": "Missing consent token"
}
400 — json
{
"error": "invalid_request",
"error_description": "Invalid or expired consent token"
}
400 — json
{
"error": "invalid_request",
"error_description": "Consent session expired"
}
500 — json
{
"error": "unexpected_response",
"error_description": "Authorization handler returned an unexpected response type"
}
500 — json
{
"error": "server_error",
"error_description": "An unexpected error occurred: EXAMPLE"
}
500 — json
{
"error": "server_error",
"error_description": "User not found"
}
e.status_code — json
{
"error": "EXAMPLE_ERROR",
"error_description": "EXAMPLE_ERROR_DESCRIPTION"
}
/e/v1/oauth/authorize/
Start authorization or submit the hosted consent decision.
Browser application-user session; unauthenticated browsers are redirected to hosted login. Retain cookies and state through the redirect chain.
GET
Required query strings: client_id, redirect_uri, response_type (use code). Optional scope (space-delimited), state, nonce. Public clients require PKCE: code_challenge plus code_challenge_method=S256, or a valid initialized pkce_session_id. Use an exact registered redirect URI. Supported response branches also include token/id_token combinations in the implementation; authorization code with PKCE is the documented first integration.
Request fields (combine with the requirements and schema above):
| Location | Field | Fallback when absent |
|---|---|---|
| query | temp_auth | not supplied |
| query | client_id | not supplied |
| query | redirect_uri | not supplied |
| query | response_type | not supplied |
| query | state | not supplied |
| query | pkce_session_id | not supplied |
| query | scope | '' |
| query | code_challenge | not supplied |
| query | code_challenge_method | not supplied |
| query | nonce | not supplied |
Success and error response examples
Illustrative values; conditional branches are alternatives. Fields vary with the operation and account configuration.
302 — redirect
Redirect: inspect Location and preserve cookies.
500 — json
{
"error": "server_error",
"error_description": "An unexpected error occurred: EXAMPLE"
}
e.status_code — json
{
"error": "EXAMPLE_ERROR",
"error_description": "EXAMPLE_ERROR_DESCRIPTION"
}
POST
Form body: required consent_token; approved=true grants consent (literal form string). Requires matching consent session/cache state. This is distinct from JSON /oauth/consent/approve/.
Request fields (combine with the requirements and schema above):
| Location | Field | Fallback when absent |
|---|---|---|
| form | consent_token | not supplied |
| form | approved | not supplied |
Success and error response examples
Illustrative values; conditional branches are alternatives. Fields vary with the operation and account configuration.
302 — redirect
Redirect: inspect Location and preserve cookies.
400 — json
{
"error": "invalid_request",
"error_description": "Missing consent token"
}
400 — json
{
"error": "invalid_request",
"error_description": "Invalid or expired consent token"
}
400 — json
{
"error": "invalid_request",
"error_description": "Consent session expired"
}
500 — json
{
"error": "server_error",
"error_description": "An unexpected error occurred: EXAMPLE"
}
e.status_code — json
{
"error": "EXAMPLE_ERROR",
"error_description": "EXAMPLE_ERROR_DESCRIPTION"
}
/e/v1/oauth/token/
Exchange a code, refresh an OAuth token, or issue a client-credentials token.
Confidential clients: HTTP Basic client_id:client_secret or body credentials. Public clients: body client_id with PKCE, no secret. Client ID refers to the public identifier.
POST
Accepts JSON or form data. Required grant_type: authorization_code, refresh_token, or client_credentials. Code grant: required code, redirect_uri, plus code_verifier or valid server-side pkce_session_id when PKCE was used. Refresh grant: required refresh_token. Client credentials: optional space-delimited scope, restricted to configured grants/scopes. The handler does not implement grant_type=password.
Example request body:
{
"grant_type": "authorization_code",
"client_id": "PUBLIC_CLIENT_ID",
"code": "AUTHORIZATION_CODE",
"redirect_uri": "http://127.0.0.1:8080/callback",
"code_verifier": "ORIGINAL_PKCE_VERIFIER"
}
Success and error response examples
Illustrative values; conditional branches are alternatives. Fields vary with the operation and account configuration.
200 — json
{
"access_token": "OAUTH_ACCESS_TOKEN",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "OAUTH_REFRESH_TOKEN",
"scope": "openid profile email",
"id_token": "OIDC_ID_TOKEN_WHEN_OPENID_REQUESTED"
}
200 — json
JSON response varies with the request. See the operation requirements and linked schema; validation errors may be keyed by field name.
500 — json
{
"error": "server_error",
"error_description": "An internal server error occurred"
}
e.status_code — json
{
"error": "EXAMPLE_ERROR",
"error_description": "EXAMPLE_ERROR_DESCRIPTION"
}
OPTIONS
No additional JSON payload is read by this operation.
Success and error response examples
Illustrative values; conditional branches are alternatives. Fields vary with the operation and account configuration.
200 — text/XML
HTML or text/XML response; do not parse as JSON.
/e/v1/oauth/pkce/init/
Create a server-side PKCE session.
Availability note: standalone access with the credential described below has a known authentication limitation. Check integration availability before relying on this operation. If it returns an unexpected 401, contact support with the endpoint and sanitized response.
OPTIONS
No additional JSON payload is read by this operation.
Success and error response examples
Illustrative values; conditional branches are alternatives. Fields vary with the operation and account configuration.
200 — json
JSON response varies with the request. See the operation requirements and linked schema; validation errors may be keyed by field name.
POST
Required JSON client_id (active public protocol ID). Returns a session identifier and S256 challenge; carry pkce_session_id into authorization and token exchange. This is not required when your application securely retains its own verifier.
Request fields (combine with the requirements and schema above):
| Location | Field | Fallback when absent |
|---|---|---|
| body | client_id | not supplied |
Example request body:
{
"client_id": "PUBLIC_CLIENT_ID"
}
Success and error response examples
Illustrative values; conditional branches are alternatives. Fields vary with the operation and account configuration.
200 — json
{
"session_id": "PKCE_SESSION_ID",
"code_challenge": "BASE64URL_SHA256",
"code_challenge_method": "S256"
}
200 — json
JSON response varies with the request. See the operation requirements and linked schema; validation errors may be keyed by field name.
400 — json
{
"error": "client_id is required"
}
400 — json
{
"error": "Invalid client_id"
}
/e/v1/oauth/revoke/
Revoke an OAuth token.
Client authentication uses Basic or body client credentials, following the token endpoint rules.
POST
JSON or form: required token, plus client identity; optional token_type_hint. Success is 200 with {} even when the supplied token is not found, after client validation.
Example request body:
{
"client_id": "PUBLIC_CLIENT_ID",
"token": "OAUTH_ACCESS_TOKEN",
"token_type_hint": "access_token"
}
Success and error response examples
Illustrative values; conditional branches are alternatives. Fields vary with the operation and account configuration.
200 — json
{}
500 — json
{
"error": "server_error",
"error_description": "An unexpected error occurred"
}
e.status_code — json
{
"error": "EXAMPLE_ERROR",
"error_description": "EXAMPLE_ERROR_DESCRIPTION"
}
/e/v1/oauth/userinfo/
Return OIDC user claims permitted by the access token.
Required Authorization: Bearer OAUTH_ACCESS_TOKEN.
GET
No body; claim availability follows scopes.
Success and error response examples
Illustrative values; conditional branches are alternatives. Fields vary with the operation and account configuration.
200 — json
{
"sub": "11111111-1111-4111-8111-111111111111",
"email": "[email protected]",
"email_verified": true,
"given_name": "Alex",
"family_name": "Developer"
}
200 — json
JSON response varies with the request. See the operation requirements and linked schema; validation errors may be keyed by field name.
401 — json
{
"error": "invalid_token",
"error_description": "Invalid or missing access token"
}
500 — json
{
"error": "server_error",
"error_description": "An unexpected error occurred"
}
status_code — json
{
"error": "EXAMPLE_ERROR"
}
POST
Same as GET; the access token is read from Authorization, not the JSON body.
Success and error response examples
Illustrative values; conditional branches are alternatives. Fields vary with the operation and account configuration.
200 — json
{
"sub": "11111111-1111-4111-8111-111111111111",
"email": "[email protected]",
"email_verified": true,
"given_name": "Alex",
"family_name": "Developer"
}
200 — json
JSON response varies with the request. See the operation requirements and linked schema; validation errors may be keyed by field name.
401 — json
{
"error": "invalid_token",
"error_description": "Invalid or missing access token"
}
500 — json
{
"error": "server_error",
"error_description": "An unexpected error occurred"
}
status_code — json
{
"error": "EXAMPLE_ERROR"
}
/e/v1/.well-known/jwks.json
Publish the configured OIDC public signing key.
GET
Public; no input. Needs a valid configured PEM public key. Use its kid to select the verifier key.
Success and error response examples
Illustrative values; conditional branches are alternatives. Fields vary with the operation and account configuration.
200 — json
{
"keys": [
{
"kty": "RSA",
"use": "sig",
"kid": "1",
"alg": "RS256",
"n": "RSA_MODULUS_BASE64URL",
"e": "AQAB"
}
]
}
200 — json
{
"keys": [
{
"kty": "RSA",
"use": "sig",
"alg": "EXAMPLE_ALG",
"kid": "EXAMPLE_KID",
"n": "EXAMPLE_N",
"e": "EXAMPLE_E"
}
]
}
500 — json
{
"error": "configuration_error",
"error_description": "Public key not configured"
}
500 — json
{
"error": "configuration_error",
"error_description": "Invalid public key format"
}
500 — json
{
"error": "server_error",
"error_description": "An error occurred while generating JWKS"
}
/e/v1/.well-known/openid-configuration
Publish OIDC discovery metadata.
GET
Public; no input. The issuer and endpoints derive from OIDC configuration. Verify local issuer values before integrating.
Success and error response examples
Illustrative values; conditional branches are alternatives. Fields vary with the operation and account configuration.
200 — json
{
"issuer": "http://127.0.0.1:8002/e/v1",
"authorization_endpoint": "http://127.0.0.1:8002/e/v1/oauth/authorize/",
"token_endpoint": "http://127.0.0.1:8002/e/v1/oauth/token/",
"userinfo_endpoint": "http://127.0.0.1:8002/e/v1/oauth/userinfo/",
"jwks_uri": "http://127.0.0.1:8002/e/v1/.well-known/jwks.json"
}
200 — json
JSON response varies with the request. See the operation requirements and linked schema; validation errors may be keyed by field name.
500 — json
{
"error": "server_error",
"error_description": "An error occurred while generating discovery document"
}
/e/v1/oauth/clients/{client_id}/branding/
Read public hosted-login branding.
GET
No authentication; path value is the public client_id. Returns branding or null. Invalid client returns 404.
Path parameters: client_id (str, required).
Related schemas: OAuthClientBranding.
Success and error response examples
Illustrative values; conditional branches are alternatives. Fields vary with the operation and account configuration.
200 — json
{
"id": "11111111-1111-4111-8111-111111111111",
"oauth_client": "11111111-1111-4111-8111-111111111111",
"logo_url": "EXAMPLE_LOGO_URL",
"company_name": "EXAMPLE_COMPANY_NAME",
"primary_color": "EXAMPLE_PRIMARY_COLOR",
"secondary_color": "EXAMPLE_SECONDARY_COLOR",
"background_color": "EXAMPLE_BACKGROUND_COLOR",
"theme": "light",
"custom_css": "EXAMPLE_CUSTOM_CSS",
"show_social_logins": true,
"terms_url": "https://app.example.test/callback",
"privacy_url": "https://app.example.test/callback",
"created_at": "2026-10-26T12:00:00Z",
"updated_at": "2026-10-26T12:00:00Z"
}
200 — json
JSON response varies with the request. See the operation requirements and linked schema; validation errors may be keyed by field name.
404 — json
{
"error": "OAuth client not found"
}
500 — json
{
"error": "Failed to fetch branding"
}