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-Signature header on a tawk.to webhook?
  • Why is my tawk.to webhook signature verification failing?
  • How do I handle chat:start, chat:end, chat:transcript_created and ticket:create events?

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).

EventTriggered When
chat:startThe first message of a chat is sent by a visitor or agent (whispers and system messages don't count)
chat:endA chat has ended
chat:transcript_createdThe full transcript is generated after a chat session ends
ticket:createA 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


Repository

hookdeck/webhook-skills

v0.1.0 · MIT · Updated Nov 5, 2026

View on GitHub →