Webhooks
Webhooks let you receive real-time HTTP notifications when events happen in your chatbots. Instead of polling the API, Conferbot pushes data to your endpoint as events occur.
How It Works
- You register a webhook URL and select events to subscribe to.
- When an event occurs, Conferbot sends a
POSTrequest to your URL with a signed JSON payload. - Your server verifies the HMAC-SHA256 signature and processes the event.
- If delivery fails, Conferbot retries up to 3 times with exponential backoff.
Event Types
Subscribe to one or more of the following events:
| Event | Description | Triggered When |
|---|---|---|
response.created | New chatbot response | A visitor submits a response in a chatbot conversation |
response.updated | Response updated | A chatbot response record is modified (e.g., additional data captured) |
conversation.started | Conversation begins | A new chat session is initiated by a visitor |
conversation.completed | Conversation ends | A chat session is marked as complete |
Payload Format
Webhook payloads are sent as JSON in the POST request body. Each payload includes the event type, resource IDs, and a timestamp.
Headers
Every webhook delivery includes these headers:
| Header | Description |
|---|---|
x-webhook-signature | HMAC-SHA256 hex digest of the request body using your webhook secret |
x-webhook-event | The event type (e.g., response.created) |
x-webhook-timestamp | ISO 8601 timestamp of when the event was dispatched |
Content-Type | application/json |
User-Agent | Conferbot-Webhooks/1.0 |
Example payload — response.created
{
"event": "response.created",
"chatSessionId": "sess_abc123def456",
"responseId": "65a1b2c3d4e5f6a7b8c9d0e1",
"botId": "64f8a2b3c1d4e5f6a7b8c9d0",
"visitorId": "visitor_xyz789",
"timestamp": "2024-12-15T09:30:00.000Z"
}Example payload — response.updated
{
"event": "response.updated",
"responseId": "65a1b2c3d4e5f6a7b8c9d0e1",
"botId": "64f8a2b3c1d4e5f6a7b8c9d0",
"chatSessionId": "sess_abc123def456",
"timestamp": "2024-12-15T09:35:00.000Z"
}Example payload — conversation.started
{
"event": "conversation.started",
"chatSessionId": "sess_abc123def456",
"botId": "64f8a2b3c1d4e5f6a7b8c9d0",
"chatbotName": "Support Bot",
"visitorId": "visitor_xyz789",
"channel": "web",
"timestamp": "2024-12-15T09:30:00.000Z"
}Example payload — conversation.completed
{
"event": "conversation.completed",
"chatSessionId": "sess_abc123def456",
"botId": "64f8a2b3c1d4e5f6a7b8c9d0",
"reason": "escalated",
"timestamp": "2024-12-15T10:00:00.000Z"
}Payload fields
conversation.completedincludes areasonfield:"escalated"(handed off to agent) or"completed"(ended normally).conversation.startedincludes thechannel(web,whatsapp, etc.) and thechatbotName.
Signature Verification
Every webhook delivery is signed with your webhook's secret using HMAC-SHA256. Always verify the signature before processing the payload to ensure it came from Conferbot and hasn't been tampered with.
Verification steps
- Read the raw request body (before JSON parsing).
- Compute the HMAC-SHA256 hex digest using your webhook secret as the key.
- Compare it to the
x-webhook-signatureheader value. - Use timing-safe comparison to prevent timing attacks.
const crypto = require("crypto");
// Use raw body parser for webhook routes
app.post("/webhook", express.raw({ type: "application/json" }), (req, res) => {
const signature = req.headers["x-webhook-signature"];
const event = req.headers["x-webhook-event"];
// Compute expected signature
const expected = crypto
.createHmac("sha256", WEBHOOK_SECRET)
.update(req.body) // raw Buffer
.digest("hex");
// Timing-safe comparison
const isValid = crypto.timingSafeEqual(
Buffer.from(signature, "hex"),
Buffer.from(expected, "hex")
);
if (!isValid) {
return res.status(401).send("Invalid signature");
}
// Parse and process the event
const payload = JSON.parse(req.body);
console.log(`Received ${event}:`, payload);
// Respond with 200 to acknowledge receipt
res.status(200).send("OK");
});Never skip verification
Always verify the x-webhook-signature header. Without verification, anyone can send fake events to your endpoint. Use timing-safe comparison to prevent timing attacks.
Retries & Failure Handling
If your endpoint doesn't respond with a 2xx status code within 10 seconds, Conferbot considers the delivery failed and retries:
| Attempt | Delay | Notes |
|---|---|---|
| 1st retry | 30 seconds | First automatic retry |
| 2nd retry | 2 minutes | Second retry with longer delay |
| 3rd retry | 8 minutes | Final retry attempt |
Auto-disable
If a webhook accumulates 10 consecutive failures, it is automatically set to failed status and stops receiving events. You can reactivate it from the dashboard or API after fixing the issue.
Best practices
Respond with 200 OK immediately and process the event asynchronously. This prevents timeouts when your processing takes more than 10 seconds.
Delivery logs
Every delivery attempt is logged with status code, response time, and error details. Logs are retained for 30 days and viewable in the dashboard at Workspace → Webhooks. The External API does not currently expose a delivery-log endpoint.
Webhook Management API
Create, update, and delete webhooks programmatically. All endpoints require an x-api-key header.
Create Webhook
Target URL must be https://. We reject http://,javascript:, file:, localhost, and any private / loopback / link-local IP (defense in depth against SSRF).
POST /api/v1/external/v1/webhooks
Content-Type: application/json
{
"chatbotId": "64f8a2b3c1d4e5f6a7b8c9d0",
"url": "https://example.com/webhook",
"events": ["response.created", "conversation.completed"],
"description": "CRM integration"
}{
"data": {
"id": "65b2c3d4e5f6a7b8c9d0e1f2",
"chatbot": { "id": "64f8a2b3c1d4e5f6a7b8c9d0", "name": null },
"url": "https://example.com/webhook",
"events": ["response.created", "conversation.completed"],
"description": "CRM integration",
"status": "active",
"failureCount": 0,
"lastDeliveryAt": null,
"lastFailureAt": null,
"createdAt": "2025-01-15T09:30:00.000Z",
"updatedAt": "2025-01-15T09:30:00.000Z",
"secret": "a1b2c3d4...64-char-hex-string"
},
"message": "Save the secret — it won't be shown again."
}Save your secret
The secret is returned only at creation time. Copy it immediately. If lost, delete the webhook and create a new one — there is no rotate-in-place endpoint on the External API.
List Webhooks
GET /api/v1/external/v1/webhooksUpdate Webhook
Partial update. The signing secret is preserved across all fields you change. Allowed fields: url, events, description, and status (active ↔ paused).
PATCH /api/v1/external/v1/webhooks/:webhookId
Content-Type: application/json
{
"url": "https://new-endpoint.example.com/hook",
"events": ["response.created"],
"status": "paused",
"description": "Updated integration"
}Delete Webhook
Deleting the parent chatbot also deletes all of its webhooks (cascade), so you usually don't need to call this explicitly when retiring a bot.
DELETE /api/v1/external/v1/webhooks/:webhookIdWebhook Status
| Status | Description |
|---|---|
active | Receiving events normally |
paused | Manually paused by admin — no events delivered |
failed | Auto-disabled after 10 consecutive failures. Reactivate from the dashboard or API. |
Plan Limits
| Plan | Max Webhooks |
|---|---|
| Free | No webhook access |
| Starter | 5 |
| Pro | 15 |
| Business | 50 |
| Enterprise | Unlimited |
Testing Webhooks
Use a service like webhook.site or RequestBin to test webhooks without setting up your own server:
- Go to webhook.site and copy your unique URL.
- Create a webhook in your Conferbot dashboard using that URL.
- Trigger an event (e.g., submit a chatbot response).
- Check webhook.site to see the payload and headers.