Webhook integration
Overview
The Webhook integration sends conversation events from AtomicX Chat to your own system as they happen. Use it to feed a CRM or ticketing tool that has no built-in integration, trigger an automation (for example, in Make or n8n; for Zapier, the Zapier integration is easier), or keep your own records of every chat.
AtomicX Chat sends an HTTPS request with a JSON body to a URL you choose when:
| Event | eventType |
When it's sent |
|---|---|---|
| New conversation | conversation.started |
A visitor starts a conversation, on the website widget or on any connected channel. |
| Transferred to a person | conversation.transferred |
The conversation is handed off to a human, either by a workflow handoff node or when a teammate clicks Take Over (in the Admin console or Slack). |
| Conversation ended | conversation.completed |
The conversation is completed, closed by a teammate, or abandoned because of inactivity. The status field tells you which. |
Events are sent when the change happens, not repeated for the same state. For example, clicking Take Over on a conversation that's already with a person sends nothing new. If a teammate hands the conversation back to the bot and it's taken over again later, a new conversation.transferred event is sent.
Before you start, you need:
- The Owner or Admin role in AtomicX Chat.
- An HTTPS endpoint that can receive requests from the internet. It must use
https://and have a public address. Addresses on private or local networks (such aslocalhost,10.x.x.xor192.168.x.x) are blocked.
Steps
Step 1: Prepare your endpoint
Your endpoint must:
- Accept a
POST(orPUT, if you choose it in Step 3) request with a JSON body. - Reply with any 2xx status code, such as
200 OKor204 No Content, within the timeout you set (30 seconds by default). Any other status, a redirect, or no reply in time counts as a failed delivery and is retried. - Check the authentication header you'll set up in Step 3, and reject requests without it.
If you just want to see what the requests look like, you can use a free request inspector such as webhook.site as a temporary endpoint.
Step 2: Open the Webhook settings
- Click Settings in the sidebar and open the Integrations tab.
- On the Webhook card, click Connect. If you've set it up before, click Configure (or Reconfigure).
Step 3: Fill in the settings
Under Webhook Settings:
- Webhook URL: your endpoint, for example
https://api.example.com/atomicx/events. - HTTP Method: POST (the usual choice) or PUT.
- Timeout (seconds): how long AtomicX Chat waits for your reply, from 5 to 300 seconds. Keep your endpoint fast, and do any slow work after replying.
Under Authentication, choose how your endpoint recognizes AtomicX Chat:
| Authentication Type | Header sent | What to enter in Authentication Value |
|---|---|---|
| None | No header | Leave empty. Only use this for testing. |
| Bearer Token | Authorization: Bearer <value> |
A long random secret that your endpoint checks. |
| API Key | X-API-Key: <value> |
Your API key. |
| Basic Auth | Authorization: Basic <value> |
username:password encoded in Base64. For example, atomicx:s3cret becomes YXRvbWljeDpzM2NyZXQ=. |
Under Custom Headers, click Add Header to send any other fixed headers your endpoint needs, such as X-Source: atomicx-chat.
Under Event Settings, tick the events you want:
- New conversations started sends
conversation.started. - Conversations completed sends
conversation.completed. - Conversations transferred to human sends
conversation.transferred.
Then choose what to include in each event:
- Include conversation metadata: the visitor's name, email and phone number, the answers your workflow collected, the page the chat started on, and the chat configuration and workflow IDs.
- Include user data (IP, User Agent): the visitor's IP address and browser details.
- Include message history: the full transcript at the time of the event. This is most useful on
conversation.completed.
Only include the data your system actually needs. Contact details, IP addresses and transcripts are personal data.
Step 4: Test and save
- Click Test Webhook. AtomicX Chat sends a test request to your endpoint:
{ "eventType": "test", "message": "Test webhook from AtomicX Chat - Integration is working correctly!", "timestamp": "2026-09-28T14:03:11.52Z" } - If you see Test webhook sent successfully!, your endpoint replied with a 2xx status. If you see Test failed, see Troubleshooting.
- Click Save Configuration. The Webhook card now shows Connected, and events start flowing right away.
You can re-run the test at any time with the Test button on the card.
Step 5: Check a real event
- Start a conversation using the test chat or your website. See Test your chat.
- Your endpoint should receive a
conversation.startedevent within a few seconds. - End the conversation and check for
conversation.completed.
What your endpoint receives
Every event has the same outer shape. Header: Content-Type: application/json; charset=utf-8, plus any authentication and custom headers you set.
{
"eventType": "conversation.completed",
"tenantId": "8c1f0e4e-3a7b-4c1d-9a55-2f0d6c1b7e10",
"timestamp": "2026-09-28T14:05:42.118Z",
"data": {
"conversationId": "5d2b9f7a-61c4-4e0e-b3f8-0a9e2c7d4b21",
"sessionId": "c6f0a1d2e3",
"status": "Completed",
"isHandedOffToHuman": false,
"createdAt": "2026-09-28T14:01:02.004Z",
"updatedAt": "2026-09-28T14:05:41.870Z",
"chatConfigurationId": "0f3e2d1c-9b8a-4f7e-8d6c-5b4a39281706",
"workflowId": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
"referrerUrl": "https://www.example.com/pricing",
"userName": "Ann Lee",
"userEmail": "ann@example.com",
"userPhone": "+15551234567",
"collectedData": { "budget": "2000-2500", "moveInDate": "2026-11-01" },
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_5) ...",
"ipAddress": "203.0.113.24",
"messages": [
{ "sender": "Bot", "senderName": null, "content": "Hi! How can I help?", "createdAt": "2026-09-28T14:01:02.310Z" },
{ "sender": "User", "senderName": "Ann Lee", "content": "Do you have 2-bedroom units?", "createdAt": "2026-09-28T14:01:15.922Z" }
]
}
}
| Field | Always sent? | Description |
|---|---|---|
eventType |
Yes | conversation.started, conversation.transferred or conversation.completed. |
tenantId |
Yes | Your AtomicX Chat account ID. |
timestamp |
Yes | When the request was sent, in UTC. A retried event has a later timestamp. |
data.conversationId |
Yes | The conversation's ID. Use it to link events for the same conversation. |
data.sessionId |
Yes | The visitor's widget session ID. Can be null for channel conversations. |
data.status |
Yes | Active, HandedOff, Completed, Closed (ended by a teammate) or Abandoned (ended by inactivity). |
data.isHandedOffToHuman |
Yes | true once a person has taken over. |
data.createdAt, data.updatedAt |
Yes | When the conversation started and was last changed, in UTC. |
chatConfigurationId to collectedData |
With Include conversation metadata | Contact and workflow details. Any field the visitor didn't provide is null. collectedData holds each workflow answer by its data key. |
userAgent, ipAddress |
With Include user data | The visitor's browser and IP address. |
messages |
With Include message history | Every message so far, oldest first. sender is User, Bot, Admin (a teammate) or System. |
The data describes the conversation at the moment the request is sent. So if a conversation ends a second after it starts, the conversation.started event may already show "status": "Completed". Use eventType, not status, to decide what happened.
Failed deliveries and retries
If your endpoint doesn't reply with a 2xx status in time, AtomicX Chat tries again about 1 minute later. If that also fails, it keeps retrying after about 1 minute, 5 minutes, 30 minutes and 2 hours. After 5 retries (roughly 2.5 hours after the event), the event is dropped.
Because of retries, your endpoint can receive the same event more than once, for example when it saved the event but replied too slowly. Make your endpoint safe to call twice: treat conversationId plus eventType as a unique key and ignore duplicates.
Turn the webhook off or change it
- Stop sending one kind of event: click Configure on the card, untick it under Event Settings, and click Save Configuration.
- Pause everything: click Disconnect on the card. Your settings are kept. Click Enable to start sending again.
- Change the URL or secret: click Configure, update the fields, click Test Webhook, then Save Configuration. Events already waiting to be retried use the new settings.
Troubleshooting
| Problem | What to do |
|---|---|
| Test failed | Check that the URL starts with https:// and is reachable from the internet, that your endpoint returns a 2xx status (not a redirect), and that the authentication value matches what your endpoint expects. |
| The test works but no events arrive | Make sure the card shows Connected (not Configured), and that the events you want are ticked under Event Settings. |
401 or 403 from your endpoint |
The authentication value doesn't match. For Basic Auth, enter the Base64-encoded username:password, not the plain text. |
| Your endpoint is on your own network | Addresses on private or local networks are blocked for security. Put the endpoint behind a public HTTPS address, such as an API gateway or a tunnel. |
| Duplicate events | This is expected after a slow reply or a retry. Ignore events whose conversationId and eventType you've already processed. |
Contact fields are null |
Turn on Include conversation metadata, and make sure your workflow asks for the name, email or phone number. See Workflow node types. |