Authentication

Account registration, login, OAuth, password reset, token refresh, session lifecycle, MFA, and OAuth device-authorization for CLI/MCP clients.

54 endpoints. Generated from the OpenAPI 3.1 specification.

GET /.well-known/oauth-authorization-server

OAuth 2.0 authorization server metadata

Returns RFC 8414 authorization server metadata (also served at `/.well-known/openid-configuration`). Describes all OAuth 2.1 endpoints, supported grant types, PKCE methods, and dynamic client registration endpoint.

Auth

Responses

StatusDescription
200 Authorization server metadata document.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
GET /.well-known/oauth-protected-resource

OAuth 2.0 protected resource metadata

Returns RFC 9728 protected-resource metadata for the MCP API surface. Lists the authorization server(s) and supported bearer methods.

Auth

Responses

StatusDescription
200 Protected resource metadata document.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
GET /.well-known/oauth-protected-resource/v1/mcp

OAuth 2.0 protected resource metadata (MCP path variant)

Alternative path for RFC 9728 protected-resource metadata targeting `/v1/mcp` specifically. Returns the same document as `/.well-known/oauth-protected-resource`.

Auth

Responses

StatusDescription
200 Protected resource metadata document.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
GET /.well-known/openid-configuration

OpenID Connect discovery document

Alias for `/.well-known/oauth-authorization-server`. Returns the same RFC 8414 authorization server metadata. Provided for compatibility with OpenID Connect clients.

Auth

Responses

StatusDescription
200 Authorization server metadata document.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
GET /oauth/authorize

OAuth 2.0 authorization endpoint

Initiates the OAuth 2.0 authorization code flow with PKCE (S256 required, plain rejected per RFC 7636 §4.6). Redirects the user to the consent page on success, or returns an RFC 6749 error response.

Auth

Parameters

NameInTypeRequiredDescription
response_type query string (enum) yes
client_id query string yes
redirect_uri query string<uri> yes
code_challenge query string yes PKCE code challenge (S256).
code_challenge_method query string (enum) no PKCE challenge method. Only `S256` is accepted.
state query string no
scope query string no

Responses

StatusDescription
302 Redirect to consent page or error redirect.
400 RFC 6749 error response for invalid requests that cannot be redirected.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /oauth/register

Dynamic client registration (RFC 7591)

Registers a new OAuth 2.0 client dynamically per RFC 7591. Returns a `client_id` for use in subsequent authorization requests.

Auth

Request Body

FieldTypeRequiredDescription
redirect_uris array of string yes
client_name string no

Responses

StatusDescription
201 Client registered.
400 RFC 7591 error response. `error` values include `invalid_redirect_uri`, `invalid_client_metadata`.
429 429 Too Many Requests — a rate limit or usage quota was exceeded. Retry after the indicated window.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /oauth/token

OAuth 2.0 token endpoint

Exchanges an authorization code for an access token using the `authorization_code` grant type. The PKCE verifier must match the challenge submitted in `/oauth/authorize`. Accepts `application/x-www-form-urlencoded` or `application/json`. **Response format is RFC 6749 style** — not the standard Backbuild envelope.

Auth

Request Body

FieldTypeRequiredDescription
grant_type string (enum) authorization_code yes
code string yes
code_verifier string yes PKCE verifier.

Responses

StatusDescription
200 Access token issued. RFC 6749 response.
400 RFC 6749 error response. `error` values include `invalid_grant`, `invalid_request`, `invalid_client`, `unsupported_grant_type`.
429 429 Too Many Requests — a rate limit or usage quota was exceeded. Retry after the indicated window.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/auth/complete-registration

Complete email-verified registration

Completes a passwordless registration flow started by `/initiate`. Verifies the code, sets the password, creates the account, and returns session tokens. May return `mfa_enrollment_required` when the org mandates MFA before granting full access. Password must meet complexity requirements and must not appear in known breach databases. Requires a Cloudflare Turnstile token.

Auth

Request Body

FieldTypeRequiredDescription
flow_id string<uuid> yes
verification_code string yes
identifier string<email> yes
password string yes Password meeting complexity requirements. Must not appear in known breach databases.
display_name string no

Responses

