Agent skill
tawk.to Webhooks Skill
Receive and verify tawk.to webhooks. Use when setting up tawk.to live chat webhook handlers, debugging X-Tawk-Signature (HMAC-SHA1) verification, or handling chat:start, chat:end, chat:transcript_created and ticket:create events.
Install this skill
npx skills add hookdeck/webhook-skills --skill tawk-to-webhooks
When to Use This Skill
- How do I receive tawk.to webhooks?
- How do I verify the
X-Tawk-Signatureheader on a tawk.to webhook? - Why is my tawk.to webhook signature verification failing?
- How do I handle
chat:start,chat:end,chat:transcript_createdandticket:createevents?
Essential Code (USE THIS)
tawk.to signs every webhook with HMAC-SHA1 over the raw request body, keyed with the webhook's secret key. The lowercase hex digest is sent in the X-Tawk-Signature header. There is no timestamp and no prefix.
Verification (core)
const crypto = require('crypto');
function verifyTawkSignature(rawBody, signatureHeader, secret) {
if (!signatureHeader || !secret) return false;
const expected = crypto.createHmac('sha1', secret).update(rawBody).digest('hex');
const a = Buffer.from(signatureHeader, 'utf8');
const b = Buffer.from(expected, 'utf8');
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
import hashlib, hmac
def verify_tawk_signature(raw_body: bytes, signature: str | None, secret: str) -> bool:
if not signature or not secret:
return False
expected = hmac.new(secret.encode(), raw_body, hashlib.sha1).hexdigest()
return hmac.compare_digest(signature.encode(), expected.encode())
Use the raw body. In Express, mount express.raw({ type: '*/*' }) on the route so verification works whatever Content-Type the request carries; parse JSON only after the signature checks out.
For complete handlers with tests, see examples/express/, examples/nextjs/, examples/fastapi/.
Common Event Types
The event name is in the payload's event field (tawk.to sends no event-type header).
| Event | Triggered When |
|---|---|
chat:start | The first message of a chat is sent by a visitor or agent (whispers and system messages don't count) |
chat:end | A chat has ended |
chat:transcript_created | The full transcript is generated after a chat session ends |
ticket:create | A new ticket is created |
Each delivery carries an X-Hook-Event-Id header that stays the same across retries: use it as your idempotency key. Respond with any 2XX within 30 seconds; failures are retried for up to 12 hours.
Environment Variables
# The webhook's secret key (webhooks are under Administration > Settings > Webhooks)
TAWK_WEBHOOK_SECRET=your_webhook_secret_key
Local Development
npx hookdeck-cli listen 3000 tawk-to --path /webhooks/tawk-to
No account required. Use the URL Hookdeck prints as the webhook URL in tawk.to.
Reference Materials
- references/overview.md - What tawk.to webhooks are, events and payloads
- references/setup.md - Create a webhook and get the secret key
- references/verification.md - HMAC-SHA1 verification details and gotchas