Skip to main content

API Overview

The IdentSphere HTTP API is a small, opinionated REST surface. All endpoints live under a single base URL — by convention https://auth.example.com — and follow the same conventions for authentication, errors, and content types.

::: tip Stability Every endpoint documented here is part of the v0.1 stable contract. Breaking changes will only land in major version bumps (v1, v2, …). Additive changes (new optional request fields, new response fields) may ship in minor versions. :::

Base URL

The SDK doesn't enforce a particular host. In the docs we use:

RoleExample URL
Auth backendhttps://auth.example.com
Your app frontendhttps://app.example.com
Object storage CDNhttps://files.example.com

Replace these with whatever your deployment uses. For local development the defaults are http://localhost:4000 (auth) and http://localhost:3000 (app).

Route prefix

By default every endpoint is mounted under /v1. The prefix is configurable via AppConfig::route_prefix — if you change it (for example to /auth/v1) adjust every URL in this reference accordingly.

Endpoint catalog

Auth

MethodPathAuthNotes
POST/v1/auth/registernoneCreate org + owner user
POST/v1/auth/loginnoneEmail + password sign-in. May return mfa_required.
POST/v1/auth/refreshrefresh cookieRotate refresh token, mint new access token
POST/v1/auth/logoutoptionalRevoke the current session
GET/v1/auth/sessioncookie/BearerCurrent user + capabilities

MFA (TOTP)

MethodPathAuth
GET/v1/auth/mfa/statuscookie/Bearer
POST/v1/auth/mfa/setupcookie/Bearer
POST/v1/auth/mfa/enablecookie/Bearer
POST/v1/auth/mfa/disablecookie/Bearer + password
POST/v1/auth/mfa/recovery-codescookie/Bearer + password
POST/v1/auth/mfa/verifycookie/Bearer
POST/v1/auth/mfa/challengemfa_token (from login)

Passkeys (WebAuthn)

MethodPathAuth
POST/v1/users/me/passkeys/register/begincookie/Bearer
POST/v1/users/me/passkeys/register/completecookie/Bearer
GET/v1/users/me/passkeyscookie/Bearer
DELETE/v1/users/me/passkeys/:idcookie/Bearer
POST/v1/auth/passkey/login/beginnone
POST/v1/auth/passkey/login/completenone

OAuth

MethodPathAuth
GET/v1/auth/oauth/:provider/startnone
GET/v1/auth/oauth/:provider/callbacknone

Email OTP / verification / password reset

MethodPathAuth
POST/v1/auth/email-otp/requestnone
POST/v1/auth/email-otp/verifynone
POST/v1/auth/email/send-verificationcookie/Bearer
POST/v1/auth/email/verifynone
POST/v1/auth/password/forgotnone
POST/v1/auth/password/resetnone

Sessions

MethodPathAuth
GET/v1/auth/sessionscookie/Bearer
DELETE/v1/auth/sessions/:idcookie/Bearer
DELETE/v1/auth/sessionscookie/Bearer

Trusted browsers

MethodPathAuth
POST/v1/auth/trusted-browserscookie/Bearer
GET/v1/auth/trusted-browserscookie/Bearer
DELETE/v1/auth/trusted-browsers/:idcookie/Bearer

Users

MethodPathAuth
GET/v1/users/mecookie/Bearer
PATCH/v1/users/mecookie/Bearer
POST/v1/users/me/passwordcookie/Bearer
POST/v1/users/me/avatarcookie/Bearer
DELETE/v1/users/me/avatarcookie/Bearer

Invitations + team

MethodPathAuth
POST/v1/orgs/:org_id/invitationscookie/Bearer + members.invite
GET/v1/orgs/:org_id/invitationscookie/Bearer + members.list
DELETE/v1/orgs/:org_id/invitations/:idcookie/Bearer + members.invite
POST/v1/orgs/:org_id/invitations/:id/resendcookie/Bearer + members.invite
GET/v1/auth/invitations/previewnone (token in query)
POST/v1/auth/invitations/acceptnone / optional
GET/v1/orgs/:org_id/memberscookie/Bearer + members.list
PATCH/v1/orgs/:org_id/members/:user_idcookie/Bearer + role grant authz
DELETE/v1/orgs/:org_id/members/:user_idcookie/Bearer + members.remove

The LoginResponse discriminated union

POST /v1/auth/register, POST /v1/auth/login, POST /v1/auth/mfa/challenge, POST /v1/auth/passkey/login/complete, POST /v1/auth/email-otp/verify, and POST /v1/auth/invitations/accept (new-user branch) all share a single response shape, discriminated by the status field:

// status = "success" — full session issued
{
"status": "success",
"user": { "user_id": "...", "organization_id": "...", "email": "alice@example.com", "auth_method": "password", "session_family_id": "...", "scopes": [], "allowed_ips": [], "allowed_referrers": [], "extensions": {} },
"capabilities": { "role": "owner", "permissions": ["..."] },
"access_token": "eyJ...",
"expires_in": 900
}
// status = "mfa_required" — caller must complete MFA challenge
{
"status": "mfa_required",
"mfa_token": "eyJ...",
"mfa_token_expires_in": 300
}

Always switch on status before reading the rest of the body — accessing access_token on an mfa_required response is a TypeScript-side error.

Error envelope

Every non-2xx response follows the same shape:

{
"error": {
"code": "invalid_input",
"message": "email must be a valid email address",
"type": "validation_error"
}
}
  • code — a stable machine-readable string. Safe to switch on in code.
  • message — a human-readable explanation. Localize at your discretion.
  • type — error category. Useful for grouping in logs / metrics.

See Errors for the complete catalog.

Content negotiation

Every request body is application/json. Every response body is application/json. The only exception is POST /v1/users/me/avatar, which accepts multipart/form-data.

Idempotency

The SDK does not implement an Idempotency-Key header. Retries are safe for:

  • All GET requests
  • POST /v1/auth/logout (no-op if already logged out)
  • DELETE of an already-revoked entity
  • POST /v1/auth/mfa/disable (idempotent)

Retries are NOT safe for:

  • POST /v1/auth/login — every call increments rate-limit + audit counters
  • POST /v1/auth/mfa/challenge — single-use mfa_token
  • POST /v1/auth/password/reset — single-use token

Cookies set by the SDK

CookieSet byScopeLifetime
identsphere_atregister / login / refresh / passkeyPath=/, HttpOnlyaccess_expiry_secs
identsphere_rtregister / login / refresh / passkeyPath={route_prefix}, HttpOnlyrefresh_cookie_max_age_secs
identsphere_csrfregister / login / refresh / passkeyPath=/, not HttpOnlymatches access token
identsphere_trustPOST /v1/auth/trusted-browsersPath={route_prefix}, HttpOnly30 days

All cookies carry SameSite=Lax and Secure if cookies_secure = true.