Preview. This site is still being built. Features, prices and terms may change, and nothing here is a binding offer. Read the preview notice

Preview. Still being built; nothing here is a binding offer. Details

Authentication and profile

57 routes. Paths are relative to https://api.intersink.com/v1.

All groups

Login with Apple (Sign in with Apple)

POST/auth/apple

Public: no sign-in needed.

Client sends the Apple identity token; the server verifies it against Apple's public keys and logs the user in (creating the account on first sign-in). Returns the same { access_token, refresh_token, user } as OTP.

Parameters

NameTypeDescription
x-refstring, header
x-install-idstring, header

Request body application/json

FieldTypeDescription
identity_tokenrequiredstringThe Apple identity token from Sign in with Apple Example: "eyJraWQiOi..."
channel_idstringExample: "REF-A1"
device_idstringExample: "iphone_15_pro"

Response

200. The payload in data is not described in the spec yet. Login successful

Login with Google (Sign in with Google)

POST/auth/google

Public: no sign-in needed.

Client sends the Google ID token; the server verifies it with Google and logs the user in (creating the account on first sign-in). Returns the same { access_token, refresh_token, user } as OTP login.

Parameters

NameTypeDescription
x-refstring, header
x-install-idstring, header

Request body application/json

FieldTypeDescription
id_tokenrequiredstringThe Google ID token obtained by the client from Google Sign-In Example: "eyJhbGciOi..."
channel_idstringExample: "REF-A1"
device_idstringExample: "iphone_15_pro"

Response

200. The payload in data is not described in the spec yet. Login successful

Verify OTP & Login

POST/auth/login

Public: no sign-in needed.

Any code sent to this address on this channel in the last 15 minutes works (the newest first), once. A wrong code: 401 INVALID_CODE with attemptsLeft ("That code didn't match. 4 tries left."). The 5th wrong try burns the code: 429 TOO_MANY_ATTEMPTS without retryAfterSeconds, ask for a new code. More than 20 wrong codes in an hour for the address lock code checks: 429 TOO_MANY_ATTEMPTS with retryAfterSeconds and unlockAt. A used or replaced code: 401 CODE_EXPIRED.

Parameters

NameTypeDescription
x-refstring, header

Request body application/json

FieldTypeDescription
emailrequiredstringExample: "user@example.com"
otprequiredstringAt least 6 characters. Example: "123456"
device_idstringExample: "iphone_15_pro"
channel_idstringExample: "REF-A1"
restore_accountbooleanRestore a closed account during its 30-day grace window. Without it, signing in to a closed account answers 403 ACCOUNT_CLOSED.

Response

200. The payload in data is not described in the spec yet. Login successful

Verify OTP and Login (Mobile Apps)

POST/auth/login-app

Public: no sign-in needed.

The app's twin of /auth/login: tokens come in the body. Send the channel's app key (X-App-Key) and X-Install-Id: a random id the app makes once per install (a UUID, or 16 to 64 random letters, digits, '-' or '_') and sends on every request. The session is then bound to that install, never to the IP or user agent: it survives Wi-Fi/cellular changes and OS updates, and its tokens are refused (401 INSTALL_MISMATCH) from any other install. Without the header the session is bound to nothing. Two answers: a session (access_token, refresh_token, user), or, when the account has an authenticator or a 2-step passkey, mfa_required: true with methods and a 5-minute pending_token to finish at /auth/mfa/totp, /auth/mfa/otp or /auth/mfa/passkey/verify (send the same X-Install-Id there). Errors: 401 INVALID_CODE (with attemptsLeft), 401 CODE_EXPIRED, 429 TOO_MANY_ATTEMPTS, 403 ACCOUNT_CLOSED (restore with restore_account: true), 400 INVALID_INSTALL_ID.

Parameters

NameTypeDescription
x-refstring, header
x-install-idstring, header

Request body application/json

FieldTypeDescription
emailrequiredstringExample: "user@example.com"
otprequiredstringAt least 6 characters. Example: "123456"
device_idstringExample: "iphone_15_pro"
channel_idstringExample: "REF-A1"
restore_accountbooleanRestore a closed account during its 30-day grace window. Without it, signing in to a closed account answers 403 ACCOUNT_CLOSED.

