curl -X POST https://tawked.com/v1/email/messages \
-H "Authorization: Bearer tk_live_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-1042-confirmation" \
-d '{
"from": {
"name": "متجر أكمي",
"address": "orders@acme.sa"
},
"to": "customer@example.com",
"subject": "طلبك رقم 1042 قيد التجهيز",
"html": "<p>مرحبًا سارة،</p><p>استلمنا طلبك رقم 1042 وهو قيد التجهيز الآن.</p>",
"text": "مرحبًا سارة،\nاستلمنا طلبك رقم 1042 وهو قيد التجهيز الآن.",
"reply_to": "support@acme.sa",
"reference": "order-1042"
}'const res = await fetch("https://tawked.com/v1/email/messages", {
method: "POST",
headers: {
Authorization: "Bearer tk_live_xxxxxxxxxxxxxxxxxxxx",
"Content-Type": "application/json",
"Idempotency-Key": "order-1042-confirmation",
},
body: JSON.stringify({
"from": {
"name": "متجر أكمي",
"address": "orders@acme.sa"
},
"to": "customer@example.com",
"subject": "طلبك رقم 1042 قيد التجهيز",
"html": "<p>مرحبًا سارة،</p><p>استلمنا طلبك رقم 1042 وهو قيد التجهيز الآن.</p>",
"text": "مرحبًا سارة،\nاستلمنا طلبك رقم 1042 وهو قيد التجهيز الآن.",
"reply_to": "support@acme.sa",
"reference": "order-1042"
}),
});
const data = await res.json();<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://tawked.com/v1/email/messages",
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>',
'subject' => '<string>',
'from' => [
],
'html' => '<string>',
'text' => '<string>',
'reply_to' => '<string>',
'reference' => '<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
res = requests.post(
"https://tawked.com/v1/email/messages",
headers={"Authorization": "Bearer tk_live_xxxxxxxxxxxxxxxxxxxx", "Idempotency-Key": "order-1042-confirmation"},
json={
"from": {
"name": "متجر أكمي",
"address": "orders@acme.sa"
},
"to": "customer@example.com",
"subject": "طلبك رقم 1042 قيد التجهيز",
"html": "<p>مرحبًا سارة،</p><p>استلمنا طلبك رقم 1042 وهو قيد التجهيز الآن.</p>",
"text": "مرحبًا سارة،\nاستلمنا طلبك رقم 1042 وهو قيد التجهيز الآن.",
"reply_to": "support@acme.sa",
"reference": "order-1042"
},
)
data = res.json(){
"id": "3d9a7f2e-1c4b-4e8a-9f6d-2b5c8e1a7d40",
"status": "accepted",
"from": {
"name": "متجر أكمي",
"address": "orders@acme.sa"
},
"to": "customer@example.com",
"subject": "طلبك رقم 1042 قيد التجهيز",
"reference": "order-1042",
"price_halalas": 1,
"created_at": "2026-10-09T12:00:00+03:00"
}{
"error": "service_required"
}{
"error": "unauthorized"
}{
"error": "insufficient_credits",
"message": "Insufficient credits",
"balance_halalas": 0,
"price_halalas": 1
}{
"error": "live_key_required"
}{
"error": "service_not_found"
}{
"error": "no_verified_domain"
}{
"error": "message_too_large"
}{
"error": "sender_not_verified"
}{
"error": "daily_cap_reached"
}{
"error": "internal_error"
}{
"error": "send_failed"
}{
"error": "email_paused"
}Send an email
Sends one message to one recipient from an address on a verified domain of the key’s application, and answers 202 with an id to track it. The price is charged at the send and refunded once if the message bounces or fails; a complaint keeps it.
curl -X POST https://tawked.com/v1/email/messages \
-H "Authorization: Bearer tk_live_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-1042-confirmation" \
-d '{
"from": {
"name": "متجر أكمي",
"address": "orders@acme.sa"
},
"to": "customer@example.com",
"subject": "طلبك رقم 1042 قيد التجهيز",
"html": "<p>مرحبًا سارة،</p><p>استلمنا طلبك رقم 1042 وهو قيد التجهيز الآن.</p>",
"text": "مرحبًا سارة،\nاستلمنا طلبك رقم 1042 وهو قيد التجهيز الآن.",
"reply_to": "support@acme.sa",
"reference": "order-1042"
}'const res = await fetch("https://tawked.com/v1/email/messages", {
method: "POST",
headers: {
Authorization: "Bearer tk_live_xxxxxxxxxxxxxxxxxxxx",
"Content-Type": "application/json",
"Idempotency-Key": "order-1042-confirmation",
},
body: JSON.stringify({
"from": {
"name": "متجر أكمي",
"address": "orders@acme.sa"
},
"to": "customer@example.com",
"subject": "طلبك رقم 1042 قيد التجهيز",
"html": "<p>مرحبًا سارة،</p><p>استلمنا طلبك رقم 1042 وهو قيد التجهيز الآن.</p>",
"text": "مرحبًا سارة،\nاستلمنا طلبك رقم 1042 وهو قيد التجهيز الآن.",
"reply_to": "support@acme.sa",
"reference": "order-1042"
}),
});
const data = await res.json();<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://tawked.com/v1/email/messages",
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>',
'subject' => '<string>',
'from' => [
],
'html' => '<string>',
'text' => '<string>',
'reply_to' => '<string>',
'reference' => '<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
res = requests.post(
"https://tawked.com/v1/email/messages",
headers={"Authorization": "Bearer tk_live_xxxxxxxxxxxxxxxxxxxx", "Idempotency-Key": "order-1042-confirmation"},
json={
"from": {
"name": "متجر أكمي",
"address": "orders@acme.sa"
},
"to": "customer@example.com",
"subject": "طلبك رقم 1042 قيد التجهيز",
"html": "<p>مرحبًا سارة،</p><p>استلمنا طلبك رقم 1042 وهو قيد التجهيز الآن.</p>",
"text": "مرحبًا سارة،\nاستلمنا طلبك رقم 1042 وهو قيد التجهيز الآن.",
"reply_to": "support@acme.sa",
"reference": "order-1042"
},
)
data = res.json(){
"id": "3d9a7f2e-1c4b-4e8a-9f6d-2b5c8e1a7d40",
"status": "accepted",
"from": {
"name": "متجر أكمي",
"address": "orders@acme.sa"
},
"to": "customer@example.com",
"subject": "طلبك رقم 1042 قيد التجهيز",
"reference": "order-1042",
"price_halalas": 1,
"created_at": "2026-10-09T12:00:00+03:00"
}{
"error": "service_required"
}{
"error": "unauthorized"
}{
"error": "insufficient_credits",
"message": "Insufficient credits",
"balance_halalas": 0,
"price_halalas": 1
}{
"error": "live_key_required"
}{
"error": "service_not_found"
}{
"error": "no_verified_domain"
}{
"error": "message_too_large"
}{
"error": "sender_not_verified"
}{
"error": "daily_cap_reached"
}{
"error": "internal_error"
}{
"error": "send_failed"
}{
"error": "email_paused"
}Authorizations
Authorization: Bearer . An application key (tk_live_, tk_test_) has full access, which covers every product and any product added later, or custom access, chosen when the key is created: one or more of the scopes verify:check, verify:send (includes verify:check), notifications:read, notifications:send (includes notifications:read), email:read, email:send (includes email:read), notifications:templates (includes notifications:read). No key made on the API keys page holds notifications:templates, full access included: the three template writes answer such a key 403 insufficient_scope. A connected app's key holds it. A call outside the key's access answers 403 insufficient_scope and names the scope it needs in the WWW-Authenticate response header. A partner key (tk_partner_) always has full access. Whatever its access, a key is a server-side secret.
Headers
A 1 to 128 printable-ASCII-character key you generate, scoped to your API key, as on WhatsApp messages. Replaying the same key returns the original 202 unchanged, with the response header Idempotent-Replayed: true: nothing is sent or charged again. A send that fails with 502 releases the key.
Body
One recipient: a syntactically valid e-mail address. One recipient per call.
The subject line, 1 to 255 characters.
{ "name": "…", "address": "…" }. address must be on a verified domain of this application, any local part. Omitted, name is the domain's default from name and address its default local part (no-reply unless changed) on the application's verified domain.
The HTML body. Give html, text or both; together they are at most 512 KiB.
The plain-text body, shown by clients that do not render HTML. Give html, text or both.
Where replies go: any valid address, on your domain or not.
Your own reference (order id, event id), 1 to 64 printable characters. Echoed back, carried by the webhooks, and searchable on Email → Messages in the console.