Sign-in & sign-up
- Written for
- + Written for
- Deprecated
- + Deprecated
- Applies to
- + Applies to
AdminUpdated Sep 11, 2026
Sign-in & sign-up
Sign-in and sign-up are modelled as attempts: you create one, then advance it step by step. Each response carries a status describing what is needed next. The SDKs drive this for you; this page documents the endpoints for custom UIs.
Sign-up
POST /v1/client/sign_ups → start an email+password sign-up
POST /v1/client/sign_ups/:id/prepare_verification → (re)send a verification code (1/30s, 5/hr per address)
POST /v1/client/sign_ups/:id/attempt_verification → submit the code (3 attempts, then invalidated)Sign-in — first factor
POST /v1/client/sign_ins → start; returns the factor list (identical for unknown identifiers)
POST /v1/client/sign_ins/:id/prepare_first_factor → send an email code or magic link; returns this tab's poll_secret
POST /v1/client/sign_ins/:id/attempt_first_factor → submit a first factor; advances to MFA or completes
GET /v1/client/sign_ins/:id → poll an attempt (with poll_secret); returns a ticket once complete
GET /v1/client/sign_ins/verify → magic-link target; completes the attemptThe response for an unknown identifier is deliberately identical to a known one — the API never reveals which accounts exist.
Second factor (MFA)
POST /v1/client/sign_ins/:id/prepare_second_factor → offer a passkey as the second factor
POST /v1/client/sign_ins/:id/attempt_second_factor → submit a TOTP or recovery code
POST /v1/client/sign_ins/:id/prepare_mfa_enrollment → start TOTP enrollment for an attempt parked by a required-MFA policy
POST /v1/client/sign_ins/:id/attempt_mfa_enrollment → confirm with two consecutive codes and completePasswordless & passkeys
POST /v1/client/sign_ins/passkey/begin → begin passwordless sign-in (names no user)
POST /v1/client/sign_ins/passkey/finish → verify an assertion and issue a sessionQR cross-device sign-in ("scan to sign in on this TV/desktop"):
POST /v1/client/qr_sign_ins → returns QR token, number-match code, this tab's poll secret
GET /v1/client/qr_sign_ins/:qr_token → phone lookup (device, coarse location, match code)
POST /v1/client/qr_sign_ins/:qr_token/approve | /deny → phone confirms the number matchPassword reset
POST /v1/client/password_resets → request a reset (identical response whether or not the address exists)
POST /v1/client/password_resets/:id/attempt_verification → submit the emailed code
POST /v1/client/password_resets/:id/attempt_second_factor→ second factor (reset never bypasses MFA)
POST /v1/client/password_resets/:id/set_new_password → set new password, revoke every sessionSocial, enterprise & federated
POST /v1/client/sign_ins/oauth → begin an OAuth sign-in; returns the provider authorize URL
POST /v1/client/sign_ins/id_token → native / One-Tap (Google GSI, Apple, Facebook Limited Login)
POST /v1/client/sign_ins/sso → begin enterprise OIDC SSO (resolve by connection id or email domain)
POST /v1/client/sign_ins/saml → begin enterprise SAML SSO
POST /v1/client/sign_ins/ldap → LDAP/AD inbound sign-in (JIT create/link)
POST /v1/client/sign_ins/kerberos → Kerberos / IWA (SPNEGO) behind a trusted proxy
POST /v1/client/sign_ins/external_jwt → verify a foreign provider JWT (migration interop)Web3 wallet sign-in (SIWE / SIWS / SIWF) and Telegram Login are also supported via /v1/oauth/… nonce+verify pairs — see the Frontend endpoint index. Every path honours the instance MFA gate.
Completing an attempt
A completed attempt yields a one-time ticket. Exchange it for session cookies:
POST /v1/client/tickets/exchange → exchange a one-time ticket for a sessionExample (SDK)
import { AtlasProvider, useSignIn } from '@atlas/react';
const { signIn } = useSignIn();
// The SDK walks create → attempt → ticket exchange and manages the session:
await signIn.create({ identifier: 'ada@example.com', password: '…' });Was this page helpful?