StatusDescription
200 Registration complete. Returns session tokens or `mfa_enrollment_required: true`.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
409 409 Conflict — the request conflicts with an existing resource or current state (unique constraint, optimistic-lock, duplicate).
429 429 Too Many Requests — a rate limit or usage quota was exceeded. Retry after the indicated window.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
accessToken string
refreshToken string
accessTokenExpiresAt string<date-time>
refreshTokenExpiresAt string<date-time>
mfa_required boolean When true, the user must complete an MFA challenge. Use `mfa_challenge_token` to call `/v1/mfa/challenge/*`.
mfa_challenge_token string Short-lived JWT for MFA challenge flows. Present only when `mfa_required` is true.
mfa_enrollment_required boolean When true, the user must enroll an MFA method. Use `mfa_enrollment_token` to call `/v1/mfa/*` enrollment endpoints.
mfa_enrollment_token string Short-lived JWT for MFA enrollment flows. Present only when `mfa_enrollment_required` is true.
POST /v1/auth/dev/grant-test-entitlements

Grant test entitlements (dev only)

Development-only endpoint that grants test plan entitlements to the authenticated user's organization. Returns `404 NOT_FOUND` in non-dev environments.

Auth Session JWT (Bearer)

Responses

StatusDescription
200 Test entitlements granted.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/auth/dev/purge-test-org

Purge test organization (dev only)

Development-only endpoint that purges the test organization and optionally specific users. Returns `404 NOT_FOUND` in non-dev environments. The caller must be authenticated and the target org must be a test organization.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
org_id string<uuid> yes UUID of the test organization to purge.
user_ids array of string no Optional list of specific user UUIDs to purge. When omitted, all users in the org are purged.

Responses

StatusDescription
200 Test organization purged. Returns audit summary.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/auth/device/authorize

Initiate device authorization flow

Starts the OAuth 2.0 device authorization flow (RFC 8628 adapted with PKCE). The client provides a PKCE code challenge and receives a device code, user code, and verification URI. The user visits the verification URI in a browser to authorize the device. **Note**: This endpoint returns a raw JSON object, not the standard Backbuild envelope.

Auth

Request Body

FieldTypeRequiredDescription
redirect_uri string<uri> yes
code_challenge string yes PKCE S256 code challenge.
code_challenge_method string (enum) S256 no Must be `S256`.
state string no

Responses

StatusDescription
200 Device authorization initiated. Raw JSON response (no envelope wrapper).
400 Missing or invalid `redirect_uri`, `code_challenge`, or `code_challenge_method`. Raw JSON error response.
429 429 Too Many Requests — a rate limit or usage quota was exceeded. Retry after the indicated window.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/auth/device/complete

Approve device authorization (browser user)

Called by the authenticated browser user to approve a pending device authorization. The user enters the `user_code` displayed on the device. On success, the authorization code is minted and the device can exchange it for tokens.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
user_code string yes The user code displayed on the device.

Responses

StatusDescription
200 Authorization approved. Returns the authorization code and redirect URI for the device to use.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
success boolean
redirect_uri string<uri>
code string Authorization code for the device to exchange.
state string
POST /v1/auth/device/token

Exchange device authorization code for tokens

Exchanges the authorization code from the device flow for an access token (and optionally a refresh token). The PKCE verifier must match the challenge submitted in `/device/authorize`. Supports `token_type=jwt` for a full JWT session or `token_type=api_key` (default) for a long-lived opaque API key. **Response format is RFC 6749 style** (`{access_token, token_type, expires_in?, refresh_token?}`), not the standard Backbuild envelope.

Auth

Request Body

FieldTypeRequiredDescription
code string yes
code_verifier string yes PKCE verifier matching the challenge from `/device/authorize`.
grant_type string (enum) authorization_code yes
token_type string (enum) jwtapi_key no Requested token type. `api_key` (default) returns a long-lived opaque key; `jwt` returns a short-lived JWT with a refresh token.

Responses

StatusDescription
200 Token issued. RFC 6749 response format.
400 RFC 6749 error response. `error` values include `invalid_grant`, `invalid_request`, `invalid_client`.
429 429 Too Many Requests — a rate limit or usage quota was exceeded. Retry after the indicated window.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/auth/google-oauth

Authenticate with Google OAuth

