API reference
Verify
One-time passcodes by SMS or voice call: send a code, then check what the user typed. We keep only a hash of the code.
BrowseVerify
Read a one-time passcode to a phone by voice call
POST/
- Access
- API key. Scoped keys need
voice:send. - Rate limit
- 10 requests per second
- Safe retries
- Send
X-Idempotency-Key; a replay within 24 hours returns the first response. - Real traffic
- Places a real call or sends a real message, billed to your balance. A test key simulates it against test credit.
Calls to and, when answered, reads the code one digit at a time: "Your {brand} verification code is 4, 8, 2, 9, 1, 3. Again, 4, 8, 2, 9, 1, 3." Repeated repeat times (default 2, max 3), then the call hangs up. Pass your own code (4-10 digits) or let us generate one of length digits (default 6); a generated code is returned only when you set returnCode: true. You check the code yourself; use POST /verify/start instead to have us check it. Languages: en, es, fr, de, pt, hi. brand defaults to your company name and is cleaned to letters, digits and spaces (max 30). Returns as soon as the call is ringing; the outcome and cost arrive with the call.completed webhook and on GET /comms/voice-otp/{id}. Billed exactly like POST /comms/calls: the route rate per billing increment plus the platform fee. No text-to-speech surcharge. A test key simulates the call against test credit. Omit strategy and the code goes out over Smart Routing's best_quality route for the destination (plain calls and SMS default to balanced). Limits, shared by voice passcodes and the Verify API: 5 codes per number per hour, 30 seconds between codes to the same number, a per-account daily cap, and a cap on codes into one number range per hour. A limit answers 429 with details.retryAfterSeconds. Embargoed destinations, premium-rate / satellite / high-risk ranges and numbers on your Do-Not-Contact list are refused with 400.
Parameters
X-Idempotency-Keyheader · string
Any unique string (a UUID is ideal). Replays within 24 hours return the first response instead of acting twice.
Request body (application/json)
torequiredstring
codestring
lengthinteger
4 to 10languagestring
repeatinteger
1 to 3fromstring
strategystring
One ofcheapest,best_quality,balancedbrandstring
Brand read out / sent. Cleaned to letters, digits and spaces, max 30 charactersmax 120 charsreturnCodeboolean
Response 200
datarequiredobject
voiceOtpIdrequiredstring (uuid) · data.voiceOtpId
Use with GET /comms/voice-otp/{id}callIdrequiredstring · data.callId
The call carrying the code; it also appears in GET /comms/calls and the call.completed webhookstatusrequiredstring · data.status
initiated: the call is ringing.accepted: simulated on a test keyOne ofinitiated,acceptedtorequiredstring · data.to
fromrequiredstring · data.from
The caller ID presentedlanguagerequiredstring · data.language
codeLengthrequiredinteger · data.codeLength
repeatrequiredinteger · data.repeat
How many times the code is readcodestring · data.code
Present only when we generated the code AND you sentreturnCode: truecostrequiredmoney | null · data.cost
Test keys: the simulated charge. Live: null here; the final cost arrives with call.completed and on GET USD as a decimal string with exactly 6 places, e.g. "0.012500".simulatedboolean · data.simulated
Present and true for test keys: nothing was dialledcreatedAtrequiredstring (date-time) · data.createdAt
ISO-8601 timestamp (UTC)
Errors
- 400
VALIDATION_ERROR,INVALID_INPUTorBAD_REQUEST. ForVALIDATION_ERROR,error.detailsis an array of{ path, message }. - 401
UNAUTHORIZED: missing, invalid, expired or revoked credential. - 403
FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only. - 409
CONFLICT(or a code-specific 409): the change clashes with existing state. - 429
RATE_LIMITED: slow down and retry after theRetry-Afterseconds. - 500
INTERNAL_ERROR: unexpected failure. QuoteX-Request-Idto support.
Get the outcome of a voice passcode call
GET/
- Access
- API key. Scoped keys need
voice:send. - Rate limit
- 100 requests per second (the default)
Whether the call was answered, how long it ran and what it cost. Never returns the code.
Parameters
idrequiredpath · string (uuid)
Response 200
datarequiredobject
voiceOtpIdrequiredstring (uuid) · data.voiceOtpId
callIdrequiredstring | null · data.callId
statusrequiredstring · data.status
One ofinitiated,answered,no_answer,busy,failed,acceptedtorequiredstring · data.to
languagerequiredstring · data.language
codeLengthrequiredinteger · data.codeLength
costrequiredmoney | null · data.cost
What the call cost you, platform fee included. Null until it ends USD as a decimal string with exactly 6 places, e.g. "0.012500".durationSecondsrequiredinteger | null · data.durationSeconds
createdAtrequiredstring (date-time) · data.createdAt
ISO-8601 timestamp (UTC)completedAtrequiredstring (date-time) | null · data.completedAt
ISO-8601 timestamp (UTC)simulatedboolean · data.simulated
Errors
- 400
VALIDATION_ERROR,INVALID_INPUTorBAD_REQUEST. ForVALIDATION_ERROR,error.detailsis an array of{ path, message }. - 401
UNAUTHORIZED: missing, invalid, expired or revoked credential. - 403
FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only. - 404
NOT_FOUND: no such resource on your account. - 429
RATE_LIMITED: slow down and retry after theRetry-Afterseconds. - 500
INTERNAL_ERROR: unexpected failure. QuoteX-Request-Idto support.
Send a verification code by SMS or voice call
POST/
- Access
- API key. Scoped keys need
verify:write. - Rate limit
- 10 requests per second
- Safe retries
- Send
X-Idempotency-Key; a replay within 24 hours returns the first response. - Real traffic
- Sends a real SMS or places a real voice call carrying the code, billed as that message or call. A test key simulates it.
Generates a code of length digits (default 6), sends it over channel, and returns a verificationId. We store only a keyed hash (HMAC) of the code; the code itself is never stored or logged. The code expires after expirySeconds (default 600). SMS languages: en, es, fr, de, pt, hi, ar. Voice languages: en, es, fr, de, pt, hi. from is the SMS sender ID (defaults to your brand) or, for voice, the caller ID. Billed as the SMS or call that carries the code: the route rate plus the platform fee, no verification fee. A test key sends nothing, charges test credit and returns testCode so you can finish the flow. Omit strategy and the code goes out over Smart Routing's best_quality route for the destination (plain calls and SMS default to balanced). Limits, shared by voice passcodes and the Verify API: 5 codes per number per hour, 30 seconds between codes to the same number, a per-account daily cap, and a cap on codes into one number range per hour. A limit answers 429 with details.retryAfterSeconds. Embargoed destinations, premium-rate / satellite / high-risk ranges and numbers on your Do-Not-Contact list are refused with 400.
Parameters
X-Idempotency-Keyheader · string
Any unique string (a UUID is ideal). Replays within 24 hours return the first response instead of acting twice.
Request body (application/json)
torequiredstring
channelrequiredstring
One ofsms,voicelengthinteger
4 to 10languagestring
brandstring
Brand read out / sent. Cleaned to letters, digits and spaces, max 30 charactersmax 120 charsexpirySecondsinteger
60 to 3600fromstring
max 30 charsstrategystring
One ofcheapest,best_quality,balanced
Response 200
datarequiredobject
verificationIdrequiredstring (uuid) · data.verificationId
Pass to POST /verify/checktorequiredstring · data.to
channelrequiredstring · data.channel
One ofsms,voicestatusrequiredstring · data.status
One ofpendingexpiresAtrequiredstring (date-time) · data.expiresAt
ISO-8601 timestamp (UTC)maxAttemptsrequiredinteger · data.maxAttempts
Wrong guesses allowed before the verification is dead (5)sendRefrequiredstring · data.sendRef
The messageId (SMS) or callId (voice) that carried the codesendStatusrequiredstring · data.sendStatus
SMS send-time status, orinitiatedfor a voice callsimulatedboolean · data.simulated
Present and true for test keys: nothing was senttestCodestring · data.testCode
Test keys ONLY: the code, so a sandbox can complete the check. Never present on a live keycreatedAtrequiredstring (date-time) · data.createdAt
ISO-8601 timestamp (UTC)
Errors
- 400
VALIDATION_ERROR,INVALID_INPUTorBAD_REQUEST. ForVALIDATION_ERROR,error.detailsis an array of{ path, message }. - 401
UNAUTHORIZED: missing, invalid, expired or revoked credential. - 403
FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only. - 409
CONFLICT(or a code-specific 409): the change clashes with existing state. - 429
RATE_LIMITED: slow down and retry after theRetry-Afterseconds. - 500
INTERNAL_ERROR: unexpected failure. QuoteX-Request-Idto support.
Check the code a user entered
POST/
- Access
- API key. Scoped keys need
verify:write. - Rate limit
- 20 requests per second
approved exactly once: a code is single use, and a second check of an approved verification answers denied with reason already_used. Five attempts in total; the fifth wrong guess answers max_attempts and the verification is dead. After expiresAt every check answers expired, even with the right code. Spaces and dashes in the submitted code are ignored. The comparison is constant-time.
Request body (application/json)
verificationIdrequiredstring (uuid)
coderequiredstring
max 32 chars
Response 200
datarequiredobject
verificationIdrequiredstring (uuid) · data.verificationId
statusrequiredstring · data.status
One ofapproved,denied,expired,max_attemptsattemptsRemainingrequiredinteger · data.attemptsRemaining
reasonstring · data.reason
Why a check was not approved, when it is not obvious fromstatusOne ofwrong_code,already_used,not_pending
Errors
- 400
VALIDATION_ERROR,INVALID_INPUTorBAD_REQUEST. ForVALIDATION_ERROR,error.detailsis an array of{ path, message }. - 401
UNAUTHORIZED: missing, invalid, expired or revoked credential. - 403
FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only. - 409
CONFLICT(or a code-specific 409): the change clashes with existing state. - 429
RATE_LIMITED: slow down and retry after theRetry-Afterseconds. - 500
INTERNAL_ERROR: unexpected failure. QuoteX-Request-Idto support.
Get the state of a verification
GET/
- Access
- API key. Scoped keys need
verify:write. - Rate limit
- 100 requests per second (the default)
Status, attempts used and how the code was delivered. Never returns the code.
Parameters
idrequiredpath · string (uuid)
Response 200
datarequiredobject
verificationIdrequiredstring (uuid) · data.verificationId
torequiredstring · data.to
channelrequiredstring · data.channel
One ofsms,voicestatusrequiredstring · data.status
One ofpending,approved,expired,max_attempts,failedattemptsrequiredinteger · data.attempts
maxAttemptsrequiredinteger · data.maxAttempts
expiresAtrequiredstring (date-time) · data.expiresAt
ISO-8601 timestamp (UTC)createdAtrequiredstring (date-time) · data.createdAt
ISO-8601 timestamp (UTC)approvedAtrequiredstring (date-time) | null · data.approvedAt
ISO-8601 timestamp (UTC)sendRefrequiredstring | null · data.sendRef
sendStatusrequiredstring | null · data.sendStatus
simulatedboolean · data.simulated
Errors
- 400
VALIDATION_ERROR,INVALID_INPUTorBAD_REQUEST. ForVALIDATION_ERROR,error.detailsis an array of{ path, message }. - 401
UNAUTHORIZED: missing, invalid, expired or revoked credential. - 403
FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only. - 404
NOT_FOUND: no such resource on your account. - 429
RATE_LIMITED: slow down and retry after theRetry-Afterseconds. - 500
INTERNAL_ERROR: unexpected failure. QuoteX-Request-Idto support.