Response

200. The payload in data is not described in the spec yet. A session, or a second step to finish

Login with email + password (OTP alternative)

POST/auth/login-password

Public: no sign-in needed.

Logs in with a password. If the account has a second factor enrolled, no tokens are returned yet: the response is { mfa_required: true, methods, pending_token } and the client finishes with /auth/mfa/totp, /auth/mfa/otp or /auth/mfa/passkey/verify.

Parameters

NameTypeDescription
x-refstring, header
x-install-idstring, header

Request body application/json

FieldTypeDescription
emailstringEmail or username (one of the two is required) Example: "user@example.com"
usernamestringSign in with the username of the account's profile in this channel. Example: "riya_716"
passwordrequiredstringExample: "MyS3cret!"
device_idstringExample: "iphone_15_pro"
channel_idstringExample: "REF-A1"
captchastringCloudflare Turnstile token, when the channel turns the check on (GET /auth/sign-in-options) At most 2048 characters.

Response

200. The payload in data is not described in the spec yet. Login successful or OTP required

Finish a TOTP-protected login with an authenticator/backup code

POST/auth/login-totp

Public: no sign-in needed.

Parameters

NameTypeDescription
x-refstring, header
x-install-idstring, header

Request body application/json

FieldTypeDescription
emailrequiredstringExample: "user@example.com"
coderequiredstringAuthenticator or backup code Example: "123456"
device_idstringExample: "iphone_15_pro"
channel_idstringExample: "REF-A1"
captchastringCloudflare Turnstile token (channels with auth.captcha=turnstile; see GET /auth/sign-in-options) At most 2048 characters.

Response

200. The payload in data is of type object.

Logout and revoke session

POST/auth/logout

Needs a signed-in user (Bearer token or access_token cookie).

Response

200. The payload in data is not described in the spec yet. Logged out

Get current user profile

GET/auth/me

Needs a signed-in user (Bearer token or access_token cookie).

Response

200. The payload in data is not described in the spec yet. User profile returned

Which login methods an email supports (password/totp/otp/passkey)

POST/auth/methods

Public: no sign-in needed.

Parameters

NameTypeDescription
x-refstring, header

Request body application/json

FieldTypeDescription
emailrequiredstringExample: "user@example.com"
channel_idstringExample: "REF-A1"

Response

200. The payload in data is not described in the spec yet.

Complete login with the emailed OTP

POST/auth/mfa/otp

Public: no sign-in needed.

Parameters

NameTypeDescription
x-install-idstring, header

Request body application/json

FieldTypeDescription
pending_tokenrequiredstringThe pending-login token from the first factor
otprequiredstringThe emailed OTP Example: "123456"

Response

200. The payload in data is not described in the spec yet.

Second-factor passkey: get options

POST/auth/mfa/passkey/options

Public: no sign-in needed.

Parameters

NameTypeDescription
x-install-idstring, header

Request body application/json

FieldTypeDescription
pending_tokenrequiredstringThe pending-login token from the first factor

Response

200. The payload in data is of type object.

Second-factor passkey: verify and complete login

POST/auth/mfa/passkey/verify

Public: no sign-in needed.

Parameters

NameTypeDescription
x-install-idstring, header

Request body application/json

FieldTypeDescription
pending_tokenrequiredstringThe pending-login token from the first factor
responserequiredobjectThe WebAuthn assertion response

Response

200. The payload in data is not described in the spec yet.

Complete login with an authenticator/backup code

POST/auth/mfa/totp

Public: no sign-in needed.

Parameters

NameTypeDescription
x-install-idstring, header

Request body application/json

FieldTypeDescription
pending_tokenrequiredstringThe pending-login token from the first factor
coderequiredstringAuthenticator or backup code Example: "123456"

Response

200. The payload in data is not described in the spec yet.

Change the password or recovery key, step 2

POST/auth/opaque/credential/finish

Needs a signed-in user (Bearer token or access_token cookie).

Stores the new record. Changing the password signs out every other session.

