Skip to main content
Webhooks are how you receive WhatsApp messages. Kapso pushes real-time notifications about your messages and conversations over HTTPS, delivering a JSON payload you can use in your application.
Do not assume every payload has a phone number. See the BSUID migration guide.
WhatsApp can now send identity without a phone number, so Kapso adds business_scoped_user_id, parent_business_scoped_user_id, and username to the relevant payloads. Update your parser before assuming phone_number, wa_id, from, or to are present.

What are webhooks?

Webhooks notify your application when events occur. You can use them to:
  • Send automated replies when customers message you
  • Update conversation status in your CRM
  • Track message delivery and read receipts
  • Trigger alerts when conversations go inactive
  • Store events in your database for analytics

Steps to receive webhooks

  1. Create an endpoint to receive requests
  2. Register your webhook
  3. Verify signatures
  4. Test your endpoint

1. Create an endpoint

Create a route in your application that accepts POST requests.
Kapso sends the event name in X-Webhook-Event. Unbuffered webhooks send the event payload directly as the request body. When buffering is enabled for whatsapp.message.received, the body uses a batch envelope with type, batch: true, data: [...], and batch_info. Your endpoint must return 200 OK within 10 seconds.

2. Register your webhook

Kapso supports two types of webhooks:

Project webhooks

Project-wide events like WhatsApp connection lifecycle and workflow execution. No message or conversation events here. Use a WhatsApp webhook per phone number. Setup:
  1. Open Integrations → Webhooks
  2. Go to the Platform webhooks tab
  3. Click Add Webhook
  4. Enter your HTTPS endpoint URL
  5. Copy the auto-generated secret key
  6. Subscribe to events

WhatsApp webhooks

Message and conversation events for specific WhatsApp numbers. Two webhook kinds available:

Kapso webhooks (default)

Event-based webhooks with Kapso payload format. Subscribe to specific events, use buffering, and receive structured payloads.

Meta webhooks

Receive the exact payload Meta sends. No event filtering, no buffering - just raw Meta webhook forwarding with an idempotency key for deduplication.
Meta webhooks include an X-Idempotency-Key header (SHA256 hash of the payload) for deduplication. Only one meta webhook is allowed per phone number. You can also set this up from the dashboard: open your connected number, click Edit, and add your Webhook destination URL. Kapso forwards all Meta webhook events to that endpoint. Forwarded Meta payloads can include BSUID-only identity. For the Meta-side rollout, see Meta: business-scoped user IDs. To parse raw Meta payloads, use the TypeScript SDK:
normalizeWebhook() converts Meta’s payload to the same structure as messages.query(), adds kapso.direction, and keeps all raw fields under events.raw.

3. Verify signatures

Always verify webhook signatures to ensure requests come from Kapso.
See Security for detailed verification guide.

4. Test your endpoint

Use ngrok or Cloudflare tunnel for local testing:
Register the generated HTTPS URL in your webhook configuration.

Webhook headers

Kapso webhooks

Batched webhooks also include:

Meta webhooks

Meta webhooks forward the exact payload received from Meta, without modification.

More webhook docs

Event types

See available webhook events and payload examples

Security

Verify signatures and secure your endpoint

Advanced

Understand buffering, ordering, and retries

Legacy webhooks

Reference the older webhook format and migration path

FAQ

If Kapso doesn’t receive a 200 response, webhooks are retried automatically:
  • 10 seconds
  • 40 seconds
  • 90 seconds
Total time: ~2.5 minutes. After max retries, batched messages fall back to individual delivery.See Advanced for details.
Use the X-Idempotency-Key header to track processed events:
New webhooks default to v2. Existing v1 webhooks continue to work.See Legacy webhooks for migration guide.