OTP
Send a code
Makes an OTP and sends it by the first channel that can take it.
POSThttps://api.siellabs.com/v1/verifications
Body#
tostringRequired
The number in international format:
+447700900123.channelsstring[]Optional
The channels to try, in order:
telegram and sms. Default: Telegram, then SMS. Send one to use only that one.code_lengthintegerOptional
The length of the code we make: 4 to 8. Default 6. Not with
code.codestringOptional
Your own code: 4 to 8 digits, instead of one we make. Not with
code_length.ttl_secondsintegerOptional
How long the code is valid: 60 to 86400 seconds. Default 600.
fromstringOptional
The SMS sender, one of your approved sender IDs. Default: your first approved one.
sms_templatestringOptional
The SMS text, with
{code} where the code goes; up to 300 characters. Default: {code} is your Company OTP. Not with template_id.template_idstringOptional
One of your templates as the SMS text. It must contain
{code} and no other variables.payloadstringOptional
Up to 500 characters of your own, returned with this code and in every event: an order or user id, say. Don't put secrets in it.
callback_urlstringOptional
Where this code's events go, instead of your webhooks: an absolute
http(s) URL.Telegram writes its own message, so from, sms_template and template_id apply to SMS only. Your text needs a sender ID of your own.
Codes that fill in themselves#
Phones can take the code out of the SMS and offer it in your app or on your website, so people don't type it. How depends on the text, so it takes an sms_template of your own, or a template:
- iPhone, iPad and Mac offer any code they find in a message. End the text with the line
@yourdomain.com #{code}and the code is offered only on that website and in the apps linked to it, which keeps it out of phishing sites. Chrome on Android reads the same line for websites. - Android apps read the code themselves with Google's SMS Retriever API when the text holds the app's 11-character hash and is at most 140 bytes: one SMS of plain text. Take the hash from the app as Google Play signs it, since Play's signing changes it. Without the hash, Android's SMS User Consent API asks the person to share the message instead.
Your Acme code is {code}. FA+9qCX9VSu
@acme.example #{code}The domain line must be the last line. A domain in your text is checked like any link, against public phishing lists and your content rules.
Response#
201 Created with the OTP object, once the first channel has taken the code.
{
"id": "7c1e0b52-9d2f-7a41-8e33-52d0f1c7ab90",
"to": "+447700900123",
"status": "sent",
"channel": "telegram",
"channels": ["telegram", "sms"],
"telegram_status": "sent",
"price_micros": 15000,
"checks_left": 5,
"payload": "signup-4821",
"expires_at": "2026-11-02T09:25:02.123456Z",
"created_at": "2026-11-02T09:15:02.123456Z"
}Errors#
| HTTP | code | When |
|---|---|---|
| 402 | insufficient_balance | Your balance doesn't cover the code |
| 403 | account_pending | Your account is waiting for approval |
| 403 | trial_number | On trial credits, the number isn't one of your verified test numbers |
| 403 | country_not_allowed | The number is in a country you didn't allow under Fraud protection; no channel sends it |
| 403 | unsafe_link | Your sms_template has a link on a public phishing or malware list; no code is made |
| 403 | content_blocked | Your sms_template matches one of your content rules; no code is made |
| 403 | spending_limit_reached | Your account reached a spending limit you set under Fraud protection; no code is made |
| 422 | invalid_to | Not a valid number in international format |
| 422 | invalid_channels | channels lists something else, or a channel twice |
| 422 | telegram_unavailable | Telegram codes aren't available on your account |
| 422 | invalid_code | code isn't 4 to 8 digits, or came with code_length |
| 422 | invalid_code_length | code_length isn't 4 to 8 |
| 422 | invalid_ttl | ttl_seconds isn't 60 to 86400 |
| 422 | invalid_sms_template | The text has no {code}, has other variables or is too long, or you sent both kinds of text |
| 422 | invalid_template_id | No such template |
| 422 | sender_required | The SMS needs a sender and you have none approved |
| 422 | sender_not_approved | from isn't approved for your account |
| 422 | invalid_payload | payload is over 500 characters |
| 422 | invalid_callback_url | callback_url isn't an absolute http(s) URL |
| 422 | not_sent | No channel could send the code. The body also has the verification, with its error |
| 429 | rate_limited | Over your account's messages per second |
| 429 | too_many_codes | This number had 5 codes in the last 10 minutes. retry_after in the error, and the Retry-After header, say how many seconds until the next one can go |