Request body application/json

FieldTypeDescription
credentialrequiredstringOne of: "password", "recovery".
registration_recordrequiredstringAt most 512 characters.

Response

200. The payload in data is not described in the spec yet.

Change the password or recovery key, step 1

POST/auth/opaque/credential/start

Needs a signed-in user (Bearer token or access_token cookie).

Needs a recent sign-in (an OPAQUE sign-in counts for 10 minutes). Otherwise 401 STEP_UP_REQUIRED.

Request body application/json

FieldTypeDescription
credentialrequiredstringOne of: "password", "recovery".
registration_requestrequiredstringAt most 256 characters.

Response

200. The payload in data is not described in the spec yet.

OPAQUE sign-in, step 2

POST/auth/opaque/login/finish

Public: no sign-in needed.

App tokens { account_id, access_token, refresh_token, expires_in } (rotate with /auth/refresh-app); 401 INVALID_CREDENTIALS. An enrolled authenticator or passkey still applies (mfa_required).

Parameters

NameTypeDescription
x-refstring, header

Request body application/json

FieldTypeDescription
login_idrequiredstringAt most 64 characters.
finish_login_requestrequiredstringOPAQUE KE3 / finishLoginRequest (base64url) At most 256 characters.
device_idstringAt most 255 characters. Example: "iphone-1"

Response

200. The payload in data is of type object.

OPAQUE sign-in, step 1

POST/auth/opaque/login/start

Public: no sign-in needed.

credential = password | recovery. Unknown usernames get a well-formed fake response. 429 TOO_MANY_ATTEMPTS with retryAfterSeconds (and retry_after) after 10 failed sign-ins per username per hour.

Parameters

NameTypeDescription
x-refstring, header

Request body application/json

FieldTypeDescription
usernamerequiredstringAt most 64 characters. Example: "asha.07"
start_login_requestrequiredstringOPAQUE KE1 / startLoginRequest (base64url) At most 512 characters.
credentialrequiredstringOne of: "password", "recovery".
captchastringCloudflare Turnstile token (channels with auth.captcha=turnstile; see GET /auth/sign-in-options) At most 2048 characters.

Response

200. The payload in data is not described in the spec yet.

OPAQUE signup, step 2: create the account

POST/auth/opaque/register/finish

Public: no sign-in needed.

Stores the password and recovery records and signs in. Needs a solved proof-of-work, a Turnstile token when the channel asks, and at most 5 new accounts per IP per day. QA mode (dev only): a .test email proven by its code from the test inbox makes a QA account, counted against the shared QA quota instead of the per-IP limit and purged after 7 days.

Parameters

NameTypeDescription
x-refstring, header

Request body application/json

FieldTypeDescription
usernamerequiredstringAt most 64 characters. Example: "asha.07"
registration_recordrequiredstringOPAQUE RegistrationRecord for the password At most 512 characters.
recovery_recordrequiredstringOPAQUE RegistrationRecord for the recovery key (mandatory) At most 512 characters.
powrequiredobject
pow.saltrequiredstringAt most 64 characters.
pow.bitsrequirednumber
pow.exprequirednumberms since epoch
pow.sigrequiredstringAt most 128 characters.
pow.noncerequiredstring1–64 chars of [A-Za-z0-9_-] At most 64 characters.
captchastringCloudflare Turnstile token (channels with auth.captcha=turnstile) At most 2048 characters.
deviceobject
device.device_idstringAt most 255 characters. Example: "iphone-1"
emailstringOptional email (recovery only). Needs email_otp from POST /auth/request-otp. Required when the channel keeps auth.email_required on. A .test address is accepted only on the dev API while QA mode is in effect (its code is read from the test inbox): the account is then tagged as a QA account, counts against the shared QA quota instead of SIGNUP_LIMIT and is purged after 7 days (docs/qa-mode.md). Elsewhere it is refused: 400 QA_EMAIL_REFUSED, or 503 QA_STORE_NOT_READY while QA mode waits for its tables. At most 254 characters.
email_otpstringExample: "123456"

Response