Exchanges a Google authorization code for session tokens. Creates a new account if the email does not exist, or links/logs into an existing account. Returns `mfa_required`, `mfa_enrollment_required`, or `google_link_required` when further action is needed. An optional `mfaDeviceToken` (or array `mfaDeviceTokens` for multi-org) bypasses the MFA challenge for a remembered device.

Auth

Request Body

FieldTypeRequiredDescription
code string yes Authorization code from Google.
redirectUri string<uri> yes Redirect URI used in the OAuth flow (must be in the allowlist).
mfaDeviceToken string no Optional remembered-device token to bypass MFA challenge.
mfaDeviceTokens array of string no Optional array of device tokens for multi-org remembered-device bypass.

Responses

StatusDescription
200 OAuth result. One of: full session tokens, `mfa_required`, `mfa_enrollment_required`, or `google_link_required` with a `linkToken`.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
429 429 Too Many Requests — a rate limit or usage quota was exceeded. Retry after the indicated window.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
accessToken string
refreshToken string
accessTokenExpiresAt string<date-time>
refreshTokenExpiresAt string<date-time>
mfa_required boolean
mfa_challenge_token string
mfa_enrollment_required boolean
mfa_enrollment_token string
google_link_required boolean When true, the Google identity matches an existing account but the accounts are not yet linked. Submit `linkToken` to `/google-oauth/confirm-link` while authenticated.
linkToken string Token to pass to `/google-oauth/confirm-link`. Present only when `google_link_required` is true.
POST /v1/auth/initiate

Initiate email verification flow

Starts a passwordless registration flow by sending a verification code to the given email address. Returns a `flow_id` used in subsequent `/registration/validate` and `/complete-registration` calls. Requires a Cloudflare Turnstile token.

Auth

Request Body

FieldTypeRequiredDescription
identifier string<email> yes
identifier_type string (enum) emailphone no Type of identifier. Currently only `email` is supported.

Responses

StatusDescription
200 Verification email sent. Returns `flow_id` and a user-facing message.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
429 429 Too Many Requests — a rate limit or usage quota was exceeded. Retry after the indicated window.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
flow_id string<uuid>
message string
GET /v1/auth/landing-hint

Get login landing hint

Returns a hint for the login page based on the visitor's cookie and Origin/Referer headers. Used to detect returning users and determine whether the org has passwordless login enabled. Public endpoint; does not require authentication.

Auth

Responses

StatusDescription
200 Landing hint for the login UI.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
recognized boolean Whether the visitor appears to be a returning user.
passwordless_enabled boolean Whether passwordless (passkey) login is enabled for this org.
POST /v1/auth/login

Log in with email and password

Authenticates a user with email and password. On success returns session tokens. If the account has MFA enabled, returns `mfa_required: true` and an `mfa_challenge_token` instead of session tokens. If the account must enroll MFA, returns `mfa_enrollment_required: true` and an `mfa_enrollment_token`. An optional `mfaDeviceToken` bypasses the interactive MFA challenge for a remembered device. Requires a Cloudflare Turnstile token.

Auth

Request Body

FieldTypeRequiredDescription
email string<email> yes
password string yes
mfaDeviceToken string no Optional remembered-device token to bypass interactive MFA challenge.

Responses

StatusDescription
200 Login result. One of: full session tokens, `mfa_required` with challenge token, or `mfa_enrollment_required` with enrollment token.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
429 429 Too Many Requests — a rate limit or usage quota was exceeded. Retry after the indicated window.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
accessToken string
refreshToken string
accessTokenExpiresAt string<date-time>
refreshTokenExpiresAt string<date-time>
mfa_required boolean When true, the user must complete an MFA challenge. Use `mfa_challenge_token` to call `/v1/mfa/challenge/*`.
mfa_challenge_token string Short-lived JWT for MFA challenge flows. Present only when `mfa_required` is true.
mfa_enrollment_required boolean When true, the user must enroll an MFA method. Use `mfa_enrollment_token` to call `/v1/mfa/*` enrollment endpoints.
mfa_enrollment_token string Short-lived JWT for MFA enrollment flows. Present only when `mfa_enrollment_required` is true.
POST /v1/auth/logout

Log out current session

