Skip to main content

Verify API

Send and check OTP verification codes via SMS, WhatsApp, or Email Base path: /api/v1/verify Endpoint count: 16
GET /api/v1/public/verify/magic-link/consume
‘Public, unauthenticated endpoint that consumes a single-use magic-link token emitted by `POST

List verifications

GET /api/v1/verify/
Retrieve verification records with cursor-based pagination.

Get verification

GET /api/v1/verify/{id}
Retrieve a single verification record by ID.
string
required

Get verification detail

GET /api/v1/verify/{id}/detail
Consolidated detail DTO for the verification-request drawer. Returns the verification row plus fallback timeline, profile name, and a masked code-attempt log (submitted digits limited to the trailing 4 characters only).
string
required

Verification analytics

GET /api/v1/verify/analytics
Aggregate totals and channel breakdown for verifications.

Verify Fraud Shield conversion anomaly

GET /api/v1/verify/conversion-anomaly
Detect artificially-inflated traffic (AIT / SMS-pumping) on the Verify product via per-destination OTP completion-rate anomaly (verified vs sent): destinations converting far below the tenant baseline against a material send volume are flagged, with an estimated carrier spend-at-risk figure. Optional window_days query (1-90, default 30).

Cancel verification

POST /api/v1/verify/{id}/cancel
Cancel a pending verification.
string
required

Resend verification

POST /api/v1/verify/{id}/resend
Resend a verification code for a pending verification.
string
required

Send bulk verifications

POST /api/v1/verify/bulk
High-throughput OTP fan-out for login surges / password-reset campaigns. Accepts an array of up to 1000 recipients sharing one channel + optional profile/template. Each recipient flows through the same per-recipient send pipeline as POST /verify/send (rate limit, fraud velocity, wallet deduct, MessageRouter dispatch), so invariant #45 (SMS/voice via Devotel softswitch only) is preserved. Returns 201 when all sent, 207 (Multi-Status) on partial success, 400 when every recipient failed.

Check a verification code

POST /api/v1/verify/check
Validate a verification code against the stored record.
string
required
ID returned from the send step. Format is vrf_<hex> (per generateId('verification')); NOT a bare UUID — paired with the matching loosening on profile_id to prevent the same format: uuid mismatch (DEVOTEL-ORBIT-28 family).
string
required
Verification code entered by the user

Create backup-code factor

POST /api/v1/verify/factors/backup-codes
Mint 10 single-use backup codes for an end-tenant user. The plaintext codes are returned ONCE in the response; the server stores SHA-256 hashes only and cannot recover plaintext. Use this surface for recovery flows when the user has lost their device + SMS access (Twilio/Auth0/Authy parity).
string
required
Identifier for the end user these backup codes belong to, such as their email or username. Required, 1 to 200 characters.
string
Optional label stored with the factor for display in your own factor-management UI. Up to 200 characters.

Verify backup code

POST /api/v1/verify/factors/backup-codes/{id}/verify
Consume one backup code against a provisioned factor. The same code cannot succeed twice (single-use, enforced via an UPDATE … WHERE consumed_at IS NULL gate). Returns remaining_count so the FE can prompt regeneration when the user is low on codes.
string
required

Create TOTP factor

POST /api/v1/verify/factors/totp
Provision an authenticator-app (RFC 6238) factor. Returns the otpauth:// URI for QR rendering plus the base32 secret for manual entry. The secret is surfaced ONCE — subsequent list/get calls return metadata only.
string
required
Identifier for the end user this authenticator factor belongs to, such as their email or username. It is written into the otpauth:// URI and shown beside the generated code in the user’s authenticator app. Required, 1 to 200 characters.
string
Optional label stored with the factor for display in your own factor-management UI. Up to 200 characters.

Regenerate TOTP recovery codes

POST /api/v1/verify/factors/totp/{id}/recovery-codes/regenerate
Invalidate the factor’s existing recovery codes and return a fresh batch of 10 single-use codes. The new plaintexts are surfaced ONCE — only their SHA-256 hashes are persisted at rest. Used after a device is restored or the prior codes are suspected exposed.
string
required

Verify TOTP code

POST /api/v1/verify/factors/totp/{id}/verify
Validate a 6-digit code against a provisioned TOTP factor (RFC 6238, 30s step, ±1 step skew window).
string
required

Send a verification code

POST /api/v1/verify/send
Generate and deliver a one-time verification code via the specified channel.
string
required
Recipient (E.164 phone or email)
string
default:"sms"
Delivery channel for the OTP. Optional — when omitted it defaults to sms.Accepts any value in the canonical set: sms, whatsapp, email, voice, viber, telegram, rcs, silent, flashcall, sna, totp, push, magic_link, backup_code.The first seven are direct delivery channels. The remaining values are additional factor channels: some are not OTP-delivery channels and will return a structured error steering you to the dedicated factor endpoints (for example totp, push, magic_link, and backup_code), and provider-dependent channels such as sna and flashcall return a 503 when no capable provider is wired.
string (enum: sms|whatsapp|email|voice|viber|telegram|…)[]
Optional ad-hoc fallback channel chain (overlays the send when no profile_id is set)
object
Optional async fallback engine config (pairs with channels)
integer
Max verification attempts
string
Optional verification profile ID. Format is vprof_<hex> (per generateId("vprof")); NOT a bare UUID — the prior format: uuid constraint here was the root cause of DEVOTEL-ORBIT-28 (27 events in 11 days) where every FE call with a real profile id 422’d before reaching the Zod parse.
string
Optional ISO 3166-1 alpha-2 country hint (e.g. TR) so national-format phone numbers normalise to the E.164 form OTP providers require. Not needed for clean E.164 input.
integer
Number of digits in the generated OTP (defaults to 6). Must equal custom_code length when a custom code is supplied.
object
Optional PSD2 SCA dynamic-linking binding. Replay the SAME object on POST /verify/check; a mismatch rejects with BINDING_MISMATCH. Omit for non-PSD2 flows.
string (enum: en|es|fr|de|it|pt|…)
Optional 2-letter language code selecting the localized voice TTS and SMS body for the built-in fallback message. Profile-defined templates override it. Region tags (e.g. es-MX) are rejected — use es.
string
Optional caller-supplied OTP (4–8 digits, digits only) for sandbox / test-mode QA. Rejected on live keys. Its length must equal code_length.
string
Device-bound network access token for the sna channel (Silent Network Authentication), obtained via the GSMA Open Gateway / CAMARA flow. When present on an sna send, verification completes via a network possession-proof and no OTP is minted.