200. The payload in data is not described in the spec yet. { account_id, access_token, refresh_token, expires_in }

OPAQUE signup, step 1 (once per credential)

POST/auth/opaque/register/start

Public: no sign-in needed.

Checks the username is free in the channel and answers the OPAQUE registration request. Call it twice with the same username: once for the password, once for the recovery key.

Parameters

NameTypeDescription
x-refstring, header

Request body application/json

FieldTypeDescription
usernamerequiredstring3–32 chars of [a-z0-9_.] with a letter (asha). The older form with '.' and a 2-digit discriminator (asha.07) is still accepted. Normalised to lowercase. At most 64 characters. Example: "asha"
registration_requestrequiredstringOPAQUE RegistrationRequest (base64url). Call once for the password and once for the recovery key. At most 256 characters.

Response

200. The payload in data is not described in the spec yet.

Passkey login, step 1: get options

POST/auth/passkey/login/options

Public: no sign-in needed.

Parameters

NameTypeDescription
x-refstring, header

Request body application/json

FieldTypeDescription
emailstringOmit for a discoverable (usernameless) passkey sign-in Example: "user@example.com"
channel_idstringExample: "REF-A1"

Response

200. The payload in data is of type object.

Passkey login, step 2: verify the assertion and issue tokens

POST/auth/passkey/login/verify

Public: no sign-in needed.

Parameters

NameTypeDescription
x-refstring, header
x-install-idstring, header

Request body application/json

FieldTypeDescription
emailstringExample: "user@example.com"
challenge_idstringFrom passkey/login/options when no e-mail was given
responserequiredobjectAssertion response from the authenticator
device_idstringExample: "iphone_15_pro"
channel_idstringExample: "REF-A1"

Response

200. The payload in data is not described in the spec yet.

Passkey registration, step 1: get options

POST/auth/passkey/register/options

Needs a signed-in user (Bearer token or access_token cookie).

Response

200. The payload in data is not described in the spec yet.

Passkey registration, step 2: verify and store

POST/auth/passkey/register/verify

Needs a signed-in user (Bearer token or access_token cookie).

Request body application/json

FieldTypeDescription
responserequiredobjectAttestation response from the authenticator
device_namestringExample: "iPhone 15"

Response

200. The payload in data is not described in the spec yet.

List the signed-in user's passkeys

GET/auth/passkeys

Needs a signed-in user (Bearer token or access_token cookie).

Response

200. The payload in data is not described in the spec yet.

Remove one of the signed-in user's passkeys

DELETE/auth/passkeys/{id}

Needs a signed-in user (Bearer token or access_token cookie).

Parameters

NameTypeDescription
idrequirednumber, path

Response

200. The payload in data is not described in the spec yet.

Proof-of-work challenge for a new OPAQUE account

GET/auth/pow

Public: no sign-in needed.

Stateless: { salt, bits, exp, sig }. Find a nonce so that sha256(salt ‖ nonce) has bits leading zero bits, then send { salt, bits, exp, sig, nonce } as pow to /auth/opaque/register/finish. Valid 10 minutes, one account per solution.

Response

200. The payload in data is of type object.

Update user profile details

PATCH/auth/profile

Needs a signed-in user (Bearer token or access_token cookie).

Request body application/json

FieldTypeDescription
firstnamestringAt most 255 characters.
lastnamestringAt most 255 characters.
usernamestringAt most 255 characters.

Response

200. The payload in data is not described in the spec yet. Profile updated successfully

How many unused recovery codes remain (never the codes)

GET/auth/recovery-codes

Needs a signed-in user (Bearer token or access_token cookie).

Response

200. The payload in data is not described in the spec yet.

Replace all recovery codes (needs a current authenticator code). The new codes are returned once.

POST/auth/recovery-codes

Needs a signed-in user (Bearer token or access_token cookie).

Request body application/json

FieldTypeDescription
coderequiredstringCurrent authenticator code (or an unused recovery code) At most 32 characters. Example: "123456"

Response

200. The payload in data is not described in the spec yet.

Refresh authentication tokens (Web)

POST/auth/refresh

Public: no sign-in needed.

