Not to be confused with the inbound webhooks Meta sends to Keebai. Those are configured by Keebai in the Meta dashboard when you connect a channel via Embedded Signup; you don’t touch them.
Use cases
Sync messages to your CRM
Receive every
whatsapp.message.received and store it in your system along with the conversation, contact, and content.Track delivery / read
Subscribe to
whatsapp.message.delivered / .read / .failed to report delivery rates in your dashboard.React to templates
Receive
whatsapp.template.status_updated when Meta approves or rejects a template, and notify your marketing team.Automated provisioning
Listen for
whatsapp.channel.connected to trigger your onboarding flow the moment a channel is ready.How it works
Register an HTTPS URL
Via CLI (
keebai webhooks new) or via API (POST /v1/webhooks). Specify the events you care about and optionally extra headers.Keebai returns a secret
Once. You use it to verify that each delivery actually came from us (HMAC-SHA256 signature). It cannot be retrieved later — store it in your secret manager.
When an event happens, we deliver it
POST call to your URL with the standard JSON envelope and signature headers. If your endpoint responds 2xx, we mark the delivery as successful. If it responds 5xx / timeout / 408 / 429, we retry with exponential backoff (5 attempts, up to ~3h).Envelope
Every event shares the same outer shape. The difference is thedata field, discriminated by type.
| Field | Type | Description |
|---|---|---|
id | string | Unique event ID. Stable: if we retry the delivery, the same ID arrives. Use it to deduplicate. |
type | enum | Discriminator from the catalog. See events. |
occurred_at | ISO-8601 | Event timestamp (UTC). |
company_id | string | Your Keebai company ID. |
channel_id | string | null | Channel associated with the event, if applicable. |
data | object | Event-specific payload. Shape varies by type. |
Delivery headers
EveryPOST to your endpoint includes:
| Header | Example | Usage |
|---|---|---|
X-Keebai-Signature | t=1714214100,v1=8f2c... | HMAC-SHA256 signature over ${t}.${rawBody}. See security. |
X-Keebai-Event-Id | evt_01HXYZ... | Same as body.id. Handy for dedup without parsing the body. |
X-Keebai-Event-Type | whatsapp.message.received | Discriminator. |
X-Keebai-Delivery-Id | dlv_... | Delivery attempt ID. Changes between retries of the same event. |
X-Keebai-Timestamp | 1714214100 | Unix seconds when the signature was generated. Same value as t= in X-Keebai-Signature. |
User-Agent | Keebai-Webhooks/1.0 | |
Content-Type | application/json | |
+custom headers | If you configured headers when creating the subscription, they’re included too. |
Guarantees and limitations
At-least-once delivery
If your endpoint times out or returns 5xx, we retry. Your endpoint must be idempotent: dedup by
event_id.No ordering guarantee
Events from the same channel can arrive out of chronological order (especially with retries). Use
occurred_at to sort.10s timeout
If your endpoint doesn’t respond within 10 seconds, we count a timeout and retry. Process fast and return 2xx; if you need heavy work, push it to your own queue.
HTTPS required
We don’t accept
http:// URLs. Use a valid certificate (Let’s Encrypt works).Next steps
Event catalog
Full list of
type values and the data shape for each one.Signature verification
How to validate
X-Keebai-Signature with HMAC-SHA256 in Node, Python, and PHP.Manage via CLI
Quickstart with
keebai webhooks new/list/test/rotate/delete.Manage via API
REST endpoints
/v1/webhooks to create, list, rotate, delete, and test.