Skip to main content

Verify MFA (Login)

Completes the login process for users with MFA enabled. When POST /auth/login returns mfaRequired: true, this endpoint must be called with the MFA challenge token and a verification code (either a 6-digit TOTP code from the authenticator app or an 8-character recovery code).

Request

POST /auth/verify-mfa

Authentication

This is a public endpoint. No authentication header is required, but you must provide the mfaChallengeToken received from the login response.

Request Body

{
"mfaChallengeToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"code": "123456"
}

Request Fields

FieldTypeRequiredDescription
mfaChallengeTokenstringYesTemporary token returned in the login response when mfaRequired: true. Valid for a short time window (typically 5 minutes).
codestringYesEither a 6-digit TOTP code from the authenticator app OR an 8-character recovery code. Must be 6-12 characters.

Response

Returns an AuthResponse object with access and refresh tokens.

{
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"tokenType": "Bearer",
"expiresIn": 3600
}

Response Fields

FieldTypeDescription
accessTokenstringJWT access token for API authentication. Include in Authorization: Bearer <token> header.
refreshTokenstringJWT refresh token for obtaining new access tokens when they expire.
tokenTypestringAlways "Bearer" for JWT tokens.
expiresInintegerAccess token lifetime in seconds (typically 3600 = 1 hour).

Error Responses

Status CodeErrorDescription
400Bad RequestInvalid or missing code, or invalid challenge token format
401UnauthorizedIncorrect TOTP code, expired/invalid challenge token, or recovery code already used
429Too Many RequestsRate limit exceeded for MFA verification attempts

Example

Request with TOTP Code

curl -X POST https://api.entryguard.io/api/v1/auth/verify-mfa \
-H "Content-Type: application/json" \
-d '{
"mfaChallengeToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
"code": "123456"
}'

Request with Recovery Code

curl -X POST https://api.entryguard.io/api/v1/auth/verify-mfa \
-H "Content-Type: application/json" \
-d '{
"mfaChallengeToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
"code": "a1b2c3d4"
}'

Response

{
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIzZmE4NWY2NC01NzE3LTQzNjItYjk4Zi05ZGRkMzZlNGIwMTAiLCJvcmdJZCI6IjdlNDJhOGYzLWM5MTItNGFjZi04NzZkLWIzZDc4ZmE2YWIyMSIsInJvbGVzIjpbIlVTRVIiXSwiaWF0IjoxNjQwOTk1MjAwLCJleHAiOjE2NDA5OTg4MDB9.K7Zz8yXqY5sC3vF9wA2hN8jR4tQ6pL1mE0nO7bG5iD8",
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIzZmE4NWY2NC01NzE3LTQzNjItYjk4Zi05ZGRkMzZlNGIwMTAiLCJ0eXBlIjoicmVmcmVzaCIsImlhdCI6MTY0MDk5NTIwMCwiZXhwIjoxNjQzNTg3MjAwfQ.M5nP8qR2vX9wB3tL6sD4eA1jC7bF9kO0mH3yG8nI5rE",
"tokenType": "Bearer",
"expiresIn": 3600
}

Login Flow with MFA

  1. User submits email/password to POST /auth/login
  2. Server returns { "mfaRequired": true, "mfaChallengeToken": "..." }
  3. Client prompts user for MFA code
  4. User enters 6-digit TOTP code (or recovery code)
  5. Client calls POST /auth/verify-mfa with challenge token and code
  6. Server validates code and returns access + refresh tokens
  7. Client stores tokens and proceeds with authenticated session