Revokes the current session's refresh token and invalidates the session. The access token remains technically valid until its short TTL expires but will fail on any endpoint that checks session state.

Auth Session JWT (Bearer)

Responses

StatusDescription
200 Session revoked.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
message string
POST /v1/auth/logout-all

Log out all sessions

Revokes all active sessions for the authenticated user across all devices.

Auth Session JWT (Bearer)

Responses

StatusDescription
200 All sessions revoked.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
message string
POST /v1/auth/lookup

Look up account by email

Determines whether an email address is registered and whether passwordless (passkey) login is enabled for that account. Used by the login UI to decide which credential flow to present. Requires a valid Cloudflare Turnstile token.

Auth

Request Body

FieldTypeRequiredDescription
email string<email> yes

Responses

StatusDescription
200 Lookup result. `action` indicates the recommended login flow (`password`, `passkey`, `sso`, `register`).
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
429 429 Too Many Requests — a rate limit or usage quota was exceeded. Retry after the indicated window.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
action string Recommended login action: `password`, `passkey`, `sso`, or `register`.
GET /v1/auth/me

Get current user identity and first-paint data

Returns the authenticated user's full identity (profile, org, roles, permissions) together with first-paint bootstrap slices fetched in parallel. This is the primary session-bootstrap endpoint called on app load.

Auth Session JWT (Bearer)

Responses

StatusDescription
200 User identity and bootstrap data.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
id string<uuid>
email string<email>
displayName string
orgId string<uuid>
orgSlug string
roles array of string
permissions array of string
mfaEnabled boolean
envId string<uuid>
POST /v1/auth/otp/create

Send a one-time password

Sends a one-time password (OTP) to the user's email for the specified purpose (`login`, `verify_email`, or `reset_password`). Rate-limited per email. Requires a Cloudflare Turnstile token.

Auth

Request Body

FieldTypeRequiredDescription
email string<email> yes
purpose string (enum) loginverify_emailreset_password yes

Responses

StatusDescription
200 OTP sent (or silently suppressed if the email does not exist, to prevent enumeration).
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
429 429 Too Many Requests — a rate limit or usage quota was exceeded. Retry after the indicated window.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
message string
POST /v1/auth/otp/verify

Verify a one-time password

Verifies the OTP sent by `/otp/create` and, if valid, returns session tokens (for `login` purpose) or confirms email/password-reset eligibility (other purposes). Requires the caller's IP address via `CF-Connecting-IP`.

Auth

Request Body

FieldTypeRequiredDescription
email string<email> yes
code string yes
purpose string (enum) loginverify_emailreset_password yes

Responses

StatusDescription
200 OTP verified. Returns session tokens for `login` purpose.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
429 429 Too Many Requests — a rate limit or usage quota was exceeded. Retry after the indicated window.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
accessToken string
refreshToken string
accessTokenExpiresAt string<date-time>
refreshTokenExpiresAt string<date-time>
mfa_required boolean When true, the user must complete an MFA challenge. Use `mfa_challenge_token` to call `/v1/mfa/challenge/*`.
mfa_challenge_token string Short-lived JWT for MFA challenge flows. Present only when `mfa_required` is true.
mfa_enrollment_required boolean When true, the user must enroll an MFA method. Use `mfa_enrollment_token` to call `/v1/mfa/*` enrollment endpoints.
mfa_enrollment_token string Short-lived JWT for MFA enrollment flows. Present only when `mfa_enrollment_required` is true.
POST /v1/auth/password/change

Change password

Changes the authenticated user's password. For accounts with an existing password, `old_password` is required (omit for initial password set). Requires a recent MFA step-up. On success, revokes all other sessions.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
old_password string no Current password. Required unless this is an initial password set.
new_password string yes New password meeting complexity requirements.

Responses

StatusDescription
200 Password changed. All other sessions revoked.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
was_initial_set boolean True if this was the first password set (no old password existed).
sessions_revoked integer Number of other sessions that were revoked.
POST /v1/auth/password/reset

Reset password with code

Resets the user's password using the code sent to their email by `/password/reset/request`. The new password must meet complexity requirements and must not appear in known breach databases.

Auth

Request Body

FieldTypeRequiredDescription
email string<email> yes
code string yes
new_password string yes New password meeting complexity requirements. Must not appear in known breach databases.

