curl -X PATCH https://tawked.com/v1/chat/menus/5b1d2c3e-4f5a-4b6c-8d7e-9f0a1b2c3d4e \
-H "Authorization: Bearer tk_live_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: client-8841-bookings-key-2" \
-d '{
"url": "https://app.yourplatform.example/tawked/bookings?key=NEW_PER_CLIENT_KEY&phone={customer_phone}"
}'const res = await fetch("https://tawked.com/v1/chat/menus/5b1d2c3e-4f5a-4b6c-8d7e-9f0a1b2c3d4e", {
method: "PATCH",
headers: {
Authorization: "Bearer tk_live_xxxxxxxxxxxxxxxxxxxx",
"Content-Type": "application/json",
"Idempotency-Key": "client-8841-bookings-key-2",
},
body: JSON.stringify({
"url": "https://app.yourplatform.example/tawked/bookings?key=NEW_PER_CLIENT_KEY&phone={customer_phone}"
}),
});
const data = await res.json();<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://tawked.com/v1/chat/menus/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'title' => '<string>',
'url' => '<string>',
'icon' => '<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.patch(
"https://tawked.com/v1/chat/menus/5b1d2c3e-4f5a-4b6c-8d7e-9f0a1b2c3d4e",
headers={"Authorization": "Bearer tk_live_xxxxxxxxxxxxxxxxxxxx", "Idempotency-Key": "client-8841-bookings-key-2"},
json={
"url": "https://app.yourplatform.example/tawked/bookings?key=NEW_PER_CLIENT_KEY&phone={customer_phone}"
},
)
data = res.json(){
"id": "5b1d2c3e-4f5a-4b6c-8d7e-9f0a1b2c3d4e",
"title": "الحجوزات",
"url": "https://app.yourplatform.example/tawked/bookings?key=NEW_PER_CLIENT_KEY&phone={customer_phone}",
"icon_url": "https://tawked.com/storage/chat-menus/5b1d2c3e-4f5a-4b6c-8d7e-9f0a1b2c3d4e.png",
"frame": "opens",
"created_at": "2026-10-15T09:00:00Z",
"updated_at": "2026-11-01T08:30:00Z"
}{
"error": "invalid_request"
}{
"error": "unauthorized"
}{
"error": "live_key_required"
}{
"error": "not_found"
}{
"error": "idempotency_in_progress"
}{
"error": "too_many_requests"
}{
"error": "internal_error"
}{
"error": "chat_unavailable"
}Update a menu
For a connected app’s key alone, with chat:menus in its connection’s grant: an application’s own key, full access included, answers 403 insufficient_scope, and adds its menus in the console. Changes any of title, url and icon of a menu this connection made; what is left out stays, and at least one is sent. A new url is checked for framing again. Use it to rotate the key in the link: keep the new key on your server beside the old one, send the new link, then drop the old key once the client’s team has reloaded Tawked Chat. Answers the menu as it stands after the change.
curl -X PATCH https://tawked.com/v1/chat/menus/5b1d2c3e-4f5a-4b6c-8d7e-9f0a1b2c3d4e \
-H "Authorization: Bearer tk_live_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: client-8841-bookings-key-2" \
-d '{
"url": "https://app.yourplatform.example/tawked/bookings?key=NEW_PER_CLIENT_KEY&phone={customer_phone}"
}'const res = await fetch("https://tawked.com/v1/chat/menus/5b1d2c3e-4f5a-4b6c-8d7e-9f0a1b2c3d4e", {
method: "PATCH",
headers: {
Authorization: "Bearer tk_live_xxxxxxxxxxxxxxxxxxxx",
"Content-Type": "application/json",
"Idempotency-Key": "client-8841-bookings-key-2",
},
body: JSON.stringify({
"url": "https://app.yourplatform.example/tawked/bookings?key=NEW_PER_CLIENT_KEY&phone={customer_phone}"
}),
});
const data = await res.json();<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://tawked.com/v1/chat/menus/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'title' => '<string>',
'url' => '<string>',
'icon' => '<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.patch(
"https://tawked.com/v1/chat/menus/5b1d2c3e-4f5a-4b6c-8d7e-9f0a1b2c3d4e",
headers={"Authorization": "Bearer tk_live_xxxxxxxxxxxxxxxxxxxx", "Idempotency-Key": "client-8841-bookings-key-2"},
json={
"url": "https://app.yourplatform.example/tawked/bookings?key=NEW_PER_CLIENT_KEY&phone={customer_phone}"
},
)
data = res.json(){
"id": "5b1d2c3e-4f5a-4b6c-8d7e-9f0a1b2c3d4e",
"title": "الحجوزات",
"url": "https://app.yourplatform.example/tawked/bookings?key=NEW_PER_CLIENT_KEY&phone={customer_phone}",
"icon_url": "https://tawked.com/storage/chat-menus/5b1d2c3e-4f5a-4b6c-8d7e-9f0a1b2c3d4e.png",
"frame": "opens",
"created_at": "2026-10-15T09:00:00Z",
"updated_at": "2026-11-01T08:30:00Z"
}{
"error": "invalid_request"
}{
"error": "unauthorized"
}{
"error": "live_key_required"
}{
"error": "not_found"
}{
"error": "idempotency_in_progress"
}{
"error": "too_many_requests"
}{
"error": "internal_error"
}{
"error": "chat_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), 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. 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. Replaying it with the same request answers the original 2xx unchanged, with the response header Idempotent-Replayed: true, and runs nothing again; the same key with another request answers 409 idempotency_key_reused, and a request still in flight 409 idempotency_in_progress. A refused request is never stored, so a corrected retry under the same key runs. Keys expire after 24 hours.
Path Parameters
The menu's id, as the create answered it. An id this connection did not make answers 404 not_found, whoever made it.
Body
The name your client's team sees on the tab: 2 to 30 characters, unique among the menus that show in the application's conversations. Refused: required, length, taken.
The link of the page, saved as sent: https:// only, at most 1024 characters, on a public domain name (no IP address, no port but 443, no user name or password, no token in the host). It may hold the tokens {customer_phone}, {customer_name}, {customer_email} and {conversation_id}, filled when the menu opens, and the key you made for this one client. Refused: required, http, host, length, reserved.
Left out, the current icon stays. "site" takes the link's site's own icon (its favicon or apple-touch-icon), as the console does; "none" shows no icon; { "url": "https://..." } is an https link to a PNG, JPEG or WebP of at most 1 MB and at least 32 px on its short side, which Tawked downloads once from a public address and turns into the 64 px icon Tawked Chat shows. Refused: type (not a PNG, JPEG or WebP of at most 1 MB, or an icon of another shape), small (under 32 px), unreachable (the link could not be read).