Skip to main content

Message buffering

Message buffering allows you to receive multiple whatsapp.message.received events in a single batched webhook, reducing load during high-volume conversations.

How it works

  1. Debounce pattern - Messages are collected until the configured time window expires
  2. Automatic batching - Multiple messages from the same conversation are grouped
  3. Immediate delivery - Batches are sent when max size is reached or window expires
  4. Per-conversation - Each conversation has its own independent buffer

Configuration

When creating or editing a webhook, enable message buffering for the whatsapp.message.received event:
  • Buffer window: Time to wait before sending (1-60 seconds, default: 5)
  • Maximum batch size: Max messages per batch (1-100, default: 50)

Batched webhook format

With buffering on, every delivery uses batch format, even a single message.
The data array contains one message if only one arrived during the buffer window. Always check the batch field or the X-Webhook-Batch header rather than assuming the shape.

Handling batched webhooks

Message ordering

Kapso ensures messages are delivered in the correct order within each conversation.

How it works

  • Sequence-based ordering - Each webhook delivery gets a sequence number
  • Automatic queuing - Messages are queued if earlier messages haven’t been delivered
  • Ordering timeout - After 30 seconds, messages are delivered regardless to prevent delays
  • Per conversation - Ordering is maintained independently per conversation
  • Applies to - Message received and message sent events
This ensures your endpoint receives messages in the same order they were sent/received.

Message origin

The message.kapso.origin field tells you how the message entered the system:
  • cloud_api - Sent via Kapso API (outbound jobs, flow actions, API calls)
  • business_app - Sent from WhatsApp Business App (manual messages your team sends using the Business App)
  • history_sync - Backfilled during message history import (only present if your project ran a sync)
Use this to filter out messages you don’t want to process. For example, skip business_app messages to avoid processing manual messages sent by your team.

Retry policy

If Kapso doesn’t receive a 200 response, webhooks are automatically retried.

Retry schedule

Each webhook is attempted based on this schedule:
  • Immediately (initial attempt)
  • 10 seconds after first failure
  • 40 seconds after second failure
  • 90 seconds after third failure
Total time to failure: ~2.5 minutes across 3 retry attempts.

What happens after retries fail?

After all retries are exhausted:
  • The webhook is marked as failed
  • Batched messages fall back to individual delivery
  • You can check failed deliveries in the Kapso dashboard
  • If the failure rate is high enough, the webhook is automatically paused (see below)

Automatic pausing

Kapso automatically pauses a webhook when it detects a persistently failing endpoint. This protects your system from retry storms and prevents queue buildup.

Pause thresholds

A webhook is paused when all of the following are met within a 15-minute window:

What happens when a webhook is paused

  • The webhook’s active field is set to false
  • Pending deliveries are marked as failed with reason "Webhook inactive; delivery skipped"
  • All project members receive an email with failure details and a link to settings
  • No new deliveries are attempted until you re-enable the webhook

Re-enabling a paused webhook

  1. Fix the issue with your endpoint
  2. Open Integrations → Webhooks in the Kapso dashboard
  3. Toggle the webhook back to active
Webhooks that are re-enabled will resume delivery. Make sure your endpoint is healthy before re-enabling, or it may be paused again.

Handling retries in your code

Implement idempotency to handle retry attempts gracefully:

Best practices

Performance

  1. Respond quickly - Return 200 within 10 seconds
  2. Process asynchronously - Use background jobs for heavy processing
  3. Scale horizontally - Use load balancers to handle high volume
  4. Enable buffering - Reduce webhook volume during busy periods

Reliability

  1. Implement idempotency - Use X-Idempotency-Key to prevent duplicate processing
  2. Handle all event types - Even if you don’t need them now
  3. Log everything - Track webhook deliveries and failures
  4. Set up monitoring - Alert on high failure rates

Example production setup

Troubleshooting

  • Verify your endpoint is publicly accessible via HTTPS
  • Check firewall rules allow incoming requests from Kapso
  • Ensure you’re returning 200 status within 10 seconds
  • Check webhook is enabled in dashboard
  • Implement idempotency using X-Idempotency-Key header
  • Store processed keys in database or cache
  • Use timing-safe comparison when checking keys
  • Check sequence numbers in batch_info
  • Implement ordering logic in your application if needed
  • Note: 30-second timeout allows out-of-order delivery to prevent indefinite delays
  • Verify signature verification logic is correct
  • Check endpoint response time (must be under 10 seconds)
  • Review error logs for exceptions in your code
  • Ensure database/external services aren’t timing out
  • If Kapso auto-paused your webhook, fix the endpoint and re-enable it from Integrations → Webhooks