Message buffering
Message buffering allows you to receive multiplewhatsapp.message.received events in a single batched webhook, reducing load during high-volume conversations.
How it works
- Debounce pattern - Messages are collected until the configured time window expires
- Automatic batching - Multiple messages from the same conversation are grouped
- Immediate delivery - Batches are sent when max size is reached or window expires
- Per-conversation - Each conversation has its own independent buffer
Configuration
When creating or editing a webhook, enable message buffering for thewhatsapp.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.
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
Message origin
Themessage.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)
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
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
activefield is set tofalse - Pending deliveries are marked as
failedwith 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
- Fix the issue with your endpoint
- Open Integrations → Webhooks in the Kapso dashboard
- Toggle the webhook back to active
Handling retries in your code
Implement idempotency to handle retry attempts gracefully:Best practices
Performance
- Respond quickly - Return 200 within 10 seconds
- Process asynchronously - Use background jobs for heavy processing
- Scale horizontally - Use load balancers to handle high volume
- Enable buffering - Reduce webhook volume during busy periods
Reliability
- Implement idempotency - Use
X-Idempotency-Keyto prevent duplicate processing - Handle all event types - Even if you don’t need them now
- Log everything - Track webhook deliveries and failures
- Set up monitoring - Alert on high failure rates
Example production setup
Troubleshooting
Webhooks not being received
Webhooks not being received
- 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
Duplicate webhooks
Duplicate webhooks
- Implement idempotency using
X-Idempotency-Keyheader - Store processed keys in database or cache
- Use timing-safe comparison when checking keys
Webhooks out of order
Webhooks out of order
- 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
High failure rate
High failure rate
- 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