Response

200. The payload in data is not described in the spec yet. New tokens issued

Refresh authentication tokens (Mobile Apps)

POST/auth/refresh-app

Public: no sign-in needed.

Trade the refresh token for a new pair. Never bound to the IP or user agent. A session signed in with X-Install-Id needs that same header here (401 INSTALL_MISMATCH otherwise: sign in again, refreshing won't help). An older session refreshed with the header becomes bound to that install. 401 UNAUTHENTICATED: the refresh token is unknown, spent, revoked or older than 30 days.

Parameters

NameTypeDescription
x-install-idstring, header

Request body application/json

FieldTypeDescription
refresh_tokenrequiredstring

Response

200. data is object (RefreshResultDto). New tokens issued

FieldTypeDescription
access_tokenrequiredstringNew access token (15 minutes) Example: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI4ZDFmNmE3ZSJ9.c2lnbmF0dXJl"
refresh_tokenrequiredstringNew refresh token: the one sent is spent (a repeat within 30 seconds returns this same pair) Example: "ib1.5e8f3c2a9b7d4e6f1a0c8b2d4e6f8a1c3e5b7d9f1a3c5e7b9d1f3a5c7e9b1d3f.0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e"

Request 6-digit OTP (Login/Register)

POST/auth/request-otp

Public: no sign-in needed.

Always answers 200 with the same body for any address: an unknown address, an existing account, an account with no saved mobile (delivery sms/whatsapp), a channel closed to new accounts and a blocked new address can't be told apart. A code is sent only when the address can sign in or sign up on this channel (signup policy, or a pending team invite there). The answer takes a minimum time (it follows the route's own speed) and does not wait for delivery. retryAfterSeconds says when Resend opens. Resend: 30 s after the first code, 60 s after the second, then 120 s, at most 5 codes per address and channel in 15 minutes (429 OTP_RATE_LIMIT_REACHED, reason cooldown or window). Every code sent stays valid for 15 minutes. Wider caps: per address across all channels (429 OTP_RECIPIENT_LIMIT), per IP, IPv6 by /64 network (429 OTP_IP_LIMIT) and per channel (429 OTP_CHANNEL_LIMIT). Every 429 carries the exact retryAfterSeconds and a Retry-After header. Parallel requests can't overshoot any of them.

Parameters

NameTypeDescription
x-refstring, header

Request body application/json

FieldTypeDescription
emailrequiredstringExample: "user@example.com"
channel_idstringExample: "REF-A1"
deliverystringHow to deliver the OTP. Defaults to "email". "sms"/"whatsapp" (worldwide via Twilio) are only for existing accounts and always go to the mobile stored on the account. SMS/WhatsApp are for account security only. One of: "email", "sms", "whatsapp". Example: "sms"
mobilestringIgnored for OTP delivery: SMS/WhatsApp always go to the account's stored mobile. Example: "+919876543210"
captchastringCloudflare Turnstile token, when the channel turns the check on (GET /auth/sign-in-options) At most 2048 characters.

Response

200. data is object (RequestOtpResultDto). Accepted. message is the same for every address; a code was sent if the address can sign in here.

FieldTypeDescription
messagerequiredstringExample: "If this address can sign in here, a code is on its way."
emailrequiredstringExample: "user@example.com"
deliveryrequiredstringOne of: "email", "sms", "whatsapp".
retryAfterSecondsrequirednumberSeconds until another code can be asked for (30 after the first, 60 after the second, then 120). Show it as a countdown on Resend. Example: 30
expiresInSecondsrequirednumberHow long this code works. Every code sent stays valid until its own expiry. Example: 900
codeLengthrequirednumberExample: 6

Reset password using an OTP (forgot password)

POST/auth/reset-password

Public: no sign-in needed.

No current password needed. First call request-otp, then submit the code here with the new password.

Parameters

NameTypeDescription
x-refstring, header

Request body application/json

FieldTypeDescription
emailrequiredstringExample: "user@example.com"
otprequiredstringAt least 6 characters. Example: "123456"
new_passwordrequiredstringExample: "MyNewS3cret!"
channel_idstringExample: "REF-A1"

