Verify
Every request sends x-api-key. New here? Start with the
quickstart, or read API keys.
| Operation | SDK call | Endpoint |
|---|---|---|
| Send a verification code | verify.start | POST /v1/verify/start |
| Check a verification code | verify.check | POST /v1/verify/check |
Send a verification code
Send a verification code to a phone number using this account's approved WhatsApp authentication template. Returns a verificationId to pass to /check. ttlSeconds and codeLength may be overridden per call; everything else comes from the account's Verify configuration. A test key runs the whole flow without sending a message and returns the generated code so the path is exercisable.
Body
| Field | Type | Required | Description |
|---|---|---|---|
phone | string | yes | The recipient's phone number in E.164 format, including the country code. |
channel | whatsapp | no | Delivery channel. WhatsApp is the only value today. |
ttlSeconds | integer | no | How long the code stays valid. Defaults to the account's Verify setting. |
codeLength | integer | no | How many digits the code has. Defaults to the account's Verify setting. |
Response 200
{
"verificationId": "vrf_9f2c8d1e4b7a4c3f9e0d2a5b6c7d8e9f",
"status": "pending",
"channel": "whatsapp",
"code": "483920"
}| Field | Type | Description |
|---|---|---|
verificationId | string | Pass this to /v1/verify/check. |
status | pending | approved | invalid | expired | max_attempts | Always pending here. The other values come back from /check. |
expiresAt | string (ISO 8601) | After this, the code is rejected and you must start again. |
channel | whatsapp | The channel the code was sent over. |
testMode | boolean | Present and true on a test key. Nothing was sent. |
code | string | The generated code. Returned on a test key only, so the flow is exercisable without a phone. |
Errors
Returns 401, 403, 409, 429, 503. Every one carries the standard envelope — branch on code, not the status. See Errors.
Check a verification code
Check a code against a verification. Always a 200 carrying the resulting status — approved, invalid, expired or max_attempts — rather than an error status, so a client branches on one field. Re-checking a verification that already reached a terminal status returns that status unchanged and costs no attempt, which makes a retried check safe inside the TTL.
Body
| Field | Type | Required | Description |
|---|---|---|---|
verificationId | string | yes | The id returned by /v1/verify/start. The vrf_ prefix is optional. |
code | string | yes | The code the user entered. Digits only. |
Response 200
{
"status": "pending",
"remainingAttempts": 4
}| Field | Type | Description |
|---|---|---|
status | pending | approved | invalid | expired | max_attempts | approved means verified. invalid is a wrong code, not an error. expired and max_attempts are terminal — start a new verification. |
remainingAttempts | integer | How many tries are left. Present only while another attempt could still approve. |
Errors
Returns 401, 403, 404, 409, 429, 503. Every one carries the standard envelope — branch on code, not the status. See Errors.