Skip to content

REST API reference

The REST reference is generated from the authn-sh/openapi bundled spec. The build pipeline pulls openapi.bundled.json from its tagged release and renders the full reference here.

  • Backend API (BAPI) — server-to-server, secret-key authenticated. Source: routes/bapi.php.
  • Frontend API (FAPI) — browser-facing, publishable-key + Client-cookie authenticated. Source: routes/fapi.php.
  • /.well-known/jwks.json — per-environment JWKS. Source: JwksController.
  • All timestamps are Unix milliseconds (numbers, not strings).
  • All IDs are prefixed ULIDs — user_…, sess_…, org_…, evt_…. Treat as opaque strings.
  • Errors follow the envelope { "errors": [{ "code", "message", "long_message", "meta" }], "trace_id" }.
  • Pagination is opaque cursor-based: ?cursor=<token>&limit=<n>. Responses include meta.next_cursor when more rows exist.
MethodPathDescription
GET/v1/jwt-templatesList every JwtTemplate on the environment.
POST/v1/jwt-templatesCreate. name must be unique per env. custom_signing_key is write-only.
GET/v1/jwt-templates/{id}Fetch one. custom_signing_key is never returned.
PATCH/v1/jwt-templates/{id}Update name, claims, lifetime, allowed_clock_skew, signing_algorithm. Send null on custom_signing_key to clear.
DELETE/v1/jwt-templates/{id}Hard-delete. SDK calls to getToken({ template: <name> }) thereafter fail with 404.
POST/v1/users/{user_id}/jwt-templates/{name}/tokensMint a token for a specific user — backend-issuance path with no browser session.
MethodPathDescription
GET/v1/oauth-applicationsList every OauthApplication on the environment.
POST/v1/oauth-applicationsRegister a third-party app. client_secret is returned exactly once on this response. is_public is immutable.
GET/v1/oauth-applications/{id}Fetch one. client_secret is never included.
PATCH/v1/oauth-applications/{id}Update name, homepage_url, redirect_uris, scopes, consent_screen. is_public and client_id are immutable.
DELETE/v1/oauth-applications/{id}Hard-delete. Revokes every linked AuthorizationGrant.
POST/v1/oauth-applications/{id}/rotate-secretMint a fresh client_secret. No overlap window — old secret is invalidated immediately.
GET/v1/oauth-applications/{id}/authorization-grantsList every AuthorizationGrant for this app (operator view across all users).
DELETE/v1/oauth-applications/{id}/authorization-grants/{grant_id}Revoke a specific grant (operator unlink).

The v0.6 deferral — operator-side mirror of the per-org FAPI SCIM surface.

MethodPathDescription
GET/v1/organizations/{org_id}/scim/endpointRead the SCIM endpoint URL for the org.
GET/v1/organizations/{org_id}/scim/tokensList active + revoked ScimToken rows. Plaintext never returned.
POST/v1/organizations/{org_id}/scim/tokensIssue a SCIM token. Plaintext returned exactly once.
POST/v1/organizations/{org_id}/scim/tokens/{id}/revokeRevoke.
GET/v1/organizations/{org_id}/scim/attribute-mappingsRead the per-org override (or defaults when no override is set).
PUT/v1/organizations/{org_id}/scim/attribute-mappingsReplace the override. Empty mapping: {} reverts to defaults.

Spec backfill — EnterpriseAccount listing / get / delete were live since v0.6 but not in the OpenAPI bundle.

MethodPathDescription
GET/v1/enterprise-accountsList every EnterpriseAccount on the env (filter by user_id / enterprise_connection_id).
GET/v1/enterprise-accounts/{id}Fetch one.
DELETE/v1/enterprise-accounts/{id}Admin unlink — preserves the underlying User.

All five are hosted on the FAPI server (the env’s customer-facing origin). None of them live under /v1/client/... — they’re top-level OAuth-spec endpoints.

