SutraID|Developer Docs
QuickstartAPI ReferenceDashboard

Authentication & MFA

Magic links, password auth, TOTP, passkeys, and adaptive MFA.

POST/api/v1/auth/verifyVerify Magic Link Token

Exchanges a magic link token (extracted from the emailed URL) for a full session. Returns access and refresh tokens along with user and organization context. If MFA is required, returns mfaRequired: true and an mfaToken to complete the MFA challenge instead.

Request Body

NameTypeRequiredDescription
tokenstringRequiredThe one-time token from the magic link URL.e.g. ml_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4

Response Fields

NameTypeRequiredDescription
accessTokenstringOptionalJWT access token.e.g. eyJhbGciOiJSUzI1NiJ9...
refreshTokenstringOptionalOpaque refresh token.e.g. rt_a1b2c3d4e5f6...
expiresInnumberOptionalAccess token TTL in seconds.e.g. 900
tokenTypestringOptionalAlways "Bearer".e.g. Bearer
user.idstringOptionalUser UUID.
user.emailstringOptionalUser email address.
user.firstNamestringOptionalUser first name.
user.lastNamestringOptionalUser last name.
user.organizationIdstringOptionalCurrent organization UUID.
user.rolestringOptionalUser role within the organization.
organization.idstringOptionalOrganization UUID.
organization.namestringOptionalOrganization display name.
organization.slugstringOptionalURL-safe organization slug.
organization.rolestringOptionalUser role in the organization.
mfaRequiredbooleanOptionalPresent and true when MFA must be completed.
mfaTokenstringOptionalShort-lived token to pass to the MFA challenge endpoint.

Response Example

{
  "accessToken": "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c3JfMTIzIn0.sig",
  "refreshToken": "rt_a1b2c3d4e5f6a1b2c3d4e5f6",
  "expiresIn": 900,
  "tokenType": "Bearer",
  "user": {
    "id": "usr_01hy5j8x2k3n4m5p6q7r8s9t",
    "email": "alice@example.com",
    "firstName": "Alice",
    "lastName": "Smith",
    "organizationId": "org_01hz1a2b3c4d5e6f7g8h9i0j",
    "role": "ADMIN"
  },
  "organization": {
    "id": "org_01hz1a2b3c4d5e6f7g8h9i0j",
    "name": "Acme Corp",
    "slug": "acme-corp",
    "role": "ADMIN"
  }
}

Code Examples

curl -X POST https://api.sutraid.com/api/v1/auth/verify \
  -H "Content-Type: application/json" \
  -d '{"token": "ml_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4"}'
POST/api/v1/auth/registerRegister with Email & Password

Creates a new user account with an email and password. Returns a full session immediately upon successful registration. Password must be at least 8 characters.

Request Body

NameTypeRequiredDescription
emailstringRequiredEmail address for the new account.e.g. bob@example.com
passwordstringRequiredPassword for the new account. Minimum 8 characters.e.g. Sup3rS3cur3!

Response Fields

NameTypeRequiredDescription
accessTokenstringOptionalJWT access token.
refreshTokenstringOptionalOpaque refresh token.
expiresInnumberOptionalAccess token TTL in seconds.
tokenTypestringOptionalAlways "Bearer".
userobjectOptionalNewly created user object.
organizationobjectOptionalDefault organization assigned to the user.

Response Example

{
  "accessToken": "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c3JfbmV3In0.sig",
  "refreshToken": "rt_newuser1234567890abcdef",
  "expiresIn": 900,
  "tokenType": "Bearer",
  "user": {
    "id": "usr_02ab3cd4ef5g6h7i8j9k0l1m",
    "email": "bob@example.com",
    "firstName": null,
    "lastName": null,
    "organizationId": "org_02ab3cd4ef5g6h7i8j9k0l1m",
    "role": "OWNER"
  },
  "organization": {
    "id": "org_02ab3cd4ef5g6h7i8j9k0l1m",
    "name": "Bob's Organization",
    "slug": "bobs-organization",
    "role": "OWNER"
  }
}

Code Examples

curl -X POST https://api.sutraid.com/api/v1/auth/register \
  -H "Content-Type: application/json" \
  -d '{
    "email": "bob@example.com",
    "password": "Sup3rS3cur3!"
  }'
POST/api/v1/auth/loginLogin with Password

