Overview
Webhooks let you receive real-time HTTP POST notifications when events happen in InboundFlow — a call completes, an appointment is booked, a lead is created, or a call is transferred. Use webhooks to sync data to your CRM, send Slack notifications, update spreadsheets, or trigger any custom workflow.
Supported Integrations
Setup
Go to your InboundFlow dashboard → Settings → Integrations
Click "Connect" on Zapier, Make, or Custom Webhook
Paste your webhook URL (must be HTTPS)
Select which events to receive
Click "Test Webhook" to verify
Save
Event Types
| Event | Trigger | Description |
|---|---|---|
| call.completed | Every completed call | Fires after a call ends with summary, transcript, and caller info |
| call.transferred | Call forwarded to human | Fires when the AI transfers a call to a configured destination |
| appointment.booked | Calendar booking made | Fires when the AI books a calendar appointment during a call |
| lead.created | New lead captured | Fires when a new lead is created from a call with sufficient context |
Delivery Format
All webhook deliveries are HTTP POST requests with JSON body:
Headers
Content-Type: application/json
X-InboundFlow-Event: call.completed
X-InboundFlow-Delivery-Id: unique-uuid
X-InboundFlow-Timestamp: 1709064000
User-Agent: InboundFlow-Webhook/1.0
If you configured a signing secret:
X-InboundFlow-Signature: sha256=abc123...
Event Payloads
call.completed
{
"event": "call.completed",
"timestamp": "2026-02-24T21:00:00.000Z",
"organization_id": "uuid",
"delivery_id": "unique-uuid",
"data": {
"call_id": "uuid",
"caller_phone": "+1234567890",
"caller_name": "Dave",
"caller_email": "dave@example.com",
"duration_seconds": 55,
"summary": "Called about auto repair appointment. Customer wants to bring in a 2019 Honda Civic for brake inspection.",
"intent": "book appointment",
"urgency": "medium",
"recording_url": "https://...",
"started_at": "2026-02-24T20:59:00Z",
"ended_at": "2026-02-24T21:00:00Z"
}
}
call.transferred
{
"event": "call.transferred",
"timestamp": "2026-02-24T21:00:00.000Z",
"organization_id": "uuid",
"delivery_id": "unique-uuid",
"data": {
"call_id": "uuid",
"caller_phone": "+1234567890",
"caller_name": "Dave",
"duration_seconds": 47,
"summary": "Caller requested to speak with manager about pricing.",
"transferred_to_label": "Manager",
"transferred_to_number": "+18154264329",
"urgency": "medium",
"reason": "Wants to discuss pricing for full body repair"
}
}
appointment.booked
{
"event": "appointment.booked",
"timestamp": "2026-02-24T21:00:00.000Z",
"organization_id": "uuid",
"delivery_id": "unique-uuid",
"data": {
"call_id": "uuid",
"caller_phone": "+1234567890",
"caller_name": "Sarah",
"appointment_date": "2026-02-25",
"appointment_time_start": "2026-02-25T11:00:00Z",
"appointment_time_end": "2026-02-25T12:00:00Z",
"service_type": "Auto Repair Appointment",
"calendar_event_id": "google_event_id",
"calendar_event_link": "https://calendar.google.com/..."
}
}
lead.created
{
"event": "lead.created",
"timestamp": "2026-02-24T21:00:00.000Z",
"organization_id": "uuid",
"delivery_id": "unique-uuid",
"data": {
"call_id": "uuid",
"caller_phone": "+1234567890",
"caller_name": "Dave",
"caller_email": "dave@example.com",
"intent": "pricing inquiry",
"urgency": "high",
"interest": "auto body work",
"call_summary": "Called about getting a quote for front bumper repair on a 2019 Honda Civic."
}
}
Verifying Webhook Signatures
If you set a signing secret when configuring your webhook, every delivery includes an HMAC-SHA256 signature for verification:
const crypto = require('crypto');
function verifyWebhook(body, timestamp, signature, secret) {
const signatureInput = `${timestamp}.${JSON.stringify(body)}`;
const expectedSignature = 'sha256=' +
crypto.createHmac('sha256', secret)
.update(signatureInput)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
);
}
// In your webhook handler:
const isValid = verifyWebhook(
req.body,
req.headers['x-inboundflow-timestamp'],
req.headers['x-inboundflow-signature'],
'your_signing_secret'
);
Retry & Reliability
- Timeout: Webhooks have a 10-second delivery timeout. Respond with a 2xx status quickly.
- Failure tracking: Failed deliveries are tracked. After 10 consecutive failures, the webhook is automatically disabled.
- Re-enable: If your webhook is auto-disabled, go to Settings → Integrations to reconnect.
- Idempotency: Use the
delivery_idfield to deduplicate events if your handler is called twice.