Back to Documentation Integrations

Webhooks

Get real-time notifications when conversations, messages, and handoffs happen in ChatMox, and react instantly from your own systems instead of polling the API.

Version 1.0 Last updated 2026-06-12 Production Ready

What problem do webhooks solve?

ChatMox runs as a chat widget on your website. By default, agents work inside the ChatMox dashboard. Webhooks let your other systems react automatically when something important happens - without polling the API.

NeedWithout webhooksWith webhooks
Slack alert on handoffAgent watches inboxSlack message instantly
Zendesk ticket on handoffManual copy-pasteTicket from payload
CRM syncExport or manual entryUpdated on each message
Billing alertsCheck reportsReceive usage.limit_reached

Endpoints vs events

Two different things people often confuse:

Management API (you call ChatMox)

  • GET /webhooks - list webhooks
  • GET /webhooks/events - event types
  • POST /webhooks - register URL + events
  • PUT /webhooks/{id} - update
  • DELETE /webhooks/{id} - remove
  • POST /webhooks/{id}/test - send test payload

Webhook events (ChatMox calls you)

  • conversation.created - A new conversation is started
  • conversation.message.created - A new message is sent
  • conversation.handoff_requested - A visitor requests a human agent
  • conversation.assigned - A conversation is assigned to an agent
  • conversation.closed - A conversation is closed
  • usage.limit_reached - Monthly usage limit is reached
  • webhook.test - test event only

How delivery works

  1. Something happens in ChatMox (e.g. new message).
  2. ChatMox checks your plan and finds webhooks subscribed to that event.
  3. A queued job POSTs JSON to your URL with signed headers.
  4. Your server responds with 2xx within 10 seconds.
  5. Failures retry up to 5 times: 10s → 30s → 60s → 5m → 15m.

Payload format

Every delivery is POST with Content-Type: application/json.

{
  "event": "conversation.message.created",
  "brand_id": "550e8400-e29b-41d4-a716-446655440000",
  "data": {
    "conversation_id": "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
    "session_id": "visitor-abc-123",
    "message_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
    "role": "user",
    "content": "I need help with my order",
    "created_at": "2026-06-11T14:30:00.000000Z"
  },
  "timestamp": "2026-06-11T14:30:01+00:00"
}

Headers

  • X-ChatMox-Event - event name
  • X-ChatMox-Signature - HMAC-SHA256 of raw body using your webhook secret

Verify signature

Compare X-ChatMox-Signature against HMAC-SHA256 of the raw request body (before JSON parsing).

$payload   = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_CHATMOX_SIGNATURE'] ?? '';
$secret    = 'your-webhook-secret-from-create-response';
$expected  = hash_hmac('sha256', $payload, $secret);

if (! hash_equals($expected, $signature)) {
    http_response_code(401);
    exit('Invalid signature');
}

$event = json_decode($payload, true);
// Process $event['event'] and $event['data']
http_response_code(200);
echo 'OK';

Event reference

conversation.createdConversation created

A visitor starts a new chat session.

Use case: Alert sales when someone chats from /pricing.

conversation.message.createdNew message

User, bot, or agent sends a message (not internal notes).

Use case: Sync messages to HubSpot or run sentiment analysis.

conversation.handoff_requestedHuman handoff requested

Visitor asks for a human agent.

Use case: Create a Zendesk ticket or page on-call engineers.

conversation.assignedConversation assigned

An agent is assigned from the inbox.

Use case: Track workload or email the customer who is helping them.

conversation.closedConversation closed

Conversation is closed (optionally with CSAT).

Use case: Send ratings to analytics or resolve external tickets.

usage.limit_reachedUsage limit reached

Monthly message allowance is exhausted.

Use case: Trigger billing automation or internal ops alerts.

FAQ

Why not one generic webhook?
Different integrations need different data at different times. Separate events reduce noise and keep payloads focused.
Can I use one URL for all events?
Yes. Subscribe to all six events and switch on the event field in your handler.
Are internal agent notes included?
No. Internal notes are excluded from conversation.message.created.
What if my server is down?
Deliveries retry 5 times with backoff. Attempts are logged for debugging.
Which plans include webhooks?
Growth and Enterprise by default. Free and Starter return 403 when managing webhooks.

Want alerts in Slack, Teams, or Discord too?

See the full CRM & Platform Integration Guide for Slack, Teams, Discord, email, and the Insights API.

View Integration Guide