kirim.dev/ docsGet started
Menu

Webhooks

Register HTTPS endpoints to receive WhatsApp events — inbound messages, delivery and read statuses, and more. kirim.dev verifies Meta's signature, then delivers each event to your endpoints, retrying on failure and signing every delivery so you can trust it.

Register an endpoint

Add an endpoint from the dashboard under Webhooks. You provide a URL and the fields to subscribe to; kirim.dev returns a signing secret shown once — store it, it is not shown again.

  • url — your HTTPS endpoint. It must return a 2xx quickly.
  • fields — the events to receive, e.g. messages, statuses (1–40 fields).
  • Optionally scope an endpoint to a single connected number; otherwise it receives events for all of them.

What a delivery looks like

Each event is a POST to your URL. The body is the WhatsApp webhook payload, unchanged:

POST /your-endpoint
POST https://your-app.example.com/webhooks
Content-Type: application/json
webhook-id: msg_2a9f...
webhook-timestamp: 1720000000
webhook-signature: v1,K5oScU9s7Yx...
X-Meta-Signature-256: sha256=...

{
  "object": "whatsapp_business_account",
  "entry": [ { "changes": [ { "field": "messages", "value": { ... } } ] } ]
}

Verifying the signature

Deliveries are signed with the Standard Webhooks scheme, so any Standard Webhooks library verifies them. The signature covers id.timestamp.payload, which also protects against replay.

verify.ts
import { Webhook } from "standardwebhooks";

const wh = new Webhook(process.env.KIRIM_WEBHOOK_SECRET);

// throws if the signature or timestamp is invalid
const event = wh.verify(rawRequestBody, {
  "webhook-id": req.headers["webhook-id"],
  "webhook-timestamp": req.headers["webhook-timestamp"],
  "webhook-signature": req.headers["webhook-signature"],
});

Headers on every delivery:

  • webhook-id — unique id for this event (use it to deduplicate).
  • webhook-timestamp — unix seconds; reject deliveries far outside your tolerance.
  • webhook-signaturev1,<base64 HMAC-SHA256>.
  • X-Meta-Signature-256 — Meta's original signature, forwarded for BYOA verification.

Retries & delivery history

A delivery that does not get a 2xx is retried with backoff over several hours. You can see each endpoint's delivery history — status, attempts, and the response it got — and replay a delivery from the dashboard. An endpoint that keeps failing is disabled automatically, and shown as such before it happens.

Payload details:The structure of the event payload (entry, changes, value) and every field you can subscribe to are documented in Meta's Cloud API reference →