Authenticates a user with their email and password. Optionally accepts an organizationId to log into a specific organization context. If the account has MFA enabled, the response will include mfaRequired: true and an mfaToken — use the MFA Verify Challenge endpoint to complete the login.

Request Body

NameTypeRequiredDescription
emailstringRequiredThe user email address.e.g. alice@example.com
passwordstringRequiredThe user password.e.g. Sup3rS3cur3!
organizationIdstringOptionalOptional organization UUID to log into a specific organization context.e.g. org_01hz1a2b3c4d5e6f7g8h9i0j

Response Fields

NameTypeRequiredDescription
accessTokenstringOptionalJWT access token (absent when MFA is required).
refreshTokenstringOptionalOpaque refresh token (absent when MFA is required).
expiresInnumberOptionalAccess token TTL in seconds.
tokenTypestringOptionalAlways "Bearer".
userobjectOptionalAuthenticated user.
organizationobjectOptionalActive organization context.
mfaRequiredbooleanOptionalTrue when an MFA challenge must be completed.
mfaTokenstringOptionalShort-lived token for the MFA challenge flow.

Response Example

{
  "accessToken": "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c3JfMTIzIn0.sig",
  "refreshToken": "rt_a1b2c3d4e5f6a1b2c3d4e5f6",
  "expiresIn": 900,
  "tokenType": "Bearer",
  "user": {
    "id": "usr_01hy5j8x2k3n4m5p6q7r8s9t",
    "email": "alice@example.com",
    "firstName": "Alice",
    "lastName": "Smith",
    "organizationId": "org_01hz1a2b3c4d5e6f7g8h9i0j",
    "role": "ADMIN"
  },
  "organization": {
    "id": "org_01hz1a2b3c4d5e6f7g8h9i0j",
    "name": "Acme Corp",
    "slug": "acme-corp",
    "role": "ADMIN"
  }
}

Code Examples

curl -X POST https://api.sutraid.com/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "alice@example.com",
    "password": "Sup3rS3cur3!",
    "organizationId": "org_01hz1a2b3c4d5e6f7g8h9i0j"
  }'
POST/api/v1/auth/forgot-passwordRequest Password Reset

Sends a password reset email to the provided address. Returns a generic message regardless of whether the email is registered, preventing user enumeration.

Request Body

NameTypeRequiredDescription
emailstringRequiredEmail address associated with the account to reset.e.g. alice@example.com

Response Fields

NameTypeRequiredDescription
messagestringOptionalGeneric confirmation message.e.g. If an account exists, a reset link has been sent

Response Example

{
  "message": "If an account exists, a reset link has been sent"
}

Code Examples

curl -X POST https://api.sutraid.com/api/v1/auth/forgot-password \
  -H "Content-Type: application/json" \
  -d '{"email": "alice@example.com"}'
POST/api/v1/auth/reset-passwordReset Password

Resets a user password using the token received in the reset email. The new password must be at least 8 characters. The reset token is single-use and expires after a short period.

Request Body

NameTypeRequiredDescription
tokenstringRequiredPassword reset token from the emailed link.e.g. pr_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4
newPasswordstringRequiredThe new password. Minimum 8 characters.e.g. N3wP@ssw0rd!

Response Fields

NameTypeRequiredDescription
messagestringOptionalConfirmation message.e.g. Password reset successfully

Response Example

{
  "message": "Password reset successfully"
}

Code Examples

curl -X POST https://api.sutraid.com/api/v1/auth/reset-password \
  -H "Content-Type: application/json" \
  -d '{
    "token": "pr_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
    "newPassword": "N3wP@ssw0rd!"
  }'
POST/api/v1/auth/change-passwordChange PasswordBearer Token

Changes the password for the currently authenticated user. Requires the current password for verification. The new password must be at least 8 characters.

Request Body

NameTypeRequiredDescription
currentPasswordstringRequiredThe user current password.e.g. Sup3rS3cur3!
newPasswordstringRequiredThe new password. Minimum 8 characters.e.g. N3wP@ssw0rd!

Response Fields

NameTypeRequiredDescription
messagestringOptionalConfirmation message.e.g. Password changed successfully

Response Example

{
  "message": "Password changed successfully"
}

Code Examples

curl -X POST https://api.sutraid.com/api/v1/auth/change-password \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{
    "currentPassword": "Sup3rS3cur3!",
    "newPassword": "N3wP@ssw0rd!"
  }'
GET/api/v1/auth/meGet Current UserBearer Token

