curl -X POST https://tawked.com/v1/email/domains \
-H "Authorization: Bearer tk_live_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"name": "acme.sa"
}'const res = await fetch("https://tawked.com/v1/email/domains", {
method: "POST",
headers: {
Authorization: "Bearer tk_live_xxxxxxxxxxxxxxxxxxxx",
"Content-Type": "application/json",
},
body: JSON.stringify({
"name": "acme.sa"
}),
});
const data = await res.json();<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://tawked.com/v1/email/domains",
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([
'name' => '<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/domains",
headers={"Authorization": "Bearer tk_live_xxxxxxxxxxxxxxxxxxxx"},
json={
"name": "acme.sa"
},
)
data = res.json(){
"id": "0199f1c2-7a41-7c3e-9d2b-5e8f1a2b3c4d",
"name": "acme.sa",
"state": "pending",
"created_at": "2026-10-23T09:00:00+00:00",
"verified_at": null,
"pending_until": "2026-10-26T09:00:00+00:00",
"records": [
{
"purpose": "dkim",
"type": "TXT",
"name": "tawked._domainkey.acme.sa",
"value": "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA…",
"state": "missing"
}
],
"defaults": {
"from_name": "متجر أكمي",
"from_local": "orders"
},
"authentication": {
"dkim": "pass",
"return_path": "working",
"dmarc": "none"
},
"tracking": null,
"receiving": null
}{
"error": "invalid_json"
}{
"error": "unauthorized"
}{
"error": "insufficient_scope"
}{
"error": "domain_taken",
"message": "Another application holds this domain, verified"
}{
"error": "domain_public",
"message": "A public mailbox's domain cannot send: use the business's own domain"
}{
"error": "rate_limited"
}{
"error": "internal_error"
}{
"error": "email_unavailable"
}Add a domain
Adds a sending domain to the application and answers its records to put at your DNS host: the DKIM key’s TXT record, and the return path’s MX and TXT records. Tawked checks them every ten minutes, or at once with POST /v1/email/domains/{id}/verify. 201 with the new domain; 200 with the one the application already has. A live key of the application with the explicit email:manage: a full-access key does not hold it. At most ten a minute for an application.
curl -X POST https://tawked.com/v1/email/domains \
-H "Authorization: Bearer tk_live_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"name": "acme.sa"
}'const res = await fetch("https://tawked.com/v1/email/domains", {
method: "POST",
headers: {
Authorization: "Bearer tk_live_xxxxxxxxxxxxxxxxxxxx",
"Content-Type": "application/json",
},
body: JSON.stringify({
"name": "acme.sa"
}),
});
const data = await res.json();<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://tawked.com/v1/email/domains",
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([
'name' => '<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/domains",
headers={"Authorization": "Bearer tk_live_xxxxxxxxxxxxxxxxxxxx"},
json={
"name": "acme.sa"
},
)
data = res.json(){
"id": "0199f1c2-7a41-7c3e-9d2b-5e8f1a2b3c4d",
"name": "acme.sa",
"state": "pending",
"created_at": "2026-10-23T09:00:00+00:00",
"verified_at": null,
"pending_until": "2026-10-26T09:00:00+00:00",
"records": [
{
"purpose": "dkim",
"type": "TXT",
"name": "tawked._domainkey.acme.sa",
"value": "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA…",
"state": "missing"
}
],
"defaults": {
"from_name": "متجر أكمي",
"from_local": "orders"
},
"authentication": {
"dkim": "pass",
"return_path": "working",
"dmarc": "none"
},
"tracking": null,
"receiving": null
}{
"error": "invalid_json"
}{
"error": "unauthorized"
}{
"error": "insufficient_scope"
}{
"error": "domain_taken",
"message": "Another application holds this domain, verified"
}{
"error": "domain_public",
"message": "A public mailbox's domain cannot send: use the business's own domain"
}{
"error": "rate_limited"
}{
"error": "internal_error"
}{
"error": "email_unavailable"
}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), email:manage (includes email:send), webhooks:manage, email:inbound, notifications:templates (includes notifications:read), chat:menus, chat:attendant. 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. Nor chat:menus: the five conversation menu operations answer such a key 403 insufficient_scope, and a connected app's key holds it once the client approved it. Nor chat:attendant: the five auto-attendant operations answer such a key 403 insufficient_scope too, and a connected app's key holds it once the client approved it. email:manage and webhooks:manage are held only by a key someone chose them for: a full-access key, old or new, never holds them. email:inbound, which reads, deletes and forwards received e-mail, is opt-in on every key, full access included: a key holds it only when it was turned on when the key was created. 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
Up to 128 characters. A retry with the same key and the same body within 24 hours answers what the first call answered and changes nothing again; the same key with another body answers 409 idempotency_key_reused.
Body
The domain, such as acme.sa: the business's own, never a public mailbox's (gmail.com and the like) or Tawked's.