Responses

StatusDescription
200 Password successfully reset.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
429 429 Too Many Requests — a rate limit or usage quota was exceeded. Retry after the indicated window.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
message string
POST /v1/auth/password/reset/request

Request a password reset

Sends a password-reset code to the email address if it is registered. Always returns success to prevent email enumeration. Requires a Cloudflare Turnstile token.

Auth

Request Body

FieldTypeRequiredDescription
identifier string<email> yes

Responses

StatusDescription
200 Reset email dispatched (or silently suppressed for unknown emails).
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
429 429 Too Many Requests — a rate limit or usage quota was exceeded. Retry after the indicated window.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
message string
POST /v1/auth/preferences/passkey-primary-override

Override passkey-primary login preference

Sets the authenticated user's passkey-primary login preference to `inherit` (follow org policy), `force_on` (always prompt passkey first), or `force_off` (always show password form first).

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
override string (enum) inheritforce_onforce_off yes

Responses

StatusDescription
200 Preference saved.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
override string (enum) inheritforce_onforce_off
POST /v1/auth/refresh

Refresh session tokens

Exchanges a valid refresh token for a new access token / refresh token pair. The old refresh token is invalidated (rotation). Returns `AUTH_REFRESH_TOKEN_INVALID` if the token has been revoked, already rotated, or is expired.

Auth

Request Body

FieldTypeRequiredDescription
refreshToken string yes

Responses

StatusDescription
200 New token pair issued.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
429 429 Too Many Requests — a rate limit or usage quota was exceeded. Retry after the indicated window.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
accessToken string Short-lived JWT access token.
refreshToken string Long-lived opaque refresh token.
accessTokenExpiresAt string<date-time>
refreshTokenExpiresAt string<date-time>
POST /v1/auth/register

Register a new account

Creates a new user account with email and password. Returns session tokens on success, or an `mfa_enrollment_required` flag when MFA enrollment is mandatory. Requires a Cloudflare Turnstile token. Password must meet complexity requirements (uppercase, lowercase, digit, special character) and must not appear in known breach databases.

Auth

Request Body

FieldTypeRequiredDescription
email string<email> yes
password string yes Password meeting complexity requirements: uppercase, lowercase, digit, and special character. Must not appear in known breach databases.
displayName string no
orgId string<uuid> no Optional organization to join upon registration.

Responses

StatusDescription
200 Registration succeeded. Returns session tokens, or `mfa_enrollment_required: true` when the org requires MFA enrollment before access is granted.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
409 409 Conflict — the request conflicts with an existing resource or current state (unique constraint, optimistic-lock, duplicate).
429 429 Too Many Requests — a rate limit or usage quota was exceeded. Retry after the indicated window.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
accessToken string
refreshToken string
accessTokenExpiresAt string<date-time>
refreshTokenExpiresAt string<date-time>
mfa_required boolean When true, the user must complete an MFA challenge. Use `mfa_challenge_token` to call `/v1/mfa/challenge/*`.
mfa_challenge_token string Short-lived JWT for MFA challenge flows. Present only when `mfa_required` is true.
mfa_enrollment_required boolean When true, the user must enroll an MFA method. Use `mfa_enrollment_token` to call `/v1/mfa/*` enrollment endpoints.
mfa_enrollment_token string Short-lived JWT for MFA enrollment flows. Present only when `mfa_enrollment_required` is true.
POST /v1/auth/registration/validate

Validate registration verification code

Validates the verification code for an in-progress registration flow without completing it. Used to give inline feedback before the user fills in the rest of the registration form.

Auth

Request Body

FieldTypeRequiredDescription
flow_id string<uuid> yes
verification_code string yes
identifier string<email> yes

Responses

StatusDescription
200 Code is valid for the given flow.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
410 Flow expired or code is invalid. Error code: `NOT_FOUND` or `VALIDATION_ERROR`.
429 429 Too Many Requests — a rate limit or usage quota was exceeded. Retry after the indicated window.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
validated boolean Always `true` on success.
POST /v1/auth/switch-env

Switch active environment

Issues new session tokens scoped to the specified environment within the current organization.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
env_id string<uuid> yes

Responses

