MFA API
Account API endpoints for TOTP enrolment and Customer API risk event queries
This page documents the MFA-related REST endpoints: TOTP enrolment and verification on the Account API, and risk assessment history on the Customer API.
Authentication
| API | Token | Base URL |
|---|---|---|
| Account API | User access token (Authorization: Bearer eyJ...) | https://TENANT.api.wocha.ai/v1/account |
| Customer API | Management API key (wocha_mgmt_...) or OAuth token with risk:read | https://TENANT.api.wocha.ai/v1/customer |
TOTP enrolment flow
TOTP enrolment is a two-step process: initiate (POST), then verify and activate (PUT).
Step 1 — Initiate enrolment
Response 201 Created:
| Field | Description |
|---|---|
secret | Base32 TOTP secret — display once for manual entry |
qr_uri | otpauth:// URI — render as a QR code in your UI |
backup_codes | One-time recovery codes — display once; stored hashed server-side on activation |
The pending enrolment expires after 10 minutes. A new POST replaces any existing pending enrolment.
Errors:
| Status | Code | When |
|---|---|---|
409 | conflict | TOTP is already enrolled |
404 | not_found | User identity not found |
503 | service_unavailable | Identity service not configured |
Step 2 — Verify and activate
Submit a 6-digit code from the user's authenticator app to activate the credential:
Response 200 OK:
On success, the pending enrolment is cleared from identity metadata and the TOTP credential is activated in Kratos. Backup codes are stored as lookup secrets if none exist.
Errors:
| Status | Code | When |
|---|---|---|
422 | validation_error | Invalid or expired TOTP code, or code format invalid (must be 6 digits) |
404 | not_found | No pending TOTP enrolment — call POST first |
409 | conflict | TOTP is already enrolled |
400 | validation_error | Request body is not valid JSON |
Remove TOTP
Returns 204 No Content on success. Also removes associated backup codes.
React SDK
The useMfa() hook wraps the Account API:
Risk events API
Query risk assessment audit events for your tenant. Requires the risk:read scope.
Query parameters
| Parameter | Type | Description |
|---|---|---|
limit | integer | Results per page (1–100, default 50) |
page_token | string | Cursor for pagination (event id from previous page) |
verdict | string | Filter by allow, step_up, or block |
subject_id | string | Filter by user identity ID |
range_start | ISO 8601 | Events on or after this timestamp |
range_end | ISO 8601 | Events on or before this timestamp |
Response
Assessor details
Each entry in assessments is keyed by assessor ID (bot_detected, velocity_anomaly, unknown_device, etc.) and includes:
| Field | Description |
|---|---|
confidence | Ordinal level: low, medium, high, or neutral |
code | Assessor identifier (same as the key) |
triggered | Whether this assessor fired on this event |
weight | Effective weight (configured default or tenant override) |
details | Assessor-specific context (geo country, ASN, fingerprint hash, velocity counts, etc.) |
Event types include risk.scored, risk.step_up_triggered, risk.blocked, and risk.bot_detected.
Example
Related
- Adaptive MFA guide — policy model and assessor reference
- Step-up authentication —
acr_valuesin OAuth flows - API reference — full OpenAPI explorer