curl --request POST \
--url https://tawked.com/v1/verify/start \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"to": "<string>",
"phone": "<string>",
"channel": "<string>",
"lang": "<string>",
"application": "<string>",
"reference": "<string>",
"client_ip": "<string>",
"autofill": "<string>"
}
'const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
to: '<string>',
phone: '<string>',
channel: '<string>',
lang: '<string>',
application: '<string>',
reference: '<string>',
client_ip: '<string>',
autofill: '<string>'
})
};
fetch('https://tawked.com/v1/verify/start', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://tawked.com/v1/verify/start",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'to' => '<string>',
'phone' => '<string>',
'channel' => '<string>',
'lang' => '<string>',
'application' => '<string>',
'reference' => '<string>',
'client_ip' => '<string>',
'autofill' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}import requests
url = "https://tawked.com/v1/verify/start"
payload = {
"to": "<string>",
"phone": "<string>",
"channel": "<string>",
"lang": "<string>",
"application": "<string>",
"reference": "<string>",
"client_ip": "<string>",
"autofill": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"id": "b7e5c2b0-9c1a-4e2f-8f2a-3a6b0e9d1c44",
"status": "pending",
"expires_at": "2026-09-01T12:34:56.789Z"
}{
"error": "service_required"
}{
"error": "unauthorized"
}{
"error": "insufficient_credits"
}{
"error": "account_not_active"
}{
"error": "service_not_found"
}{
"error": "unsupported_channel"
}{
"error": "too_many_requests"
}{
"error": "internal_error"
}{
"error": "send_failed"
}Start a verification
Sends a one-time code to a destination and returns an id to check it against.
curl --request POST \
--url https://tawked.com/v1/verify/start \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"to": "<string>",
"phone": "<string>",
"channel": "<string>",
"lang": "<string>",
"application": "<string>",
"reference": "<string>",
"client_ip": "<string>",
"autofill": "<string>"
}
'const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
to: '<string>',
phone: '<string>',
channel: '<string>',
lang: '<string>',
application: '<string>',
reference: '<string>',
client_ip: '<string>',
autofill: '<string>'
})
};
fetch('https://tawked.com/v1/verify/start', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://tawked.com/v1/verify/start",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'to' => '<string>',
'phone' => '<string>',
'channel' => '<string>',
'lang' => '<string>',
'application' => '<string>',
'reference' => '<string>',
'client_ip' => '<string>',
'autofill' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}import requests
url = "https://tawked.com/v1/verify/start"
payload = {
"to": "<string>",
"phone": "<string>",
"channel": "<string>",
"lang": "<string>",
"application": "<string>",
"reference": "<string>",
"client_ip": "<string>",
"autofill": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"id": "b7e5c2b0-9c1a-4e2f-8f2a-3a6b0e9d1c44",
"status": "pending",
"expires_at": "2026-09-01T12:34:56.789Z"
}{
"error": "service_required"
}{
"error": "unauthorized"
}{
"error": "insufficient_credits"
}{
"error": "account_not_active"
}{
"error": "service_not_found"
}{
"error": "unsupported_channel"
}{
"error": "too_many_requests"
}{
"error": "internal_error"
}{
"error": "send_failed"
}Authorizations
Authorization: Bearer
Headers
A 1–128 printable-ASCII-character key you generate, scoped to your API key (and, for a partner key, to the named application too). Replaying the same key returns the original 201 response unchanged, with the response header Idempotent-Replayed: true — nothing is sent or charged again. A send that fails releases the key so a retry can go through.
Body
The destination. Any of the accepted Saudi mobile formats below.
Deprecated alias for to, kept for pre-multichannel integrations. Only used when to is absent or blank; to always wins when both are present. New integrations should use to.
Delivery channel. Defaults to "sms" when absent or blank — "sms" is the only channel live over this API today.
Message language. Only the literal value "en" selects English; anything else (including missing) defaults to Arabic.
Partner keys only: which of your provisioned applications is sending. The legacy field name service is accepted identically.
Your own reference (order id, request id, …), up to 64 printable characters. Echoed back on start and on GET /v1/verify/{id}, and searchable in the dashboard's verifications list.
The end user's IP address. Enables the per-IP protection guard for this application when one is configured — never inferred from the request, always explicit.
web, android or none — which autofill line(s) to include on this send. web sends only the @domain #code line, android only the app-hash line, none sends neither. Omit it to send every line the application has configured.