Response

200. The payload in data is not described in the spec yet. Password reset successfully

The signed-in user's security log: sign-ins, failed attempts, password / two-factor / passkey changes, session sign-outs (paged, max 100)

GET/auth/security/activity

Needs a signed-in user (Bearer token or access_token cookie).

Parameters

NameTypeDescription
pagenumber, queryMinimum 1. Example: 1
limitnumber, queryMax 100 Minimum 1. Example: 25
categorystring, queryOne of: "sign_in", "session", "account", "mfa", "privacy", "vault".

Response

200. The payload in data is not described in the spec yet.

What protects the signed-in account: password set/changed, two-step methods, passkey and recovery-code counts (flags only)

GET/auth/security/summary

Needs a signed-in user (Bearer token or access_token cookie).

Response

200. The payload in data is not described in the spec yet.

List all active sessions

GET/auth/sessions

Needs a signed-in user (Bearer token or access_token cookie).

Response

200. data is object[].

Revoke a specific session

POST/auth/sessions/{id}/revoke

Needs a signed-in user (Bearer token or access_token cookie).

Parameters

NameTypeDescription
idrequiredstring, path

Response

201. The payload in data is not described in the spec yet.

Sign out everywhere: revoke every session and refresh token except this one (step-up)

POST/auth/sessions/logout-all

Needs a signed-in user (Bearer token or access_token cookie).

Needs a step-up in the last 10 minutes (401 STEP_UP_REQUIRED until POST /auth/step-up). With linked_devices: true (alias e2ee_devices), every linked end-to-end-encrypted device of the account is removed too, except this session's own device; pending device-link tokens stop working. The devices of the revoked sessions stop getting push notifications. revoked_sessions counts only the sessions this call deleted (one removed by a refresh while it runs is skipped). Any value of linked_devices other than a boolean form is 400 VALIDATION_FAILED. A row that cannot be deleted gives 503 SIGN_OUT_INCOMPLETE (send it again).

Request body application/json