Returns the profile of the currently authenticated user. Useful for hydrating application state after a page load or token refresh.

Response Fields

NameTypeRequiredDescription
user.idstringOptionalUser UUID.
user.emailstringOptionalUser email address.
user.firstNamestringOptionalUser first name.
user.lastNamestringOptionalUser last name.
user.organizationIdstringOptionalCurrent organization UUID.
user.rolestringOptionalUser role within the organization.

Response Example

{
  "user": {
    "id": "usr_01hy5j8x2k3n4m5p6q7r8s9t",
    "email": "alice@example.com",
    "firstName": "Alice",
    "lastName": "Smith",
    "organizationId": "org_01hz1a2b3c4d5e6f7g8h9i0j",
    "role": "ADMIN"
  }
}

Code Examples

curl -X GET https://api.sutraid.com/api/v1/auth/me \
  -H "Authorization: Bearer <token>"
POST/api/v1/auth/logoutLogoutBearer Token

Revokes the current session for the authenticated user. The access token is invalidated server-side. Clients should discard stored tokens after calling this endpoint.

Response Fields

NameTypeRequiredDescription
messagestringOptionalConfirmation message.e.g. Logged out successfully

Response Example

{
  "message": "Logged out successfully"
}

Code Examples

curl -X POST https://api.sutraid.com/api/v1/auth/logout \
  -H "Authorization: Bearer <token>"
GET/api/v1/auth/mfa/statusGet MFA StatusBearer Token

Returns the current MFA enrollment status for the authenticated user, including all enrolled methods with their type, verification status, and last usage timestamp.

Response Fields

NameTypeRequiredDescription
enabledbooleanOptionalWhether MFA is currently active for this user.
methodsarrayOptionalList of enrolled MFA methods.
methods[].idstringOptionalMethod UUID.
methods[].typestringOptionalMethod type: TOTP, PASSKEY, or BACKUP_CODE.
methods[].namestringOptionalHuman-readable method name.
methods[].verifiedbooleanOptionalWhether the method has been verified.
methods[].enabledbooleanOptionalWhether the method is currently active.
methods[].lastUsedAtstring | nullOptionalISO 8601 timestamp of last use.

Response Example

{
  "enabled": true,
  "methods": [
    {
      "id": "mfa_01hz1a2b3c4d5e6f7g8h",
      "type": "TOTP",
      "name": "Authenticator App",
      "verified": true,
      "enabled": true,
      "lastUsedAt": "2025-01-15T10:30:00.000Z"
    },
    {
      "id": "mfa_02ab3cd4ef5g6h7i8j9k",
      "type": "BACKUP_CODE",
      "name": "Backup Codes",
      "verified": true,
      "enabled": true,
      "lastUsedAt": null
    }
  ]
}

Code Examples

curl -X GET https://api.sutraid.com/api/v1/auth/mfa/status \
  -H "Authorization: Bearer <token>"
POST/api/v1/auth/mfa/enroll/totpEnroll TOTP AuthenticatorBearer Token

Initiates TOTP enrollment for the authenticated user. Returns a methodId, the otpauth:// URI, a base64-encoded QR code image, and a set of one-time backup codes. Present the QR code to the user for scanning with an authenticator app, then call the Verify TOTP Enrollment endpoint to confirm.

Response Fields

NameTypeRequiredDescription
methodIdstringOptionalMFA method UUID to use when verifying enrollment.
otpAuthUrlstringOptionalotpauth:// URI for manual entry into authenticator apps.
qrCodestringOptionalBase64-encoded PNG QR code image of the otpauth URL.
backupCodesstring[]OptionalOne-time backup codes. Store securely.

Response Example

{
  "methodId": "mfa_01hz1a2b3c4d5e6f7g8h",
  "otpAuthUrl": "otpauth://totp/SutraID%3Aalice%40example.com?secret=BASE32SECRET&issuer=SutraID",
  "qrCode": "data:image/png;base64,iVBORw0KGgo...",
  "backupCodes": [
    "AAAA-BBBB-CCCC",
    "DDDD-EEEE-FFFF",
    "GGGG-HHHH-IIII",
    "JJJJ-KKKK-LLLL",
    "MMMM-NNNN-OOOO",
    "PPPP-QQQQ-RRRR",
    "SSSS-TTTT-UUUU",
    "VVVV-WWWW-XXXX"
  ]
}

Code Examples