StatusDescription
200 New env-scoped token pair issued.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
accessToken string Short-lived JWT access token.
refreshToken string Long-lived opaque refresh token.
accessTokenExpiresAt string<date-time>
refreshTokenExpiresAt string<date-time>
POST /v1/auth/switch-org

Switch active organization

Issues new session tokens scoped to the specified organization. The caller must be a member of the target org.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
org_id string<uuid> yes

Responses

StatusDescription
200 New org-scoped token pair issued.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
accessToken string Short-lived JWT access token.
refreshToken string Long-lived opaque refresh token.
accessTokenExpiresAt string<date-time>
refreshTokenExpiresAt string<date-time>
POST /v1/auth/webauthn/assertion/options

Get WebAuthn assertion options for passkey login

Returns WebAuthn assertion (get) options for the primary passkey login flow. Returns an `assertion_nonce` that must be submitted with the credential in `/webauthn/assertion/verify`.

Auth

Responses

StatusDescription
200 WebAuthn assertion options and nonce.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
options object WebAuthn PublicKeyCredentialRequestOptions.
assertion_nonce string Nonce to submit alongside the credential in `/webauthn/assertion/verify`.
POST /v1/auth/webauthn/assertion/verify

Verify WebAuthn assertion for passkey login

Verifies a WebAuthn assertion credential against the stored passkey and the nonce issued by `/webauthn/assertion/options`. On success returns session tokens.

Auth

Request Body

FieldTypeRequiredDescription
assertion_nonce string yes
credential object yes WebAuthn PublicKeyCredential assertion.

Responses

StatusDescription
200 Passkey verified. Returns session tokens.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
accessToken string Short-lived JWT access token.
refreshToken string Long-lived opaque refresh token.
accessTokenExpiresAt string<date-time>
refreshTokenExpiresAt string<date-time>
POST /v1/mfa/challenge/email-otp/send

Send email OTP during MFA challenge

Sends an email OTP to the user's registered email address during an active MFA challenge. Requires an MFA challenge token.

Auth Session JWT (Bearer)

Responses

StatusDescription
200 OTP sent.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
429 429 Too Many Requests — a rate limit or usage quota was exceeded. Retry after the indicated window.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
sent boolean
email string Masked email address (e.g. `u***@example.com`).
expiresInMinutes integer
POST /v1/mfa/challenge/email-otp/verify

Verify email OTP during MFA challenge

Verifies the email OTP sent by `/challenge/email-otp/send` during an active MFA challenge. Requires an MFA challenge token. On success returns full session tokens and optionally a device trust token.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
code string yes
rememberDevice boolean no
rememberDeviceDays integer no
deviceName string no

Responses

StatusDescription
200 MFA verified. Returns session tokens and optionally a device trust token.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
accessToken string
refreshToken string
accessTokenExpiresAt string<date-time>
refreshTokenExpiresAt string<date-time>
mfaDeviceToken string Device trust token for remembered-device bypass on future logins. Present only when `rememberDevice` was requested.
POST /v1/mfa/challenge/recovery

Use recovery code during MFA challenge

Verifies a one-time recovery code during an active MFA challenge. The code is consumed and cannot be reused. Requires an MFA challenge token. On success returns full session tokens and optionally a device trust token.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
code string yes
rememberDevice boolean no
rememberDeviceDays integer no
deviceName string no

Responses

StatusDescription
200 Recovery code accepted. Returns session tokens.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
accessToken string
refreshToken string
accessTokenExpiresAt string<date-time>
refreshTokenExpiresAt string<date-time>
mfaDeviceToken string Device trust token for remembered-device bypass on future logins. Present only when `rememberDevice` was requested.
POST /v1/mfa/challenge/totp

Verify TOTP during MFA challenge

Verifies a TOTP code during an active MFA challenge (mid-login). Requires an MFA challenge token issued by `/login`, `/google-oauth`, or similar. On success, returns full session tokens. Optionally issues a `mfaDeviceToken` for remembered-device bypass on future logins.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
code string yes 6-digit TOTP code.
rememberDevice boolean no
rememberDeviceDays integer no
deviceName string no

Responses

