MFA Endpoints

Base URL: https://auth.calimatic.com/api/v1/auth/headless

MFA endpoints use two different authentication schemes depending on the operation. The verify endpoint uses an mfaToken (received from a login challenge). All other MFA endpoints use a Bearer access token.


Authentication

EndpointAuth TypeHeader
POST /mfa/verifyApp Client + MFA Tokenx-client-id, x-client-secret, plus mfaToken in body
All other MFA endpointsBearer TokenAuthorization: Bearer <access_token>

Endpoints Overview

MethodEndpointDescription
POST/mfa/verifyComplete MFA challenge to receive tokens
GET/mfa/statusGet MFA enrollment status
POST/mfa/enrollInitiate TOTP enrollment
POST/mfa/enroll/confirmConfirm enrollment with TOTP code
POST/mfa/disableDisable TOTP for the user
GET/mfa/backup-codesGet remaining backup code count
POST/mfa/backup-codesRegenerate backup codes

POST /api/v1/auth/headless/mfa/verify

Complete an MFA challenge to receive full access tokens. Called after POST /login returns mfaRequired: true.

Authentication: App Client (x-client-id + x-client-secret) + mfaToken in request body

Request Body

FieldTypeRequiredDescription
mfaTokenstringYesShort-lived MFA challenge token from the login response
codestringYesTOTP code from authenticator app, or a backup code
methodstringYesVerification method: "totp" or "backup_code"

Response (200 OK)

{
  "accessToken": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refreshToken": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "idToken": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "expiresAt": "2025-01-15T11:00:00.000Z",
  "user": {
    "userId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "email": "user@example.com",
    "firstName": "Jane",
    "lastName": "Doe"
  }
}

Error Codes

CodeHTTP StatusDescription
MFA_INVALID_CODE401The TOTP code or backup code is incorrect
MFA_CHALLENGE_EXPIRED401The mfaToken has expired (default: 5 minutes)
RATE_LIMITED429Request rate limit exceeded
INVALID_CLIENT401App client credentials are missing or invalid

SDK Method

const tokens = await client.mfa.verify({
  mfaToken: challenge.mfaToken,
  code: '123456',
  method: 'totp',
});

curl Example

curl -X POST https://auth.calimatic.com/api/v1/auth/headless/mfa/verify \
  -H "Content-Type: application/json" \
  -H "x-client-id: cca_aBcDeFgHiJkL" \
  -H "x-client-secret: ccas_xYzAbCdEfGhI" \
  -d '{
    "mfaToken": "mfa_eyJhbGciOiJIUzI1NiJ9...",
    "code": "123456",
    "method": "totp"
  }'

GET /api/v1/auth/headless/mfa/status

Get MFA enrollment status for the authenticated user. Returns whether TOTP is enrolled, which methods are active, and how many backup codes remain.

Authentication: Bearer Token (Authorization: Bearer <access_token>)

Request Body

None. Pass the access token in the Authorization header.

Response (200 OK)

{
  "enrolled": true,
  "methods": ["totp"],
  "backupCodesRemaining": 8
}

Error Codes

CodeHTTP StatusDescription
INVALID_TOKEN401Access token is expired or invalid
INVALID_CLIENT401App client credentials are missing or invalid
RATE_LIMITED429Request rate limit exceeded

SDK Method

const status = await client.mfa.status(accessToken);
console.log(status.enrolled, status.backupCodesRemaining);

curl Example

curl -X GET https://auth.calimatic.com/api/v1/auth/headless/mfa/status \
  -H "x-client-id: cca_aBcDeFgHiJkL" \
  -H "x-client-secret: ccas_xYzAbCdEfGhI" \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."

POST /api/v1/auth/headless/mfa/enroll

Initiate TOTP enrollment for the authenticated user. Returns a TOTP secret and QR code URI to display to the user. The user must scan the QR code and call POST /mfa/enroll/confirm with a valid code to complete enrollment.

Authentication: Bearer Token (Authorization: Bearer <access_token>)

Request Body

None.

Response (200 OK)

{
  "secret": "JBSWY3DPEHPK3PXP",
  "qrUri": "otpauth://totp/Calimatic%20Auth:user%40example.com?secret=JBSWY3DPEHPK3PXP&issuer=Calimatic%20Auth",
  "issuer": "Calimatic Auth"
}

Error Codes

CodeHTTP StatusDescription
MFA_ALREADY_ENROLLED409User already has MFA enrolled
INVALID_TOKEN401Access token is expired or invalid
RATE_LIMITED429Request rate limit exceeded
INVALID_CLIENT401App client credentials are missing or invalid

SDK Method

const enrollment = await client.mfa.enroll(accessToken);
console.log(enrollment.qrUri); // Display QR code to user

curl Example

