Webhooks
Get a signed request from Chatvox when a lead is captured, a visitor asks for a person, or a Helpdesk ticket is opened.
A webhook is a URL on your server, or in a tool like Zapier, Make, or n8n. When an event happens, Chatvox sends it a POST request with the details as JSON.
Add a webhook
Open API & webhooks
Go to Team settings. Next to API & webhooks, select Manage, then Add webhook.
Enter your endpoint
Enter the URL that receives events. It must use https:// and be reachable from the internet.
Choose the agent
- All agents: events from every agent in the team, including agents you create later.
- One agent: only that agent’s events. Use this to send each agent’s events somewhere different, for example Agent A’s leads to Zapier and Agent B’s to n8n.
Choose events
Tick the events you want to receive.
Save the signing secret
After you save, Chatvox shows the webhook’s signing secret once. It starts with whsec_. Store it on your server and use it to verify requests.
Send a test event
Open the webhook’s … menu and select Send test event. Then open Deliveries to check that your endpoint answered.
You can add as many webhooks as you need. An event goes to every active webhook that’s subscribed to it and covers that agent.
Events
| Event | Sent when | data contains |
|---|---|---|
lead.created |
An agent captures a new lead. | lead |
lead.updated |
A lead gets new details later in the same conversation. | lead |
conversation.handoff_requested |
A visitor or the agent asks for a person (website, Public Chat, or WhatsApp). | conversation, reason, summary |
helpdesk_ticket.opened |
A new Helpdesk ticket is opened. | ticket |
webhook.test |
You select Send test event on an active webhook. Always sent, whatever events you chose. | message |
Payload
Every request has the same envelope:
| Field | Description |
|---|---|
id |
A unique ID for this event. Same as the webhook-id header. |
type |
The event name, such as lead.created. |
created_at |
When the event happened. |
team_id |
Your team’s ID. |
agent_id |
The agent the event came from. For test events, the webhook’s agent, or null for an All agents webhook. |
data |
The event’s details. |
lead.created and lead.updated
data.lead is a lead object.
{
"id": "4b1b9e0e-2f6c-4a7e-9c55-0a2f6c1d9e10",
"type": "lead.created",
"created_at": "2026-10-09T18:40:12+00:00",
"team_id": "019c83c8-fc1b-705b-ae7c-64ca1e3c7158",
"agent_id": "019f80ad-e549-712d-bc26-3ab29ae2228c",
"data": {
"lead": {
"id": "01a12267-9e4a-73b6-8619-2bb0cdda7ba2",
"agent_id": "019f80ad-e549-712d-bc26-3ab29ae2228c",
"conversation_id": "01a12260-2b5c-7d41-9f0e-6a1f2c9b8e11",
"name": "Ada Lovelace",
"email": "ada@example.com",
"phone": "+1 555 0100",
"notes": null,
"custom_fields": { "company": "Analytical Engines Ltd" },
"source": "embed",
"referrer_url": "https://example.com/pricing",
"utm": { "utm_source": "google", "utm_campaign": "spring_sale" },
"created_at": "2026-10-09T18:40:12+00:00",
"updated_at": "2026-10-09T18:40:12+00:00"
}
}
}
conversation.handoff_requested
data.conversation is a conversation object without messages. reason and summary explain why a person was requested, when available.
{
"id": "…",
"type": "conversation.handoff_requested",
"created_at": "2026-10-09T19:58:02+00:00",
"team_id": "…",
"agent_id": "…",
"data": {
"conversation": { "id": "…", "state": "handoff_requested", "source": "public_link", "…": "…" },
"reason": "The customer wants to change their billing address.",
"summary": "Customer on the Pro plan asking to update billing details."
}
}
helpdesk_ticket.opened
data.ticket field |
Description |
|---|---|
id |
The ticket’s ID. |
case_reference |
The reference shown in the Helpdesk, such as HD-0E9NEGBM. |
agent_id |
The agent the ticket came from. |
conversation_id |
The conversation it belongs to. |
channel |
embed, public_link, or whatsapp. |
status |
new for a new ticket. |
requester_name |
The customer’s name, if known. |
subject |
The ticket’s subject. |
summary |
A short summary of the request. |
created_at |
When it was opened. |
Delivery and retries
- Success: your endpoint must answer with any
2xxstatus within 10 seconds. Do slow work, like calling other APIs, after you respond. - Retries: any other status, a timeout, or a connection error is retried after 1 minute, 5 minutes, 30 minutes, 2 hours, and 6 hours. After 6 attempts the delivery is marked Failed.
- Redirects aren’t followed. Use your endpoint’s final URL.
- Duplicates: the same event can arrive more than once, for example if your server timed out after processing it. Use the payload
id(or thewebhook-idheader) to skip events you’ve already handled. - Order: events aren’t guaranteed to arrive in order. Use
created_atif order matters.
Delivery history
Select Deliveries on a webhook to see its 10 most recent deliveries: the event, whether it was Delivered, is Retrying, or Failed, the HTTP status your endpoint returned, and any error. Delivery history is kept for 30 days.
Manage webhooks
From the webhook’s … menu you can:
- Edit the URL, agent, and events, or turn the webhook off without deleting it.
- Send test event to check your endpoint. Turn a webhook on before testing it.
- Rotate signing secret if the secret may have leaked. The old secret stops working immediately, so update your endpoint right away.
- Delete the webhook.
Changes to webhooks are recorded in your team’s activity log.
Requirements
- Your endpoint must use HTTPS and resolve to a public IP address. Addresses on private networks, such as
localhostor192.168.x.x, are rejected. To test locally, use a tunnel such as ngrok or Cloudflare Tunnel. - Webhooks stop sending if your team’s plan drops below Standard or billing is suspended.