StatusDescription
200 MFA verified. Returns session tokens and optionally a device trust token.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
accessToken string
refreshToken string
accessTokenExpiresAt string<date-time>
refreshTokenExpiresAt string<date-time>
mfaDeviceToken string Device trust token for remembered-device bypass on future logins. Present only when `rememberDevice` was requested.
POST /v1/mfa/challenge/webauthn/options

Get WebAuthn options during MFA challenge

Returns WebAuthn assertion options and a `challenge_token` during an active MFA challenge. Requires an MFA challenge token.

Auth Session JWT (Bearer)

Responses

StatusDescription
200 WebAuthn assertion options for the MFA challenge.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
options object WebAuthn PublicKeyCredentialRequestOptions or CreationOptions.
challenge_token string HMAC-signed JWT challenge to submit with the credential verify call.
POST /v1/mfa/challenge/webauthn/verify

Verify WebAuthn assertion during MFA challenge

Verifies a WebAuthn assertion during an active MFA challenge. Requires an MFA challenge token. On success returns full session tokens and optionally a device trust token.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
credential object no WebAuthn PublicKeyCredential assertion.
id string no
rawId string no
type string no
response object no
challenge_token string no
rememberDevice boolean no
rememberDeviceDays integer no
deviceName string no Truncated to 100 characters server-side.

Responses

StatusDescription
200 MFA verified. Returns session tokens and optionally a device trust token.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
accessToken string
refreshToken string
accessTokenExpiresAt string<date-time>
refreshTokenExpiresAt string<date-time>
mfaDeviceToken string Device trust token for remembered-device bypass on future logins. Present only when `rememberDevice` was requested.
POST /v1/mfa/email-otp/setup

Set up email OTP MFA method

Enrolls the user's verified email address as an MFA method and sends a verification OTP. Returns recovery codes on first enrollment. Accepts either a full session JWT or an MFA enrollment token.

Auth Session JWT (Bearer)

Responses

StatusDescription
200 Email OTP method enrolled.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
409 409 Conflict — the request conflicts with an existing resource or current state (unique constraint, optimistic-lock, duplicate).
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
methodId string<uuid>
email string<email>
isFirstMethod boolean
recoveryCodes array of string
session object Session token pair.
GET /v1/mfa/methods

List enrolled MFA methods

Returns all MFA methods enrolled for the authenticated user. Accepts either a full session JWT or an MFA enrollment token (issued during login when MFA enrollment is required).

Auth Session JWT (Bearer)

Responses

StatusDescription
200 List of enrolled MFA methods.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
methods array of object
PATCH /v1/mfa/methods/{methodId}

Rename an MFA method

Updates the display name of an enrolled MFA method.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
methodId path string<uuid> yes UUID of the MFA method to rename.

Request Body

FieldTypeRequiredDescription
name string yes

Responses

StatusDescription
200 Method renamed.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
methodId string<uuid>
name string
renamedAt string<date-time>
DELETE /v1/mfa/methods/{methodId}

Delete an MFA method

Removes an enrolled MFA method. When `force=true` is passed, requires a recent authentication and MFA step-up. Passing `force` without a recent step-up returns `MFA_STEPUP_REQUIRED`.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
methodId path string<uuid> yes UUID of the MFA method to delete.
force query boolean no When true, requires a recent MFA step-up and deletes even the last method (fully disenrolling MFA).

Responses

StatusDescription
200 Method deleted.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
methodId string<uuid>
remainingMethods integer
mfaDisenrolled boolean True if all MFA methods have been removed.
POST /v1/mfa/recovery-codes/generate

Generate new recovery codes

Generates a fresh set of one-time recovery codes, invalidating any previously issued codes. The returned codes are shown only once.

Auth Session JWT (Bearer)

Responses

StatusDescription
200 New recovery codes issued.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
codes array of string
count integer
warning string Advisory message reminding the user to store codes safely.
GET /v1/mfa/step-up/methods

List available step-up MFA methods

Returns the list of MFA method types available for step-up authentication for the current user.

Auth Session JWT (Bearer)

Responses

StatusDescription
200 Available step-up method types.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
methods array of string Array of method type strings, e.g. `["totp", "webauthn"]`.
POST /v1/mfa/step-up/totp

Perform TOTP step-up

