Webhooks
Zapy API sends real-time notifications to your server when events occur on your WhatsApp instances. Configure a webhook URL to receive these events and build reactive applications.
How Webhooks Work
- Configure your webhook URL in your instance settings
- Zapy sends HTTP POST requests to your URL when events occur
- Your server processes the event and responds with a 2xx status code
Webhook Payload Structure
All webhook payloads follow this structure:
{
"event": "event-type",
"instanceId": "your-instance-id",
"data": {
// Event-specific data
}
}
| Field | Type | Description |
|---|---|---|
event | string | The event type identifier |
instanceId | string | The WhatsApp instance ID that triggered the event |
data | object | Event-specific payload data |
Available Events
| Event | Description |
|---|---|
message | New message received (text, media, polls, calls, etc.) |
message-status | Message delivery status update |
qr-code | QR code generated for authentication |
contact-created | New contact discovered |
contact-updated | Contact information updated |
contact-deduplicated | Duplicate contacts merged |
Webhook Security
Signature Verification
If you configure a webhook secret, Zapy will sign all webhook payloads using HMAC-SHA256. The signature is included in the X-Webhook-Signature header.
Header format:
X-Webhook-Signature: sha256=<signature>
Verification example (Node.js):
const crypto = require('crypto');
function verifyWebhookSignature(payload, signature, secret) {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(JSON.stringify(payload))
.digest('hex');
return signature === `sha256=${expectedSignature}`;
}
// In your webhook handler
app.post('/webhook', (req, res) => {
const signature = req.headers['x-webhook-signature'];
const isValid = verifyWebhookSignature(req.body, signature, YOUR_SECRET);
if (!isValid) {
return res.status(401).send('Invalid signature');
}
// Process the webhook...
res.status(200).send('OK');
});
Request Headers
All webhook requests include these headers:
| Header | Value |
|---|---|
Content-Type | application/json |
User-Agent | ZapyAPI-Webhook/1.0 |
X-Webhook-Signature | sha256=<signature> (if secret configured) |
Best Practices
- Respond quickly - Return a 2xx status code within 10 seconds
- Process asynchronously - Queue events for background processing
- Verify signatures - Always validate the webhook signature in production
- Handle duplicates - Use the
messageIdto deduplicate events - Implement retries - Webhooks may be retried on failure