FieldTypeDescription
linked_devicesbooleanAlso remove every linked end-to-end-encrypted device of the account (except this session's own device). Default false.
e2ee_devicesbooleanSame as linked_devices.

Response

200. The payload in data is not described in the spec yet.

Sign out everywhere: revoke every session and refresh token except this one (step-up)

POST/auth/sessions/revoke-all

Needs a signed-in user (Bearer token or access_token cookie).

Needs a step-up in the last 10 minutes (401 STEP_UP_REQUIRED until POST /auth/step-up). With linked_devices: true (alias e2ee_devices), every linked end-to-end-encrypted device of the account is removed too, except this session's own device; pending device-link tokens stop working. The devices of the revoked sessions stop getting push notifications. revoked_sessions counts only the sessions this call deleted (one removed by a refresh while it runs is skipped). Any value of linked_devices other than a boolean form is 400 VALIDATION_FAILED. A row that cannot be deleted gives 503 SIGN_OUT_INCOMPLETE (send it again).

Request body application/json

FieldTypeDescription
linked_devicesbooleanAlso remove every linked end-to-end-encrypted device of the account (except this session's own device). Default false.
e2ee_devicesbooleanSame as linked_devices.

Response

200. The payload in data is not described in the spec yet.

Public: the bot check and sender address for a channel's sign-in pages

GET/auth/sign-in-options

Public: no sign-in needed.

Send the channel as x-ref. captcha is { provider: 'none' } or { provider: 'turnstile', sitekey }. When it is Turnstile, request-otp, login-password, login-totp and opaque/login/start need the widget's token as captcha. sender is the address sign-in codes come from.

Parameters

NameTypeDescription
x-refstring, header

Response

200. The payload in data is not described in the spec yet.

Whether this session has confirmed it's you in the last 10 minutes, and the ways it can

GET/auth/step-up

Needs a signed-in user (Bearer token or access_token cookie).

Response

200. The payload in data is not described in the spec yet.

Confirm it's you (passkey, authenticator, password or e-mailed code); lasts 10 minutes for this session

POST/auth/step-up

Needs a signed-in user (Bearer token or access_token cookie).

Request body application/json

FieldTypeDescription
methodrequiredstringOne of: "passkey", "totp", "password", "email".
codestringAuthenticator, recovery or e-mailed code At most 32 characters.
passwordstringAt most 256 characters.
responseobjectThe passkey assertion (WebAuthn response JSON)

Response

200. The payload in data is not described in the spec yet.

E-mail a 6-digit confirmation code to the account's own address

POST/auth/step-up/email

Needs a signed-in user (Bearer token or access_token cookie).

Response

200. The payload in data is not described in the spec yet.

End the confirmation early

POST/auth/step-up/end

Needs a signed-in user (Bearer token or access_token cookie).

Response

200. The payload in data is not described in the spec yet.

Confirm it's you with the account's password (OPAQUE), step 2

POST/auth/step-up/opaque/finish

Needs a signed-in user (Bearer token or access_token cookie).

Steps up THIS session for 10 minutes, as every step-up method does, and answers the GET /auth/step-up status. No new session and no tokens. If the account has an authenticator, passkey or e-mail codes, nothing is granted yet: the answer is { active: false, mfa_required: true, methods, expires_in: 300 } and the client finishes at /auth/step-up/opaque/second-factor. 401 INVALID_CREDENTIALS for a wrong password and for an expired, used or foreign login_id; 429 TOO_MANY_ATTEMPTS. Recorded as step_up_opaque (failures as step_up_failed, or login_locked at the limit).

Request body application/json

FieldTypeDescription
login_idrequiredstringlogin_id from /auth/step-up/opaque/start At most 64 characters.
finish_login_requestrequiredstringOPAQUE KE3 / finishLoginRequest (base64url) At most 256 characters.

Response

200. The payload in data is of type object.

Confirm it's you with the password (OPAQUE), the second factor

POST/auth/step-up/opaque/second-factor

Needs a signed-in user (Bearer token or access_token cookie).

Only after /auth/step-up/opaque/finish answered mfa_required, within 5 minutes, on the same session and client. method = one of its methods: totp (authenticator or recovery code), passkey (assertion for POST /auth/step-up/passkey/options) or email (code from POST /auth/step-up/email). A wrong code can be retried until the step-up lockout; success steps up this session for 10 minutes, once. Errors as at /auth/mfa/*: 401 INVALID_CODE, INVALID_CREDENTIALS (passkey, other client), CODE_EXPIRED (nothing pending, or already used), 400 FACTOR_NOT_AVAILABLE, 429 TOO_MANY_ATTEMPTS.

Request body application/json

FieldTypeDescription
methodrequiredstringOne of the methods the finish step answered. email: the code from POST /auth/step-up/email. passkey: the assertion for POST /auth/step-up/passkey/options. One of: "totp", "passkey", "email".
codestringAuthenticator code, recovery code or e-mailed code At most 32 characters.
responseobjectThe passkey assertion (WebAuthn response JSON)

Response

200. The payload in data is not described in the spec yet.

Confirm it's you with the account's password (OPAQUE), step 1

POST/auth/step-up/opaque/start

Needs a signed-in user (Bearer token or access_token cookie).

The OPAQUE login exchange for the signed-in account (the username comes from the session, never the body). credential = password (default) | recovery. Answers { login_id, login_response }; login_id lives 2 minutes, works once, and only for this session from this client. The same lockout as sign-in: 429 TOO_MANY_ATTEMPTS after 10 failed tries an hour, sign-in and step-up together. 400 STEP_UP_METHOD_UNAVAILABLE when the account has no such credential; 404 METHOD_DISABLED when its channel turned OPAQUE off.

Request body application/json

FieldTypeDescription
start_login_requestrequiredstringOPAQUE KE1 / startLoginRequest (base64url) At most 512 characters.
credentialstringOne of: "password", "recovery".

Response

200. The payload in data is not described in the spec yet. { login_id, login_response }

Passkey challenge to confirm it's you

POST/auth/step-up/passkey/options

Needs a signed-in user (Bearer token or access_token cookie).

Response

200. The payload in data is of type object.

Stage 2: Switch active profile/business and get new tokens (Web)

POST/auth/switch-business

Needs a signed-in user (Bearer token or access_token cookie).

Request body application/json

FieldTypeDescription
profile_idstringExample: "8b98f219-c120-4a8e-a9b0-4b2a8d1a1b1b"
business_idstringExample: "5f3d06b8-3d46-4b0c-aae2-b443b2ea9973"
channel_idstringExample: "42f5bb84-b9d6-41b9-b837-e9bba90ff03b"
refresh_tokenstring

Response

201. The payload in data is not described in the spec yet.

Stage 2: Switch active profile/business/channel (Mobile/CRM Apps)

POST/auth/switch-business-app

Needs a signed-in user (Bearer token or access_token cookie).

Request body application/json

FieldTypeDescription
profile_idstringExample: "8b98f219-c120-4a8e-a9b0-4b2a8d1a1b1b"
business_idstringExample: "5f3d06b8-3d46-4b0c-aae2-b443b2ea9973"
channel_idstringExample: "42f5bb84-b9d6-41b9-b837-e9bba90ff03b"
refresh_tokenstring

Response

201. The payload in data is not described in the spec yet.

Stage 2: Switch active profile/business/channel (Mobile/CRM Apps)

POST/auth/switch-channel

Needs a signed-in user (Bearer token or access_token cookie).

Request body application/json

FieldTypeDescription
profile_idstringExample: "8b98f219-c120-4a8e-a9b0-4b2a8d1a1b1b"
business_idstringExample: "5f3d06b8-3d46-4b0c-aae2-b443b2ea9973"
channel_idstringExample: "42f5bb84-b9d6-41b9-b837-e9bba90ff03b"
refresh_tokenstring

Response

201. The payload in data is not described in the spec yet.

Stage 2: Switch active profile/business and get new tokens (Web)

POST/auth/switch-profile

Needs a signed-in user (Bearer token or access_token cookie).

Request body application/json

FieldTypeDescription
profile_idstringExample: "8b98f219-c120-4a8e-a9b0-4b2a8d1a1b1b"
business_idstringExample: "5f3d06b8-3d46-4b0c-aae2-b443b2ea9973"
channel_idstringExample: "42f5bb84-b9d6-41b9-b837-e9bba90ff03b"
refresh_tokenstring

Response

201. The payload in data is not described in the spec yet.

Stage 2: Switch active profile/business/channel (Mobile/CRM Apps)

POST/auth/switch-profile-app

Needs a signed-in user (Bearer token or access_token cookie).

Request body application/json

FieldTypeDescription
profile_idstringExample: "8b98f219-c120-4a8e-a9b0-4b2a8d1a1b1b"
business_idstringExample: "5f3d06b8-3d46-4b0c-aae2-b443b2ea9973"
channel_idstringExample: "42f5bb84-b9d6-41b9-b837-e9bba90ff03b"
refresh_tokenstring

Response

201. The payload in data is not described in the spec yet.

Disable authenticator (TOTP) two-factor

POST/auth/totp/disable

Needs a signed-in user (Bearer token or access_token cookie).

Request body application/json

FieldTypeDescription
coderequiredstringCode from authenticator app Example: "123456"

Response

200. The payload in data is not described in the spec yet.

Confirm a code to enable TOTP; returns backup codes

POST/auth/totp/enable

Needs a signed-in user (Bearer token or access_token cookie).

Request body application/json

FieldTypeDescription
coderequiredstringCode from authenticator app Example: "123456"

Response

200. The payload in data is not described in the spec yet.

Start authenticator (TOTP) setup; returns a QR code

POST/auth/totp/setup

Needs a signed-in user (Bearer token or access_token cookie).

Response

200. The payload in data is not described in the spec yet.

Enable/disable two-factor authentication

PATCH/auth/two-factor

Needs a signed-in user (Bearer token or access_token cookie).

Request body application/json

FieldTypeDescription
enabledrequiredbooleanEnable or disable 2FA Example: true

Response

200. The payload in data is not described in the spec yet. Two-factor preference updated