MethodPathDescription
GET/oauth/authorizeAuthorization-code grant entry point. Renders sign-in + consent, then 302 to redirect_uri. RFC 6749 §4.1 + OIDC §3.1.2.1.
POST/oauth/tokenExchange authorization_code for tokens, or refresh-token grant. client_secret_basic / client_secret_post / none auth (per is_public).
POST/oauth/token_infoToken introspection per RFC 7662.
GET/oauth/userinfoOIDC userinfo. Scope-filtered claims. Bearer-token auth.
GET/.well-known/openid-configurationOIDC discovery document. Public, CORS-open, cached 5 minutes.

The signed-in user’s view of their granted apps — backs <UserProfile />’s Authorized apps section.

MethodPathDescription
GET/v1/me/oauth-authorization-grantsList the user’s active AuthorizationGrant rows.
GET/v1/me/oauth-authorization-grants/{id}Fetch one.
DELETE/v1/me/oauth-authorization-grants/{id}Revoke — hard-deletes the row. Subsequent third-party-app refresh calls return 401 invalid_grant.
MethodPathDescription
GET/v1/enterprise-connectionsList every EnterpriseConnection on the environment (instance-wide + org-scoped).
POST/v1/enterprise-connectionsCreate a SAML or OIDC connection. organization_id: null for instance-wide; set to an Organization.id for org-scoped. Both protocol and organization_id are immutable after create.
GET/v1/enterprise-connections/{id}Fetch one. oidc_client_secret + saml_signing_key are never included — write-only.
PATCH/v1/enterprise-connections/{id}Update non-immutable fields. Send null on oidc_client_secret / saml_signing_key to clear.
DELETE/v1/enterprise-connections/{id}Soft-delete. Linked EnterpriseAccount rows survive for audit.
POST/v1/enterprise-connections/{id}/testDry-run probe — discovery / JWKS / certificate / redirect-URI checks. Returns EnterpriseConnectionTestResult. Never redirects a real user.
GET/v1/enterprise-accountsList every EnterpriseAccount on the environment.
GET/v1/enterprise-accounts/{id}Fetch one.
DELETE/v1/enterprise-accounts/{id}Unlink — orphans the row from sign-in but preserves the audit trail.
MethodPathDescription
GET/v1/organizations/{org_id}/enterprise-connectionsList the org’s connections.
POST/v1/organizations/{org_id}/enterprise-connectionsCreate. organization_id on the body must match (or be omitted). Requires org:sys_enterprise_sso:manage.
GET/v1/organizations/{org_id}/enterprise-connections/{id}Fetch.
PATCH/v1/organizations/{org_id}/enterprise-connections/{id}Update.
DELETE/v1/organizations/{org_id}/enterprise-connections/{id}Soft-delete.
POST/v1/organizations/{org_id}/enterprise-connections/{id}/testSame dry-run probe as the BAPI counterpart.

SCIM 2.0 (IdP-facing — bearer-token auth)

Section titled “SCIM 2.0 (IdP-facing — bearer-token auth)”
MethodPathDescription
GET/scim/v2/UsersList provisioned users in the token’s org. Supports SCIM filter / pagination.
POST/scim/v2/UsersProvision a user. Fires scimUser.provisioned.
GET/scim/v2/Users/{id}Fetch one.
PUT/scim/v2/Users/{id}Full replace.
PATCH/scim/v2/Users/{id}SCIM patch operations. active: false triggers soft-delete + fires scimUser.deprovisioned.
DELETE/scim/v2/Users/{id}Hard-delete (rare — most IdPs use active: false instead).
GET/scim/v2/GroupsList groups.
POST/scim/v2/GroupsCreate a group.
GET/scim/v2/Groups/{id}Fetch.
PUT / PATCH / DELETE/scim/v2/Groups/{id}Update / delete.
GET/scim/v2/ServiceProviderConfigCapability descriptor — IdPs probe this on connection test.
GET/scim/v2/ResourceTypesSupported SCIM resource types.
GET/scim/v2/SchemasSupported SCIM schemas.

Org-scoped SCIM admin (operator-facing — same auth as the rest of FAPI)

