API and webhooks
For developers connecting Chatterbell to their own software.
At a glance
- Webhooks (Team and Business plans): we send your system a signed message the moment a chat starts, a message arrives, a customer needs a person, and more.
- API: on the Team plan, read chats and connect Zapier; on the Business plan, also reply, add private notes, close, reopen and pass chats to someone.
- Set both up in your inbox under Integrations. Only owners and admins can.
API keys
Create a key in Integrations → API. It looks like cb_ followed by 40 letters and numbers, and it’s shown once, so keep it somewhere safe. Send it with every request:
Authorization: Bearer cb_your_key_here
A key works for one business. Replies you send through the API show the name of the person who created the key, just as if they’d typed it. A key stops working if you delete it, if that person leaves the team, or if the business moves to a plan without the API. On the Team plan a key can use the GET requests and hooks below; the POST requests that change chats need the Business plan.
Each key can make 120 requests a minute. Everything is JSON, and times are ISO 8601 in UTC.
Endpoints
All addresses start with https://chatterbell.com/api/v1.
| Request | What it does |
|---|---|
GET /business | Your business’s name, website, plan, and whether anyone is available to chat. |
GET /team | Everyone on the team: id, name customers see, email, role, available, online. |
GET /conversations | Chats, newest activity first. status = open (default), closed or all; limit up to 100 (default 25); before = the next value from the previous page. |
GET /conversations/{id} | One chat with all its messages, including private notes (marked "private": true). |
POST /conversations/{id}/messages | Reply to the customer: {"text": "…"}. Add "private": true for a note only your team sees. |
POST /conversations/{id}/close | Close the chat. |
POST /conversations/{id}/reopen | Reopen it. |
POST /conversations/{id}/assign | Give it to someone: {"email": "sam@yourbusiness.co.uk"} or {"userId": "…"}. Send {} to unassign. |
POST /hooks | Subscribe an address to one event (REST hooks, as Zapier uses): {"url": "https://…", "event": "conversation.started"}. Returns {"id": "…"}. |
DELETE /hooks/{id} | Unsubscribe it. |
Example: reply to a chat
curl https://chatterbell.com/api/v1/conversations/CONVERSATION_ID/messages \
-H "Authorization: Bearer cb_your_key_here" \
-H "Content-Type: application/json" \
-d '{"text": "Your order has shipped and should arrive tomorrow."}'
A conversation
{
"id": "k3Yp9QwErT2aZx1L",
"status": "open",
"channel": "web",
"needsHuman": false,
"createdAt": "2026-10-01T09:14:03.000Z",
"lastMessageAt": "2026-10-01T09:15:40.000Z",
"assignee": { "id": "…", "name": "Sam", "email": "sam@yourbusiness.co.uk" },
"visitor": { "id": "…", "name": "Priya", "email": "priya@example.com", "phone": null,
"page": "https://yourbusiness.co.uk/booking", "pageTitle": "Book a visit", "country": "GB" },
"link": "https://chatterbell.com/app/…/c/k3Yp9QwErT2aZx1L"
}
A message
{
"id": "…",
"conversationId": "k3Yp9QwErT2aZx1L",
"author": "visitor", // visitor, agent, ai or system
"authorName": null,
"text": "Do you have anything on Saturday?",
"private": false,
"files": [],
"createdAt": "2026-10-01T09:15:40.000Z"
}
Errors
Errors come back with a normal HTTP status and {"error": "A sentence explaining what went wrong."}: 400 something in the request needs fixing, 401 missing or invalid key, 402 the business’s plan doesn’t include the API, 404 not found, 429 too many requests, so wait a moment.
Webhooks
Add a webhook in Integrations → Webhooks: give us an https:// address and choose what you want to hear about. When it happens we send a POST with a JSON body like this:
{
"id": "evt_8sJk2…",
"type": "message.created",
"created": "2026-10-01T09:15:40.512Z",
"business": { "id": "…", "name": "Wagtail Grooming" },
"data": { "conversation": { … }, "message": { … } }
}
| Event | When | data |
|---|---|---|
conversation.started | A customer starts a new chat. | conversation |
message.created | A customer, your team or the AI sends a message. Private notes are never sent. | conversation, message |
conversation.needs_human | A customer asks for a person, or the AI can’t answer. | conversation |
conversation.assigned | A chat is given to someone, by a person, by routing or through the API. | conversation |
conversation.closed | A chat is closed. | conversation |
conversation.reopened | A closed chat is reopened by your team. | conversation |
visitor.contact | A customer leaves their email address or name. | conversation |
Answer with any 2xx status within 10 seconds. If we don’t get one, we try again after 1 minute and again after 10 minutes. After 15 failures in a row we switch the webhook off and show it in Integrations, where you can turn it back on. The Send a test event button sends a test event straight away and shows what your address answered.
Checking it came from us
Every request has a Chatterbell-Signature header: t=1790848000,v1=5f3c…. v1 is an HMAC-SHA256, using your webhook’s signing secret (it starts whsec_), of the time t, a full stop, and the exact body we sent. Check it, and ignore anything more than 5 minutes old:
const crypto = require('crypto');
function fromChatterbell(rawBody, header, secret) {
const t = /t=(\d+)/.exec(header)?.[1], sig = /v1=([0-9a-f]+)/.exec(header)?.[1];
if (!t || !sig || Math.abs(Date.now() / 1000 - Number(t)) > 300) return false;
const want = crypto.createHmac('sha256', secret).update(`${t}.${rawBody}`).digest('hex');
return sig.length === want.length && crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(want));
}
Use the raw body exactly as it arrived, before parsing the JSON. The same event can occasionally arrive twice, so use its id to ignore repeats.
Zapier, Make and n8n
Chatterbell has its own Zapier app. In your inbox, open Integrations → Zapier and follow the link, then connect it with an API key. Triggers (new chat, new message, a customer needs a person, contact details left, chat assigned, chat closed) work on the Team plan; the actions (reply, close, assign) need the Business plan.
For Make, use its “Custom webhook” module, and for n8n its “Webhook” node: copy the address they give you into a new Chatterbell webhook.
Help
Stuck, or need something the API doesn’t do yet? Email hello@chatterbell.com and tell us what you’re building.