Skip to main content

User sessions, MFA and passkeys

These APIs protect users of your application. Your own dashboard MFA and sessions are managed in Settings. Complete the availability checks before integrating application MFA or passkeys. Enrollment must be confirmed; recovery codes are single-use.

API conventions · All endpoints · Schemas

/e/v1/user/sessions/​

List application-user sessions or revoke other sessions.

Availability note: standalone access with the credential described below has a known authentication limitation. Check integration availability before relying on this operation. If it returns an unexpected 401, contact support with the endpoint and sanitized response.

Authentication: application-user token in Authorization: Bearer APPLICATION_TOKEN.

Use the application-user Bearer token. These sessions belong to your application users, separately from your dashboard account sessions.

GET​

No body; at most 200 sessions ordered by last_seen_at. is_current identifies the token’s matching tracked session.

Success and error response examples

Illustrative values; conditional branches are alternatives. Fields vary with the operation and account configuration.

200 — json


{
"results": [
{
"id": "11111111-1111-4111-8111-111111111111",
"device_name": "EXAMPLE_DEVICE_NAME",
"user_agent": "EXAMPLE_USER_AGENT",
"ip_address": "EXAMPLE_IP_ADDRESS",
"created_at": "EXAMPLE_CREATED_AT",
"last_seen_at": "EXAMPLE_LAST_SEEN_AT",
"expires_at": "EXAMPLE_EXPIRES_AT",
"revoked_at": "EXAMPLE_REVOKED_AT",
"revoked_reason": "EXAMPLE_REVOKED_REASON",
"is_active": true,
"is_current": true
}
]
}

DELETE​

No body. Revokes sessions except the current session when it can be identified from the JWT jti. Returns revoked count.

Success and error response examples

Illustrative values; conditional branches are alternatives. Fields vary with the operation and account configuration.

200 — json


{
"revoked": "EXAMPLE_REVOKED"
}

/e/v1/user/sessions/{session_id}/​

Revoke one application-user session.

Availability note: standalone access with the credential described below has a known authentication limitation. Check integration availability before relying on this operation. If it returns an unexpected 401, contact support with the endpoint and sanitized response.

Authentication: application-user token in Authorization: Bearer APPLICATION_TOKEN.

DELETE​

No body. Session must belong to the authenticated application user. New revocation returns 204; already revoked returns 200.

Path parameters: session_id (uuid, required).

Success and error response examples

Illustrative values; conditional branches are alternatives. Fields vary with the operation and account configuration.

200 — json


{
"message": "Already revoked"
}

204 — json

No response body.

404 — json


{
"error": "Session not found"
}

/e/v1/user/mfa/devices/​

List application-user MFA devices.

Availability note: standalone access with the credential described below has a known authentication limitation. Check integration availability before relying on this operation. If it returns an unexpected 401, contact support with the endpoint and sanitized response.

Authentication: application-user token in Authorization: Bearer APPLICATION_TOKEN.

GET​

No body. Results contain device metadata, not enrollment secrets.

Success and error response examples

Illustrative values; conditional branches are alternatives. Fields vary with the operation and account configuration.

200 — json


{
"results": [
[]
]
}

/e/v1/user/mfa/totp/enroll/​

Begin TOTP enrollment.

Availability note: standalone access with the credential described below has a known authentication limitation. Check integration availability before relying on this operation. If it returns an unexpected 401, contact support with the endpoint and sanitized response.

Authentication: application-user token in Authorization: Bearer APPLICATION_TOKEN.

POST​

Optional JSON name string. Returns device_id, secret and otpauth_uri. Store the secret in an authenticator, then confirm with a current code; enrollment alone is not activation.

Request fields (combine with the requirements and schema above):

LocationFieldFallback when absent
bodynamenot supplied

Example request body:


{
"name": "My authenticator"
}

Success and error response examples

Illustrative values; conditional branches are alternatives. Fields vary with the operation and account configuration.

200 — json


{
"device_id": "EXAMPLE_DEVICE_ID",
"secret": "EXAMPLE_SECRET",
"otpauth_uri": "EXAMPLE_OTPAUTH_URI"
}

/e/v1/user/mfa/totp/confirm/​

Confirm a pending TOTP device.

Availability note: standalone access with the credential described below has a known authentication limitation. Check integration availability before relying on this operation. If it returns an unexpected 401, contact support with the endpoint and sanitized response.

Authentication: application-user token in Authorization: Bearer APPLICATION_TOKEN.

POST​

Required device_id UUID and code string. Device must belong to the application user.

Request fields (combine with the requirements and schema above):

LocationFieldFallback when absent
bodydevice_idnot supplied
bodycodenot supplied

Example request body:


{
"device_id": "11111111-1111-4111-8111-111111111111",
"code": "123456"
}

Success and error response examples

Illustrative values; conditional branches are alternatives. Fields vary with the operation and account configuration.

200 — json


{
"confirmed": true
}

400 — json


{
"error": "device_id and code are required"
}

400 — json


{
"error": "Invalid code"
}