curl -X POST https://api.sutraid.com/api/v1/auth/mfa/enroll/totp \
  -H "Authorization: Bearer <token>"
POST/api/v1/auth/mfa/enroll/verifyVerify TOTP EnrollmentBearer Token

Completes TOTP enrollment by submitting the 6-digit code from the authenticator app. Must be called after initiating enrollment with the Enroll TOTP endpoint. On success, TOTP becomes the active MFA method for the account.

Request Body

NameTypeRequiredDescription
methodIdstringRequiredThe methodId returned from the enroll TOTP endpoint.e.g. mfa_01hz1a2b3c4d5e6f7g8h
codestringRequiredThe 6-digit TOTP code from the authenticator app.e.g. 482910

Response Fields

NameTypeRequiredDescription
successbooleanOptionalWhether enrollment verification succeeded.
backupCodesstring[]OptionalBackup codes (returned on first successful verify).

Response Example

{
  "success": true,
  "backupCodes": [
    "AAAA-BBBB-CCCC",
    "DDDD-EEEE-FFFF",
    "GGGG-HHHH-IIII",
    "JJJJ-KKKK-LLLL"
  ]
}

Code Examples

curl -X POST https://api.sutraid.com/api/v1/auth/mfa/enroll/verify \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{
    "methodId": "mfa_01hz1a2b3c4d5e6f7g8h",
    "code": "482910"
  }'
POST/api/v1/auth/mfa/verify-challengeVerify MFA Challenge

Completes the MFA challenge step during a login flow. Submit the mfaToken received from a login response (when mfaRequired is true) along with either a TOTP code or a backup code. On success, returns a full session with access and refresh tokens.

Request Body

NameTypeRequiredDescription
mfaTokenstringRequiredThe mfaToken returned from the login endpoint when mfaRequired is true.e.g. mfat_a1b2c3d4e5f6a1b2c3d4e5f6
codestringRequiredTOTP code (6 digits) or backup code (6-8 chars).e.g. 482910
isBackupCodebooleanOptionalSet to true when submitting a backup code instead of a TOTP code.e.g. false

Response Fields

NameTypeRequiredDescription
accessTokenstringOptionalJWT access token.
refreshTokenstringOptionalOpaque refresh token.
expiresInnumberOptionalAccess token TTL in seconds.
tokenTypestringOptionalAlways "Bearer".
userobjectOptionalAuthenticated user.
organizationobjectOptionalActive organization context.

Response Example

{
  "accessToken": "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c3JfMTIzIn0.sig",
  "refreshToken": "rt_a1b2c3d4e5f6a1b2c3d4e5f6",
  "expiresIn": 900,
  "tokenType": "Bearer",
  "user": {
    "id": "usr_01hy5j8x2k3n4m5p6q7r8s9t",
    "email": "alice@example.com",
    "firstName": "Alice",
    "lastName": "Smith",
    "organizationId": "org_01hz1a2b3c4d5e6f7g8h9i0j",
    "role": "ADMIN"
  },
  "organization": {
    "id": "org_01hz1a2b3c4d5e6f7g8h9i0j",
    "name": "Acme Corp",
    "slug": "acme-corp",
    "role": "ADMIN"
  }
}

Code Examples

curl -X POST https://api.sutraid.com/api/v1/auth/mfa/verify-challenge \
  -H "Content-Type: application/json" \
  -d '{
    "mfaToken": "mfat_a1b2c3d4e5f6a1b2c3d4e5f6",
    "code": "482910",
    "isBackupCode": false
  }'
POST/api/v1/auth/mfa/backup-codes/regenerateRegenerate Backup CodesBearer Token

Generates a new set of backup codes for the authenticated user, invalidating all previously issued backup codes. Store the returned codes securely — they cannot be retrieved again.

Response Fields

NameTypeRequiredDescription
backupCodesstring[]OptionalNew set of single-use backup codes.e.g. ["AAAA-BBBB-CCCC", "DDDD-EEEE-FFFF"]

Response Example

{
  "backupCodes": [
    "AAAA-BBBB-CCCC",
    "DDDD-EEEE-FFFF",
    "GGGG-HHHH-IIII",
    "JJJJ-KKKK-LLLL",
    "MMMM-NNNN-OOOO",
    "PPPP-QQQQ-RRRR",
    "SSSS-TTTT-UUUU",
    "VVVV-WWWW-XXXX"
  ]
}

Code Examples

