Webhooks Overview
Webhooks enable real-time notifications when events occur in your Leezy account. Instead of polling the API, webhooks push data to your application as it happens.
How Webhooks Work
┌───────────┐ ┌───────────┐ ┌───────────┐
│ Visitor │ │ Leezy │ │ Your App │
└─────┬─────┘ └─────┬─────┘ └─────┬─────┘
│ Chat message │ │
│────────────────────>│ │
│ │ │
│ │ Lead created │
│ │ (event triggered) │
│ │ │
│ │ POST webhook │
│ │────────────────────>│
│ │ │
│ │ 200 OK │
│ │<────────────────────│
- An event occurs (lead created, ticket opened, etc.)
- Leezy finds matching webhook subscriptions
- Leezy sends HTTP POST to your endpoint
- Your server responds with 2xx status code
Webhook Payload
Every webhook delivery includes:
{
"id": "evt_abc123xyz789",
"type": "lead.created",
"created_at": "2024-01-15T10:30:00Z",
"organization_id": "org_xyz789",
"chatbot_id": "chatbot_abc123",
"data": {
"id": "lead_def456",
"contact": {
"name": "John Doe",
"email": "john@example.com"
},
"qualification": {
"score": 85,
"qualified": true
}
}
}
| Field | Type | Description |
|---|---|---|
id | string | Unique event identifier |
type | string | Event type (e.g., lead.created) |
created_at | ISO 8601 | When the event occurred |
organization_id | string | Your organization ID |
chatbot_id | string | Related chatbot (if applicable) |
data | object | Event-specific payload |
Webhook Headers
Each webhook request includes these headers:
| Header | Description | Example |
|---|---|---|
X-Leezy-Signature | HMAC-SHA256 signature | sha256=abc123... |
X-Leezy-Timestamp | Unix timestamp (seconds) | 1705316400 |
X-Leezy-Event | Event type | lead.created |
X-Leezy-Delivery | Delivery log ID | del_xyz789 |
Content-Type | Always JSON | application/json |
User-Agent | Leezy identifier | Leezy-Webhook/1.0 |
Delivery Behavior
Success Criteria
A delivery is successful when your endpoint returns:
- HTTP status code
2xx(200, 201, 202, etc.) - Response within 30 seconds
Retry Policy
Failed deliveries are retried with exponential backoff:
| Attempt | Delay | Total Time |
|---|---|---|
| 1 | Immediate | 0 |
| 2 | 30 seconds | 30s |
| 3 | 1 minute | 1m 30s |
| 4 | 2 minutes | 3m 30s |
| 5 | 4 minutes | 7m 30s |
| 6 (final) | 8 minutes | 15m 30s |
After 5 failed retry attempts, the delivery is marked as failed.
Subscription Pausing
If 5 different webhook deliveries fail consecutively, the subscription is automatically paused (status: failed). This prevents repeated failures and protects your endpoint.
To resume a paused subscription, create a new subscription with the same configuration.
Best Practices
Respond Quickly
Process webhooks asynchronously to respond within 30 seconds:
app.post('/webhooks/leezy', async (req, res) => {
// Respond immediately
res.status(200).send('OK');
// Process asynchronously
processWebhook(req.body).catch(console.error);
});
Verify Signatures
Always verify webhook signatures to ensure requests come from Leezy.
Handle Duplicates
Webhooks may be delivered more than once. Use the id field to deduplicate:
const processedEvents = new Set();
function handleWebhook(payload) {
if (processedEvents.has(payload.id)) {
return; // Already processed
}
processedEvents.add(payload.id);
// Process event...
}
Use HTTPS
Webhook endpoints must use HTTPS in production for security.
Filtering by Chatbot
Optionally filter webhooks to specific chatbots:
curl -X POST "https://app.leezy.ai/api/v1/webhooks/subscribe" \
-H "Authorization: Bearer lzy_at_your_token" \
-d '{
"target_url": "https://yourapp.com/webhooks",
"event_types": ["lead.created"],
"filters": {
"chatbot_id": "chatbot_abc123"
}
}'
Without filters, you receive events from all chatbots.
Monitoring
Track webhook deliveries in your Leezy dashboard:
- Go to Settings > Integrations
- Click on your webhook subscription
- View delivery history and status
Next Steps
- Webhook Security - Verify signatures
- Event Types - All available events
- Webhooks API - Manage subscriptions