404 — json


{
"error": "Device not found"
}

/e/v1/user/mfa/totp/disable/​

Remove a user-owned MFA device.

Availability note: standalone access with the credential described below has a known authentication limitation. Check integration availability before relying on this operation. If it returns an unexpected 401, contact support with the endpoint and sanitized response.

Authentication: application-user token in Authorization: Bearer APPLICATION_TOKEN.

POST​

Required device_id UUID. Returns 204 on deletion.

Request fields (combine with the requirements and schema above):

LocationFieldFallback when absent
bodydevice_idnot supplied

Example request body:


{
"device_id": "11111111-1111-4111-8111-111111111111"
}

Success and error response examples

Illustrative values; conditional branches are alternatives. Fields vary with the operation and account configuration.

204 — json

No response body.

400 — json


{
"error": "device_id is required"
}

404 — json


{
"error": "Device not found"
}

/e/v1/auth/mfa/verify/​

Finish an application login using TOTP or a recovery code.

Availability note: standalone access with the credential described below has a known authentication limitation. Check integration availability before relying on this operation. If it returns an unexpected 401, contact support with the endpoint and sanitized response.

POST​

Required JSON mfa_ticket string from the primary login and code string. A recovery code can be supplied in the code field. Expired/invalid ticket or failed code rejects the request; restart login when needed.

Request fields (combine with the requirements and schema above):

LocationFieldFallback when absent
bodymfa_ticketnot supplied
bodycodenot supplied

Related schemas: User.

Example request body:


{
"mfa_ticket": "LOGIN_MFA_TICKET",
"code": "123456"
}

Success and error response examples

Illustrative values; conditional branches are alternatives. Fields vary with the operation and account configuration.

200 — json


{
"user": {
"id": "11111111-1111-4111-8111-111111111111",
"email": "[email protected]",
"first_name": "Example",
"last_name": "Example",
"company": "EXAMPLE_COMPANY",
"website": "https://app.example.test/callback",
"country": "EXAMPLE_COUNTRY",
"job_title": "EXAMPLE_JOB_TITLE",
"phone_number": "EXAMPLE_PHONE_NUMBER",
"email_verified": true,
"created_at": "2026-10-26T12:00:00Z",
"updated_at": "2026-10-26T12:00:00Z",
"last_login": "2026-10-26T12:00:00Z",
"created_via_api_key": "EXAMPLE_CREATED_VIA_API_KEY",
"developer_id": "EXAMPLE_DEVELOPER_ID",
"workspace": "11111111-1111-4111-8111-111111111111",
"oauth_client": "11111111-1111-4111-8111-111111111111"
},
"token": "EXAMPLE_TOKEN",
"refresh_token": "EXAMPLE_REFRESH_TOKEN",
"message": "Login successful"
}

400 — json


{
"error": "mfa_ticket and code are required"
}

400 — json


{
"error": "Invalid or expired MFA ticket"
}

401 — json


{
"error": "Invalid credentials"
}

401 — json


{
"error": "Invalid MFA code"
}

/e/v1/user/mfa/recovery/status/​

Read remaining recovery-code count.

Availability note: standalone access with the credential described below has a known authentication limitation. Check integration availability before relying on this operation. If it returns an unexpected 401, contact support with the endpoint and sanitized response.

Authentication: application-user token in Authorization: Bearer APPLICATION_TOKEN.

GET​

No body. Requires authenticated application user.

Success and error response examples

Illustrative values; conditional branches are alternatives. Fields vary with the operation and account configuration.

200 — json


{
"remaining": 1,
"total": 1
}

/e/v1/user/mfa/recovery/generate/​

Generate or rotate ten recovery codes.

Availability note: standalone access with the credential described below has a known authentication limitation. Check integration availability before relying on this operation. If it returns an unexpected 401, contact support with the endpoint and sanitized response.

Authentication: application-user token in Authorization: Bearer APPLICATION_TOKEN.

POST​

No body. Plaintext codes are returned once. Rotation invalidates prior codes; save the new set before dismissing it.

Success and error response examples

Illustrative values; conditional branches are alternatives. Fields vary with the operation and account configuration.

200 — json


{
"codes": [],
"total": 1,
"_warning": "Store these codes now. They will never be shown again. Any previously-issued codes are now invalid."
}

/e/v1/user/mfa/webauthn/register/begin/​

Create passkey registration options.

Availability note: standalone access with the credential described below has a known authentication limitation. Check integration availability before relying on this operation. If it returns an unexpected 401, contact support with the endpoint and sanitized response.

Authentication: application-user token in Authorization: Bearer APPLICATION_TOKEN.

POST​

Optional name string. Use the returned challenge/options with navigator.credentials.create; preserve application-user identity and RP origin.

Request fields (combine with the requirements and schema above):

LocationFieldFallback when absent
bodynamenot supplied

Example request body:


{
"name": "My passkey"
}

Success and error response examples

Illustrative values; conditional branches are alternatives. Fields vary with the operation and account configuration.

200 — json

