Skip to main content

TOTP Authentication

Time-based One-Time Password (TOTP) authentication using authenticator apps like Google Authenticator, Authy, or Microsoft Authenticator.

Begin TOTP Setup

Start TOTP authenticator app setup process.

Endpoint: POST /webauthn/totp/beginSetup

Request Body

{
"client_id": "string",
"email": "string",
"tenant_id": "string"
}

Parameters

ParameterTypeRequiredDescription
client_idstringNoClient identifier
emailstringYesUser email address
tenant_idstringYesTenant identifier

Response

Success (200):

{
"account": "string",
"issuer": "string",
"manual_entry": "string",
"otp_auth_url": "string",
"qr_code": "string",
"secret": "string"
}

Response Fields

FieldTypeDescription
accountstringAccount name for authenticator app
issuerstringIssuer name (e.g., "AuthSec")
manual_entrystringSecret for manual entry
otp_auth_urlstringotpauth:// URL for app linking
qr_codestringBase64-encoded QR code image
secretstringTOTP secret key

Error Responses:

  • 400 - Bad Request
  • 404 - Not Found
  • 500 - Internal Server Error

Confirm TOTP Setup

Confirm TOTP setup with verification code from authenticator app.

Endpoint: POST /webauthn/totp/confirmSetup

Request Body

{
"client_id": "string",
"code": "string",
"email": "string",
"secret": "string",
"tenant_id": "string"
}

Parameters

ParameterTypeRequiredDescription
client_idstringNoClient identifier
codestringYes6-digit TOTP code from app
emailstringYesUser email address
secretstringYesTOTP secret from beginSetup
tenant_idstringYesTenant identifier

Response

Success (200):

{
"backup_codes": [
"string"
],
"message": "string",
"success": true
}

Response Fields

FieldTypeDescription
backup_codesarray[string]Recovery codes (store securely!)
messagestringSuccess message
successbooleanSetup success status

Error Responses:

  • 400 - Bad Request (invalid code)
  • 404 - Not Found
  • 500 - Internal Server Error

Verify TOTP Code

Verify TOTP code for authentication.

Endpoint: POST /webauthn/totp/verify

Request Body

{
"backup_code": "string",
"client_id": "string",
"code": "string",
"email": "string",
"tenant_id": "string"
}

Parameters

ParameterTypeRequiredDescription
backup_codestringNo*Backup recovery code
client_idstringNoClient identifier
codestringNo*6-digit TOTP code
emailstringYesUser email address
tenant_idstringYesTenant identifier

*Either code or backup_code must be provided.

Response

Success (200):

{
"email": "string",
"message": "string",
"method": "string",
"success": true,
"tenant_id": "string"
}

Error Responses:

  • 400 - Bad Request (invalid code)
  • 404 - Not Found
  • 500 - Internal Server Error

Verify TOTP for Login

Verify TOTP code during login process.

Endpoint: POST /webauthn/totp/verifyLogin

Request Body

{
"backup_code": "string",
"code": "string",
"email": "string",
"tenant_id": "string"
}

Parameters

ParameterTypeRequiredDescription
backup_codestringNo*Backup recovery code
codestringNo*6-digit TOTP code
emailstringYesUser email address
tenant_idstringYesTenant identifier

*Either code or backup_code must be provided.

Response

Success (200):

{
"email": "string",
"message": "string",
"method": "string",
"success": true,
"tenant_id": "string"
}

Error Responses:

  • 400 - Bad Request
  • 404 - Not Found
  • 500 - Internal Server Error

TOTP Implementation Guide

Setup Flow

// 1. Begin TOTP Setup
const setupResponse = await fetch('/webauthn/totp/beginSetup', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email: '[email protected]',
tenant_id: 'tenant123'
})
});
const { qr_code, secret } = await setupResponse.json();

// 2. Display QR code to user
// User scans with authenticator app

// 3. User enters code from app
const code = getUserInput(); // 6-digit code

// 4. Confirm setup
const confirmResponse = await fetch('/webauthn/totp/confirmSetup', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email: '[email protected]',
tenant_id: 'tenant123',
secret: secret,
code: code
})
});
const { backup_codes } = await confirmResponse.json();

// 5. Display backup codes to user (IMPORTANT!)
displayBackupCodes(backup_codes);

Verification Flow

// Verify TOTP during login
const code = getUserInput(); // 6-digit code

const verifyResponse = await fetch('/webauthn/totp/verifyLogin', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email: '[email protected]',
tenant_id: 'tenant123',
code: code
})
});

const { success } = await verifyResponse.json();
if (success) {
// Proceed with login
}

Using Backup Codes

// If user lost access to authenticator app
const backupCode = getUserInput(); // One of the backup codes

const verifyResponse = await fetch('/webauthn/totp/verify', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email: '[email protected]',
tenant_id: 'tenant123',
backup_code: backupCode
})
});

Best Practices

Setup

  • QR Code Display: Always show QR code prominently for easy scanning
  • Manual Entry: Provide manual entry option for users who can't scan
  • Backup Codes: Force users to save backup codes before completing setup
  • Testing: Require one successful verification before confirming setup

Verification

  • Code Expiration: TOTP codes expire every 30 seconds
  • Time Sync: Ensure server time is properly synchronized
  • Rate Limiting: Implement rate limiting to prevent brute force
  • Backup Code Security: Treat backup codes as passwords (one-time use recommended)

User Experience

  • Clear Instructions: Provide step-by-step setup instructions
  • App Recommendations: Suggest popular authenticator apps
  • Troubleshooting: Offer help for common issues (time sync, wrong code)
  • Recovery Process: Clear process for using backup codes

Security

  • Secret Storage: Store TOTP secrets encrypted
  • Backup Code Hashing: Hash backup codes before storage
  • Code Reuse Prevention: Prevent same code from being used twice
  • Attempt Limiting: Lock account after multiple failed attempts