Webhook Payload Format
Every webhook delivery is an HTTP POST request with a JSON body. All payloads follow the same envelope structure regardless of the event type.
Envelope Structure
{
"eventId": "evt_6612a1b2c3d4e5f6a7b8c9d0",
"eventType": "inbox.conversation.created",
"timestamp": "2026-03-24T14:30:00.000Z",
"workspaceId": "ws_5501a1b2c3d4e5f6a7b8c9d0",
"data": {
// Event-specific payload
}
}| Field | Type | Description |
|---|---|---|
eventId | string | Unique identifier for this event delivery (use for deduplication) |
eventType | string | The event type in service.entity.action format |
timestamp | string | ISO 8601 timestamp of when the event occurred |
workspaceId | string | The workspace where the event occurred |
data | object | Event-specific payload (varies by event type) |
HTTP Headers
| Header | Description |
|---|---|
Content-Type | Always application/json |
X-Webhook-Signature | HMAC-SHA256 signature (if signing secret is configured) |
X-Webhook-Event | The event type (same as eventType in body) |
X-Webhook-Delivery-Id | Unique delivery attempt ID |
User-Agent | VelaFlows-Webhook/1.0 |
Example Payloads
Conversation Created
{
"eventId": "evt_6612a1b2c3d4e5f6a7b8c9d0",
"eventType": "inbox.conversation.created",
"timestamp": "2026-03-24T14:30:00.000Z",
"workspaceId": "ws_5501a1b2c3d4e5f6a7b8c9d0",
"data": {
"conversation": {
"_id": "conv_7723b2c3d4e5f6a7b8c9d0e1",
"channel": "whatsapp",
"status": "open",
"priority": "normal",
"contactName": "John Doe",
"contactPhone": "+14155551234",
"assignedAgentId": null,
"createdAt": "2026-03-24T14:30:00.000Z"
}
}
}Message Received
{
"eventId": "evt_7723b2c3d4e5f6a7b8c9d0e1",
"eventType": "inbox.message.received",
"timestamp": "2026-03-24T14:31:00.000Z",
"workspaceId": "ws_5501a1b2c3d4e5f6a7b8c9d0",
"data": {
"conversationId": "conv_7723b2c3d4e5f6a7b8c9d0e1",
"message": {
"_id": "msg_8834c3d4e5f6a7b8c9d0e1f2",
"type": "text",
"text": "Hi, I need help with my order",
"sender": {
"type": "contact",
"name": "John Doe",
"phone": "+14155551234"
},
"channel": "whatsapp",
"timestamp": "2026-03-24T14:31:00.000Z"
}
}
}Lead Stage Changed
{
"eventId": "evt_8834c3d4e5f6a7b8c9d0e1f2",
"eventType": "crm.lead.stage_changed",
"timestamp": "2026-03-24T15:00:00.000Z",
"workspaceId": "ws_5501a1b2c3d4e5f6a7b8c9d0",
"data": {
"lead": {
"_id": "lead_9945d4e5f6a7b8c9d0e1f2g3",
"name": "Acme Corp",
"pipelineId": "pipe_1234567890",
"previousStageId": "stage_qualification",
"newStageId": "stage_proposal",
"movedBy": "member_abcdef123456",
"movedAt": "2026-03-24T15:00:00.000Z"
}
}
}Customer Created
{
"eventId": "evt_9945d4e5f6a7b8c9d0e1f2g3",
"eventType": "customer.created",
"timestamp": "2026-03-24T15:30:00.000Z",
"workspaceId": "ws_5501a1b2c3d4e5f6a7b8c9d0",
"data": {
"customer": {
"_id": "cust_aa56e5f6a7b8c9d0e1f2g3h4",
"firstName": "Jane",
"lastName": "Smith",
"email": "jane@example.com",
"phone": "+14155559876",
"createdAt": "2026-03-24T15:30:00.000Z"
}
}
}Workflow Execution Completed
{
"eventId": "evt_bb67f6a7b8c9d0e1f2g3h4i5",
"eventType": "workflows.execution.completed",
"timestamp": "2026-03-24T16:00:00.000Z",
"workspaceId": "ws_5501a1b2c3d4e5f6a7b8c9d0",
"data": {
"execution": {
"_id": "exec_cc78a7b8c9d0e1f2g3h4i5j6",
"workflowId": "wf_dd89b8c9d0e1f2g3h4i5j6k7",
"workflowName": "Lead Routing",
"trigger": "event",
"status": "completed",
"startedAt": "2026-03-24T15:59:55.000Z",
"completedAt": "2026-03-24T16:00:00.000Z",
"duration": 5000,
"nodesExecuted": 7
}
}
}Data Shapes
The data object varies by event type. Common patterns:
- Entity events (created, updated, deleted) include the full entity object
- Stage/status change events include both
previousandnewvalues - Assignment events include
assignedToandassignedByfields - Relationship events (linked, unlinked, merged) include IDs for both sides
Tips for Handling Payloads
- Always check
eventTypebefore processing thedataobject - Use
eventIdfor deduplication — you may receive the same event more than once during retries - Handle unknown event types gracefully — new events may be added in future API versions
- Store raw payloads for debugging — save the original JSON for at least 7 days