Section titled “Org-scoped SCIM admin (operator-facing — same auth as the rest of FAPI)”
MethodPathDescription
GET/v1/organizations/{org_id}/scim/endpointRead the SCIM endpoint URL the IdP admin pastes into their provisioning config. Returns { endpoint_url }. Requires org:sys_provisioning:read.
GET/v1/organizations/{org_id}/scim/tokensList active + revoked ScimToken rows. Plaintext not returned.
POST/v1/organizations/{org_id}/scim/tokensIssue a fresh SCIM token — plaintext returned exactly once on this response.
POST/v1/organizations/{org_id}/scim/tokens/{id}/revokeRevoke. Subsequent SCIM requests with this token return 401.
GET/v1/organizations/{org_id}/scim/attribute-mappingsRead the per-org override (returns the platform defaults when no override is set).
PUT/v1/organizations/{org_id}/scim/attribute-mappingsReplace the override. PUT with empty mapping: {} reverts to defaults.
MethodPathDescription
POST/v1/saml/{id}/acsSAML AssertionConsumerService endpoint — the IdP POSTs the assertion here. Server validates against the connection’s saml_idp_certificate.
GET/v1/saml/{id}/metadataSP metadata XML — the IdP ingests this URL to learn the SP’s entity / ACS / signing-cert.
GET/v1/enterprise-sso-callbackShared OIDC redirect URI for every OIDC enterprise connection in the env. Connection is identified via the OAuth state parameter.
MethodPathDescription
GET/v1/oauth-providersList every OauthProvider row on the environment.
POST/v1/oauth-providersCreate a preset, custom_oidc, or custom_oauth2 row.
GET/v1/oauth-providers/{id}Fetch a single provider. client_secret is never included.
PATCH/v1/oauth-providers/{id}Update toggles, secret, scopes, attribute mapping. provider_kind and provider_key are immutable.
DELETE/v1/oauth-providers/{id}Soft-delete. Refused while ExternalAccount rows still link to this provider.
POST/v1/oauth-providers/{id}/testDry-run probe — surfaces broken endpoints without redirecting any user.
MethodPathDescription
GET/v1/sms-templatesList the three seeded rows in slug order.
GET/v1/sms-templates/{slug}Fetch one.
PATCH/v1/sms-templates/{slug}Patch body, delivered_by_us, or from_number_override.
POST/v1/sms-templates/{slug}/revertRestore platform defaults.
MethodPathDescription
GET/v1/me/external-accountsList the signed-in user’s ExternalAccount rows.
GET/v1/me/external-accounts/{id}Fetch one.
DELETE/v1/me/external-accounts/{id}Unlink (best-effort IdP-side revocation).
MethodPathDescription
GET/v1/me/phone-numbersList the user’s phone numbers.
POST/v1/me/phone-numbersAdd a new phone number (always created unverified).
GET/v1/me/phone-numbers/{id}Fetch one.
PATCH/v1/me/phone-numbers/{id}Toggle is_primary, reserved_for_second_factor, default_second_factor.
DELETE/v1/me/phone-numbers/{id}Remove (refused while reserved_for_second_factor: true).
POST/v1/me/phone-numbers/{id}/challengesIssue a phone_code verification Challenge.
POST/v1/me/phone-numbers/{id}/challenges/{cid}/answerAnswer with the 6-digit code.
GET/v1/me/phone-numbers/{id}/challenges/{cid}Poll Challenge status.
MethodPathDescription
GET/v1/oauth-callback/{provider_key}IdP redirect target — browsers only, never called by the SDK.
MethodPathDescription
POST/v1/users/{id}/verify-totpVerify a user’s TOTP code server-side (returns { verified: bool }).
DELETE/v1/users/{id}/mfaReset all MFA factors for a user — deletes TOTP secret and all backup codes.
MethodPathDescription
POST/v1/me/totpStart TOTP enrollment — returns QR code, otpauth_uri, and plaintext secret (one-time).
POST/v1/me/totp/verifyConfirm enrollment by submitting the first generated 6-digit code.
DELETE/v1/me/totpRemove the signed-in user’s TOTP secret.
MethodPathDescription
POST/v1/me/backup-codes(Re)generate backup codes — plaintext returned exactly once.
DELETE/v1/me/backup-codesDelete all unused backup codes for the signed-in user.
MethodPathDescription
GET/v1/organizationsList organizations (cursor-paginated).
POST/v1/organizationsCreate an organization.
GET/v1/organizations/{id}Get a single organization.
PATCH/v1/organizations/{id}Update name, slug, image, metadata.
DELETE/v1/organizations/{id}Delete an organization.
GET/v1/organizations/{id}/membershipsList members.
POST/v1/organizations/{id}/membershipsAdd a member directly.
PATCH/v1/organizations/{id}/memberships/{membership_id}Change a member’s role.
DELETE/v1/organizations/{id}/memberships/{membership_id}Remove a member.
GET/v1/organizations/{id}/invitationsList invitations.
POST/v1/organizations/{id}/invitationsCreate an invitation.
POST/v1/organizations/{id}/invitations/bulkBulk-create invitations.
POST/v1/organizations/{id}/invitations/{inv_id}/revokeRevoke a pending invitation.
GET/v1/organizations/{id}/domainsList verified domains.
POST/v1/organizations/{id}/domainsAdd a domain.
PATCH/v1/organizations/{id}/domains/{domain_id}Update enrollment mode.
DELETE/v1/organizations/{id}/domains/{domain_id}Remove a domain.
POST/v1/organizations/{id}/domains/{domain_id}/challengesCreate a domain-verification challenge (dns_txt or email_code).
POST/v1/organizations/{id}/domains/{domain_id}/challenges/{cid}/answerSubmit the email code to answer a challenge.
GET/v1/organizations/{id}/domains/{domain_id}/challenges/{cid}Poll challenge status (dns_txt resolves automatically on poll).
MethodPathDescription
GET/v1/rolesList roles.
POST/v1/rolesCreate a custom role.
GET/v1/roles/{id}Get a single role.
PATCH/v1/roles/{id}Update a role’s name / description / flags.
DELETE/v1/roles/{id}Delete a custom role.
PUT/v1/roles/{id}/permissionsReplace a role’s permission set.
GET/v1/permissionsList permissions (system + custom).
MethodPathDescription
GET/v1/me/organization-membershipsList the signed-in user’s memberships.
GET/v1/me/organization-invitationsList the user’s pending invitations.
POST/v1/me/organization-invitations/{inv_id}/acceptAccept an invitation.
GET/v1/me/organization-membership-requestsList the user’s membership requests.
GET/v1/organizations/{id}Get an org the user is a member of.
GET/v1/organizations/{id}/membershipsList an org’s members (user-scoped).
POST/v1/organizations/{id}/invitationsInvite a member (requires org:sys_memberships:manage).
POST/v1/organizations/{id}/leaveLeave an organization.
PATCH/v1/client/sessions/{sid}/active-organizationSet the active organization.
MethodPathDescription
POST/v1/me/email-addresses/{id}/challengesIssue an email_code or email_link verification challenge.
POST/v1/me/email-addresses/{id}/challenges/{cid}/answerAnswer a challenge (code string, or empty body for email_link).
GET/v1/me/email-addresses/{id}/challenges/{cid}Poll challenge status.
MethodPathDescription
POST/v1/client/sign-ins/{sid}/challengesIssue a challenge; server picks step from sign-in state.
POST/v1/client/sign-ins/{sid}/challenges/{cid}/answerAnswer a challenge (password, code, or empty body for email_link).
GET/v1/client/sign-ins/{sid}/challenges/{cid}Fetch challenge — used for magic-link cross-device polling.
MethodPathDescription
POST/v1/client/sign-ups/{sid}/challengesIssue a verification challenge on a sign-up.
POST/v1/client/sign-ups/{sid}/challenges/{cid}/answerAnswer a sign-up challenge.
GET/v1/client/sign-ups/{sid}/challenges/{cid}Fetch challenge — used for magic-link cross-device polling.
MethodPathDescription
GET/v1/client/handshakeConsume a __authn_ticket from the clicked magic link.