curl -X POST https://auth.calimatic.com/api/v1/auth/headless/mfa/enroll \
  -H "x-client-id: cca_aBcDeFgHiJkL" \
  -H "x-client-secret: ccas_xYzAbCdEfGhI" \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."

POST /api/v1/auth/headless/mfa/enroll/confirm

Confirm TOTP enrollment with a code generated by the authenticator app. Must be called after POST /mfa/enroll. On success, returns backup codes that the user should store securely.

Authentication: Bearer Token (Authorization: Bearer <access_token>)

Request Body

FieldTypeRequiredDescription
codestringYes6-digit numeric TOTP code from the authenticator app

Response (200 OK)

{
  "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"
  ]
}

Error Codes

CodeHTTP StatusDescription
MFA_INVALID_CODE401The TOTP code is incorrect
INVALID_TOKEN401Access token is expired or invalid
RATE_LIMITED429Request rate limit exceeded
INVALID_CLIENT401App client credentials are missing or invalid

SDK Method

const result = await client.mfa.confirmEnrollment(accessToken, { code: '123456' });
console.log(result.backupCodes); // Store these securely

curl Example

curl -X POST https://auth.calimatic.com/api/v1/auth/headless/mfa/enroll/confirm \
  -H "Content-Type: application/json" \
  -H "x-client-id: cca_aBcDeFgHiJkL" \
  -H "x-client-secret: ccas_xYzAbCdEfGhI" \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..." \
  -d '{
    "code": "123456"
  }'

POST /api/v1/auth/headless/mfa/disable

Disable TOTP for the authenticated user. Requires a valid TOTP code to confirm the action. After disabling, the user can log in without MFA until they re-enroll.

Authentication: Bearer Token (Authorization: Bearer <access_token>)

Request Body

FieldTypeRequiredDescription
codestringYes6-digit numeric TOTP code to confirm the disable action

Response (200 OK)

Returns an empty body on success.

{}

Error Codes

CodeHTTP StatusDescription
MFA_INVALID_CODE401The TOTP code is incorrect
MFA_NOT_ENROLLED400User does not have MFA enrolled
INVALID_TOKEN401Access token is expired or invalid
INVALID_CLIENT401App client credentials are missing or invalid

SDK Method

await client.mfa.disable(accessToken, { code: '123456' });

curl Example

curl -X POST https://auth.calimatic.com/api/v1/auth/headless/mfa/disable \
  -H "Content-Type: application/json" \
  -H "x-client-id: cca_aBcDeFgHiJkL" \
  -H "x-client-secret: ccas_xYzAbCdEfGhI" \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..." \
  -d '{
    "code": "123456"
  }'

GET /api/v1/auth/headless/mfa/backup-codes

Get remaining backup code count for the authenticated user. Returns total issued codes and how many remain unused.

Authentication: Bearer Token (Authorization: Bearer <access_token>)

Request Body

None.

Response (200 OK)

{
  "total": 10,
  "remaining": 8
}

Error Codes

CodeHTTP StatusDescription
MFA_NOT_ENROLLED400User does not have MFA enrolled
INVALID_TOKEN401Access token is expired or invalid
RATE_LIMITED429Request rate limit exceeded
INVALID_CLIENT401App client credentials are missing or invalid

SDK Method

const counts = await client.mfa.backupCodes.count(accessToken);
console.log(`${counts.remaining} of ${counts.total} backup codes remaining`);

curl Example

curl -X GET https://auth.calimatic.com/api/v1/auth/headless/mfa/backup-codes \
  -H "x-client-id: cca_aBcDeFgHiJkL" \
  -H "x-client-secret: ccas_xYzAbCdEfGhI" \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."

POST /api/v1/auth/headless/mfa/backup-codes

Regenerate backup codes for the authenticated user. Requires a valid TOTP code. All previous backup codes are invalidated and replaced with a new set.

Authentication: Bearer Token (Authorization: Bearer <access_token>)

Request Body

FieldTypeRequiredDescription
codestringYes6-digit numeric TOTP code to authorize regeneration

Response (200 OK)

{
  "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"
  ]
}

Error Codes

CodeHTTP StatusDescription
MFA_INVALID_CODE401The TOTP code is incorrect
MFA_NOT_ENROLLED400User does not have MFA enrolled
INVALID_TOKEN401Access token is expired or invalid
INVALID_CLIENT401App client credentials are missing or invalid

SDK Method

const result = await client.mfa.backupCodes.regenerate(accessToken, { code: '123456' });
console.log(result.backupCodes); // Store these securely

curl Example

curl -X POST https://auth.calimatic.com/api/v1/auth/headless/mfa/backup-codes \
  -H "Content-Type: application/json" \
  -H "x-client-id: cca_aBcDeFgHiJkL" \
  -H "x-client-secret: ccas_xYzAbCdEfGhI" \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..." \
  -d '{
    "code": "123456"
  }'