Verify Codes
The verify codes endpoint allows you to send one-time verification codes (OTP) to phone numbers via multiple delivery channels. It supports a multi-step routing strategy with automatic fallback — if one channel fails or times out, the next channel is tried automatically.
- Create a verify code request with a flexible routing strategy
- Support for Telegram, Voice (text-to-speech), and SMS delivery channels
- Automatic fallback between channels on failure or timeout
- Query verify code status, delivery history, and cost information
- Delete verification codes from storage after delivery for security
How it works
Section titled “How it works”When you create a verify code request, you define a routing strategy — an ordered list of delivery channels to attempt. The system processes each channel in order:
- Sends the verification code through the first channel (e.g., Telegram).
- Telegram: waits for a delivery confirmation from the Telegram API within
timeout_sec. Voice: makes one call attempt; success if the recipient picks up. SMS: succeeds once the message is accepted by the mobile network. - If the channel fails or times out, automatically falls back to the next channel.
- Repeats until a channel succeeds or all channels have been exhausted.
Routing strategy
Section titled “Routing strategy”Each step in the routing strategy specifies a channel and optional parameters. All parameters except channel are optional — sensible defaults are used when omitted.
| Channel | Parameters | Delivery success criteria | Notes |
|---|---|---|---|
telegram | timeout_sec | Delivery confirmation received from Telegram within timeout_sec | timeout_sec: min 30, max 3600, default 30. |
voice | sender_id, template | Recipient picked up the phone | Text-to-speech call. Only one dial attempt is made. Template is automatically wrapped in SSML <speak> tags. |
sms | sender_id, template | SMS was accepted for delivery by the network | Standard SMS delivery. Can only be the last step in the routing strategy. |
Rules:
- At least one channel is required.
- Duplicate channels are not allowed.
- The
smschannel can only be the last step (no fallback after SMS). - The
timeout_secparameter is only applicable for thetelegramchannel.
Cost optimization
Section titled “Cost optimization”The total cost of a verify code request is the sum of all sent messages across all channels that were attempted — even if some channels failed. Each channel attempt incurs a per-message cost.
Recommendation: Order your routing strategy from cheapest to most expensive channel. For example, place telegram first (lowest cost), then voice, and sms last. This way, if the cheaper channel succeeds, you avoid paying for the more expensive ones.
Blocking and filtering
Section titled “Blocking and filtering”Before attempting delivery, the system checks the recipient’s phone number against your account-level restrictions:
- Blocked phone numbers: If the recipient number is in your blocked numbers list, the message will not be sent.
- SMS filters: If the recipient number matches any of your SMS filters, the message will not be sent.
When a message is blocked by a filter or blocked number, the channel step and the overall task both receive status 20 (Failed). No fallback to the next channel is attempted in this case.
Verification code
Section titled “Verification code”The verification code is a numeric string (4–8 digits) sent to the recipient:
- Custom code: Provide your own code via the
codeproperty (4–8 characters). - Auto-generated: If
codeis not provided, a random numeric code is generated. Control the length withcode_length(default: 4, range: 4–8).
Use the template property per channel to customize the message text. The placeholder {{code}} is replaced with the actual verification code. If no template is provided, a default translated message is used based on the lang field.
Security: Delete code after sending
Section titled “Security: Delete code after sending”Set is_code_deleted to true to automatically delete the verification code from LOX24 storage after it has been sent to the recipient. This ensures the code is not retained in the database after delivery.
IMPORTANT: When is_code_deleted is active, the code field will be absent in subsequent GET responses after the task is completed.
Status codes
Section titled “Status codes”The verify code request progresses through the following statuses:
Both the overall task and each individual channel use the same status values, but the semantics differ:
Task status (top-level status):
| Status | Meaning |
|---|---|
0 | New — request created, not yet processed |
5 | In Progress — delivery in progress |
10 | Success — code successfully delivered via at least one channel |
20 | Failed — delivery failed across all channels |
100 | Error — system error |
Channel status (history[].status):
| Status | Meaning |
|---|---|
0 | New — channel step created, not yet processed |
5 | In Progress — sending via this channel |
10 | Success — delivery confirmed on this channel |
20 | Failed — delivery failed on this channel |
100 | Error — system error on this channel |
Webhook notifications
Section titled “Webhook notifications”Verify code events can be sent to your webhook endpoint. The following events are available:
verify_code.success— code was successfully deliveredverify_code.failed— delivery failed across all channelsverify_code.channel.sent— code dispatched through a specific channelverify_code.channel.success— channel confirmed successful deliveryverify_code.channel.failed— channel failed to deliververify_code.channel.updated— channel status updated
See the Webhook notifications section for more details on configuring webhook endpoints.