Webhook Events
Real-time notifications for your integrations. Available on Scale plan.
How Webhooks Work
- 1Register your endpoint URL via
POST /api/v1/webhooks - 2Events are sent as POST requests with JSON body
- 3Verify the
X-Oxaide-Signatureheader using HMAC-SHA256 - 4Return 2xx status to acknowledge receipt (retries on failure)
Signature Verification
Always verify webhook signatures to ensure events are from Oxaide:
// Node.js example
const crypto = require('crypto');
function verifyWebhook(payload, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(payload, 'utf8')
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from('sha256=' + expected)
);
}Event Types
conversation.created
Fired when a new conversation is started via API, widget, or messaging channel.
{
"id": "evt_1234567890",
"type": "conversation.created",
"created_at": "2025-12-14T10:30:00Z",
"data": {
"id": "conv_abc123def456",
"object": "conversation",
"agent_id": "123",
"source": "widget",
"customer": {
"external_id": "cust_001",
"email": "customer@example.com",
"name": "John Doe"
},
"metadata": {
"page_url": "https://example.com/pricing"
},
"created_at": "2025-12-14T10:30:00Z"
}
}conversation.ended
Fired when a conversation is marked as closed or resolved.
{
"id": "evt_1234567891",
"type": "conversation.ended",
"created_at": "2025-12-14T10:45:00Z",
"data": {
"id": "conv_abc123def456",
"object": "conversation",
"agent_id": "123",
"resolution": "resolved",
"message_count": 8,
"duration_seconds": 900,
"ended_at": "2025-12-14T10:45:00Z"
}
}conversation.escalated
Fired when the AI escalates a conversation to a human agent.
{
"id": "evt_1234567892",
"type": "conversation.escalated",
"created_at": "2025-12-14T10:35:00Z",
"data": {
"id": "conv_abc123def456",
"object": "conversation",
"agent_id": "123",
"reason": "customer_request",
"last_message": "I need to speak with a human please",
"customer": {
"email": "customer@example.com",
"name": "John Doe"
},
"escalated_at": "2025-12-14T10:35:00Z"
}
}message.created
Fired when a new message is sent (both user and AI messages).
{
"id": "evt_1234567893",
"type": "message.created",
"created_at": "2025-12-14T10:32:00Z",
"data": {
"id": "msg_xyz789",
"object": "message",
"conversation_id": "conv_abc123def456",
"agent_id": "123",
"role": "assistant",
"content": "Of course! Our business hours are Monday to Friday, 9 AM to 6 PM EST.",
"user_message": {
"id": "msg_xyz788",
"content": "What are your business hours?"
},
"created_at": "2025-12-14T10:32:00Z"
}
}message.received
Fired when a message is received from a customer (before AI processes it).
{
"id": "evt_1234567894",
"type": "message.received",
"created_at": "2025-12-14T10:31:00Z",
"data": {
"id": "msg_xyz788",
"object": "message",
"conversation_id": "conv_abc123def456",
"agent_id": "123",
"role": "user",
"content": "What are your business hours?",
"source": "widget",
"customer": {
"email": "customer@example.com"
},
"created_at": "2025-12-14T10:31:00Z"
}
}lead.captured
Fired when the AI captures contact information from a customer.
{
"id": "evt_1234567895",
"type": "lead.captured",
"created_at": "2025-12-14T10:33:00Z",
"data": {
"id": "lead_abc123",
"object": "lead",
"conversation_id": "conv_abc123def456",
"agent_id": "123",
"email": "prospect@example.com",
"name": "Jane Smith",
"phone": "+1234567890",
"company": "Acme Inc",
"source": "widget",
"custom_fields": {
"company_size": "50-100",
"industry": "Technology"
},
"created_at": "2025-12-14T10:33:00Z"
}
}Retry Policy
Failed webhook deliveries are retried with exponential backoff:
1 min
1st retry
5 min
2nd retry
30 min
3rd retry
2 hrs
Final retry
After 5 consecutive failures, the webhook is automatically disabled. Re-enable from the console.