Verifies a TOTP code to elevate the current session to MFA-stepped-up status. Returns a new token pair with the step-up claim. Required before sensitive operations such as password change. Only the `code` field is accepted; device-remember fields do not apply to step-up.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
code string yes 6-digit TOTP code from the authenticator app.

Responses

StatusDescription
200 Step-up successful. Returns new token pair.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
accessToken string Short-lived JWT access token.
refreshToken string Long-lived opaque refresh token.
accessTokenExpiresAt string<date-time>
refreshTokenExpiresAt string<date-time>
POST /v1/mfa/step-up/webauthn/options

Get WebAuthn options for step-up

Returns WebAuthn assertion options and an HMAC-signed `challenge_token` for step-up authentication.

Auth Session JWT (Bearer)

Responses

StatusDescription
200 WebAuthn assertion options and challenge token for step-up.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
options object WebAuthn PublicKeyCredentialRequestOptions or CreationOptions.
challenge_token string HMAC-signed JWT challenge to submit with the credential verify call.
POST /v1/mfa/step-up/webauthn/verify

Verify WebAuthn assertion for step-up

Verifies a WebAuthn assertion for step-up and returns a new token pair with the step-up claim.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
credential object no WebAuthn PublicKeyCredential assertion.
challenge_token string no
rememberDevice boolean no
rememberDeviceDays integer no
deviceName string no Truncated to 100 characters server-side.

Responses

StatusDescription
200 Step-up successful. Returns new token pair.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
accessToken string Short-lived JWT access token.
refreshToken string Long-lived opaque refresh token.
accessTokenExpiresAt string<date-time>
refreshTokenExpiresAt string<date-time>
POST /v1/mfa/totp/confirm

Confirm TOTP enrollment

Verifies the first TOTP code against the encrypted secret from `/totp/setup`, completing TOTP enrollment. Returns recovery codes on first enrollment. If this is the first MFA method, also returns a full session (completing login when enrollment was required). Accepts either a full session JWT or an MFA enrollment token.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
code string yes 6-digit TOTP code.
methodId string<uuid> yes
encryptedSecret string yes

Responses

StatusDescription
200 TOTP enrolled. `recoveryCodes` present if this is the first method enrolled.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
verified boolean
methodId string<uuid>
isFirstMethod boolean
recoveryCodes array of string One-time recovery codes. Only present when this is the first MFA method enrolled.
session object Session token pair.
POST /v1/mfa/totp/setup

Set up TOTP MFA method

Generates a TOTP secret and URI for enrollment. The returned `encryptedSecret` must be submitted along with the first TOTP code to `/totp/confirm` to complete enrollment. Accepts either a full session JWT or an MFA enrollment token.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
friendlyName string no

Responses

StatusDescription
200 TOTP setup initiated. Scan the URI with an authenticator app, then confirm with `/totp/confirm`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
409 409 Conflict — the request conflicts with an existing resource or current state (unique constraint, optimistic-lock, duplicate).
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
methodId string<uuid>
secret string Base32-encoded TOTP secret for manual entry.
uri string otpauth:// URI for QR code generation.
encryptedSecret string Encrypted secret to submit to `/totp/confirm`.
session object Session token pair.
POST /v1/mfa/webauthn/register/options

Get WebAuthn registration options for MFA enrollment

Returns WebAuthn attestation (create) options and a `challenge_token` for enrolling a security key or platform authenticator as an MFA method. Accepts either a full session JWT or an MFA enrollment token.

Auth Session JWT (Bearer)

Responses

StatusDescription
200 WebAuthn registration options and challenge token.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
options object WebAuthn PublicKeyCredentialRequestOptions or CreationOptions.
challenge_token string HMAC-signed JWT challenge to submit with the credential verify call.
POST /v1/mfa/webauthn/register/verify

Verify WebAuthn registration for MFA enrollment

Verifies the attestation response from the authenticator and stores the credential as an MFA method. Returns recovery codes on first enrollment. If this is the first MFA method and enrollment was required, also returns a full session. Accepts either a full session JWT or an MFA enrollment token.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
attestationResponse object yes

Responses

StatusDescription
200 WebAuthn credential enrolled.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
verified boolean
methodId string<uuid>
isFirstMethod boolean
recoveryCodes array of string One-time recovery codes. Only present when this is the first MFA method enrolled.
session object Session token pair.