curl -X POST https://api.sutraid.com/api/v1/auth/mfa/backup-codes/regenerate \
  -H "Authorization: Bearer <token>"
POST/api/v1/auth/mfa/disableDisable MFABearer Token

Disables MFA for the authenticated user. Requires the current account password as confirmation. All enrolled MFA methods will be removed.

Request Body

NameTypeRequiredDescription
passwordstringRequiredCurrent account password for confirmation.e.g. Sup3rS3cur3!

Response Fields

NameTypeRequiredDescription
successbooleanOptionalWhether MFA was successfully disabled.e.g. true

Response Example

{
  "success": true
}

Code Examples

curl -X POST https://api.sutraid.com/api/v1/auth/mfa/disable \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{"password": "Sup3rS3cur3!"}'
GET/api/v1/auth/mfa/passkey/optionsGet WebAuthn Registration OptionsBearer Token

Returns the WebAuthn credential creation options (PublicKeyCredentialCreationOptions) needed to register a passkey. Pass the returned options to navigator.credentials.create() in the browser, then submit the attestation response to the Enroll Passkey endpoint.

Response Fields

NameTypeRequiredDescription
challengestringOptionalBase64url-encoded random challenge.
rpobjectOptionalRelying party info (id, name).
userobjectOptionalUser handle info (id, name, displayName).
pubKeyCredParamsarrayOptionalAccepted credential algorithms.
timeoutnumberOptionalCeremony timeout in milliseconds.
attestationstringOptionalAttestation preference.
authenticatorSelectionobjectOptionalAuthenticator selection criteria.

Response Example

{
  "challenge": "dGhpcyBpcyBhIGNoYWxsZW5nZQ==",
  "rp": {
    "id": "sutraid.com",
    "name": "SutraID"
  },
  "user": {
    "id": "dXNyXzAxaHk1ajh4MmszbjRtNXA2cTdyOHM5dA==",
    "name": "alice@example.com",
    "displayName": "Alice Smith"
  },
  "pubKeyCredParams": [
    {
      "type": "public-key",
      "alg": -7
    },
    {
      "type": "public-key",
      "alg": -257
    }
  ],
  "timeout": 60000,
  "attestation": "none",
  "authenticatorSelection": {
    "authenticatorAttachment": "platform",
    "requireResidentKey": false,
    "userVerification": "preferred"
  }
}

Code Examples

curl -X GET https://api.sutraid.com/api/v1/auth/mfa/passkey/options \
  -H "Authorization: Bearer <token>"
POST/api/v1/auth/mfa/passkey/enrollEnroll PasskeyBearer Token

Completes passkey enrollment by submitting the WebAuthn attestation response from navigator.credentials.create(). The credential object must be the serialized PublicKeyCredential returned by the browser API.

Request Body

NameTypeRequiredDescription
credentialobjectRequiredThe WebAuthn PublicKeyCredential attestation response from the browser.e.g. { id, rawId, response: { attestationObject, clientDataJSON }, type }

Response Fields

NameTypeRequiredDescription
successbooleanOptionalWhether passkey enrollment succeeded.
methodIdstringOptionalThe MFA method UUID for the new passkey.

Response Example

{
  "success": true,
  "methodId": "mfa_03cd4ef5g6h7i8j9k0l1m2n"
}

Code Examples

curl -X POST https://api.sutraid.com/api/v1/auth/mfa/passkey/enroll \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{
    "credential": {
      "id": "credentialIdBase64url",
      "rawId": "credentialIdBase64url",
      "response": {
        "attestationObject": "attestationBase64url",
        "clientDataJSON": "clientDataBase64url"
      },
      "type": "public-key"
    }
  }'
POST/api/v1/auth/mfa/adaptive/toggleToggle Adaptive MFABearer Token

Enables or disables adaptive MFA for the authenticated user. When enabled, the system uses contextual signals (IP address, device fingerprint, geolocation) to determine whether an MFA challenge is required on each login, rather than always requiring it.

Request Body

NameTypeRequiredDescription
enabledbooleanRequiredSet to true to enable adaptive MFA, false to disable it.e.g. true

Response Fields

NameTypeRequiredDescription
enabledbooleanOptionalThe new adaptive MFA state.e.g. true

Response Example

{
  "enabled": true
}

Code Examples

curl -X POST https://api.sutraid.com/api/v1/auth/mfa/adaptive/toggle \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{"enabled": true}'