JSON response varies with the request. See the operation requirements and linked schema; validation errors may be keyed by field name.

400 — json


{
"error": "EXAMPLE_ERROR"
}

/e/v1/user/mfa/webauthn/register/finish/​

Verify passkey attestation and save the device.

Availability note: standalone access with the credential described below has a known authentication limitation. Check integration availability before relying on this operation. If it returns an unexpected 401, contact support with the endpoint and sanitized response.

Authentication: application-user token in Authorization: Bearer APPLICATION_TOKEN.

POST​

Required credential object containing the browser registration response (id/rawId/type/response and Base64URL-encoded binary fields). Do not synthesize the signed response; submit the real navigator.credentials.create result after conversion.

Request fields (combine with the requirements and schema above):

LocationFieldFallback when absent
bodycredentialnot supplied

Example request body:


{
"credential": {
"id": "CREDENTIAL_ID",
"rawId": "BASE64URL_ID",
"type": "public-key",
"response": {
"clientDataJSON": "BASE64URL_CLIENT_DATA",
"attestationObject": "BASE64URL_ATTESTATION"
}
}
}

Success and error response examples

Illustrative values; conditional branches are alternatives. Fields vary with the operation and account configuration.

200 — json


{
"device_id": "EXAMPLE_DEVICE_ID",
"name": "Example",
"confirmed": true
}

400 — json


{
"error": "credential object is required"
}

400 — json


{
"error": "EXAMPLE_ERROR"
}

/e/v1/auth/webauthn/authenticate/begin/​

Begin a passkey assertion for an MFA-gated login.

Availability note: standalone access with the credential described below has a known authentication limitation. Check integration availability before relying on this operation. If it returns an unexpected 401, contact support with the endpoint and sanitized response.

POST​

Required mfa_ticket string. Returns options for navigator.credentials.get. Keep the same ticket for finish.

Request fields (combine with the requirements and schema above):

LocationFieldFallback when absent
bodymfa_ticketnot supplied

Example request body:


{
"mfa_ticket": "LOGIN_MFA_TICKET"
}

Success and error response examples

Illustrative values; conditional branches are alternatives. Fields vary with the operation and account configuration.

200 — json

JSON response varies with the request. See the operation requirements and linked schema; validation errors may be keyed by field name.

400 — json


{
"error": "mfa_ticket is required"
}

400 — json


{
"error": "Invalid or expired MFA ticket"
}

400 — json


{
"error": "EXAMPLE_ERROR"
}

401 — json


{
"error": "Invalid credentials"
}

/e/v1/auth/webauthn/authenticate/finish/​

Verify a passkey assertion and issue application tokens.

Availability note: standalone access with the credential described below has a known authentication limitation. Check integration availability before relying on this operation. If it returns an unexpected 401, contact support with the endpoint and sanitized response.

POST​

Required mfa_ticket and credential object from navigator.credentials.get, with id/rawId/type and response fields clientDataJSON, authenticatorData, signature and optional userHandle encoded as Base64URL.

Request fields (combine with the requirements and schema above):

LocationFieldFallback when absent
bodycredentialnot supplied
bodymfa_ticketnot supplied

Related schemas: User.

Example request body:


{
"mfa_ticket": "LOGIN_MFA_TICKET",
"credential": {
"id": "CREDENTIAL_ID",
"rawId": "BASE64URL_ID",
"type": "public-key",
"response": {
"clientDataJSON": "BASE64URL_CLIENT_DATA",
"authenticatorData": "BASE64URL_AUTH_DATA",
"signature": "BASE64URL_SIGNATURE",
"userHandle": null
}
}
}

Success and error response examples

Illustrative values; conditional branches are alternatives. Fields vary with the operation and account configuration.

200 — json


{
"user": {
"id": "11111111-1111-4111-8111-111111111111",
"email": "[email protected]",
"first_name": "Example",
"last_name": "Example",
"company": "EXAMPLE_COMPANY",
"website": "https://app.example.test/callback",
"country": "EXAMPLE_COUNTRY",
"job_title": "EXAMPLE_JOB_TITLE",
"phone_number": "EXAMPLE_PHONE_NUMBER",
"email_verified": true,
"created_at": "2026-10-26T12:00:00Z",
"updated_at": "2026-10-26T12:00:00Z",
"last_login": "2026-10-26T12:00:00Z",
"created_via_api_key": "EXAMPLE_CREATED_VIA_API_KEY",
"developer_id": "EXAMPLE_DEVELOPER_ID",
"workspace": "11111111-1111-4111-8111-111111111111",
"oauth_client": "11111111-1111-4111-8111-111111111111"
},
"token": "EXAMPLE_TOKEN",
"refresh_token": "EXAMPLE_REFRESH_TOKEN",
"message": "Login successful"
}

400 — json


{
"error": "mfa_ticket and credential are required"
}

400 — json


{
"error": "Invalid or expired MFA ticket"
}

401 — json


{
"error": "Invalid credentials"
}

401 — json


{
"error": "EXAMPLE_ERROR"
}