Webhooks
Receive real-time notifications from DGbot when conversations, handoffs, and leads happen.
Overview
Webhooks let DGbot push events to your server in real time — when a conversation starts, a lead is captured, a handoff is requested, or a conversation ends. This is the primary integration pattern for connecting DGbot to your backend.
Vs. Custom API actions: Custom actions are pull-based — your bot calls your API when needed. Webhooks are push-based — DGbot calls your server when an event occurs, regardless of the conversation flow.
Configure webhooks
The Webhooks configuration. Add an endpoint URL and select which events to receive.
Enter the HTTPS URL of your webhook handler. DGbot will POST to this URL for each selected event.
Choose which events to receive. You can configure separate endpoints for different event types.
DGbot generates a signing secret for each webhook endpoint. Use it to verify that incoming requests are genuine (see Verify signatures below).
Event types
conversation.started — Fires when the first visitor message is sent:
{
"event": "conversation.started",
"conversation_id": "conv_abc123",
"chatbot_id": "bot_xyz",
"visitor_id": "visitor_111",
"timestamp": "2025-05-15T10:30:00Z"
}lead.captured — Fires when the lead form is submitted:
{
"event": "lead.captured",
"conversation_id": "conv_abc123",
"chatbot_id": "bot_xyz",
"lead": {
"name": "Jane Smith",
"email": "jane@example.com",
"captured_at": "2025-05-15T10:32:00Z"
}
}handoff.requested — Fires when a visitor requests a human agent:
{
"event": "handoff.requested",
"conversation_id": "conv_abc123",
"chatbot_id": "bot_xyz",
"visitor_id": "visitor_111",
"timestamp": "2025-05-15T10:35:00Z"
}conversation.resolved — Fires when a conversation is marked resolved:
{
"event": "conversation.resolved",
"conversation_id": "conv_abc123",
"chatbot_id": "bot_xyz",
"resolved_by": "bot",
"duration_seconds": 320,
"timestamp": "2025-05-15T10:40:00Z"
}Verify signatures
DGbot signs every webhook request with your endpoint's signing secret using HMAC-SHA256. Always verify the signature before processing:
import hmac, hashlib
from fastapi import Request, HTTPException
async def verify_webhook(request: Request, secret: str):
signature = request.headers.get("X-DGbot-Signature", "")
body = await request.body()
expected = "sha256=" + hmac.new(
secret.encode(), body, hashlib.sha256
).hexdigest()
if not hmac.compare_digest(expected, signature):
raise HTTPException(status_code=401, detail="Invalid signature")const crypto = require('crypto')
function verifyWebhook(rawBody, signature, secret) {
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(rawBody)
.digest('hex')
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(signature)
)
}Retry policy
DGbot retries failed webhook deliveries (non-200 responses or timeouts) with exponential backoff:
| Attempt | Delay |
|---|---|
| 1st retry | 5 seconds |
| 2nd retry | 30 seconds |
| 3rd retry | 5 minutes |
| 4th retry | 30 minutes |
| 5th retry | 2 hours |
After 5 failed attempts, the webhook is marked as failed and no further retries are made. Failed deliveries are visible in the webhook log in the admin panel.
Design your endpoint to be idempotent — duplicate deliveries can occur if your endpoint returns a success response slowly (after DGbot's 10-second timeout). Use the event ID to deduplicate.