Everything that happens,
pushed to your systems

16 events. Signed with HMAC-SHA256. Retried on failure. Your CRM, data warehouse and ops tooling stay in sync without polling.

Setup

Dashboard → Integrations → Add Webhook. Give us your HTTPS endpoint, pick the events you want (or all), and we generate a signing secret. A test ping button verifies your endpoint before anything real flows.

The event catalog

EventFires when
message.receivedAny inbound message — includes cached media URLs
message.sentAny outbound message leaves the platform
message.statusDelivery ticks: sent → delivered → read → failed
contact.createdA brand-new number messages you
contact.updatedProfile, tags or opt-in status changes
campaign.completedA campaign finishes — with sent/failed totals
automation.completedA contact finishes a chatbot flow — with collected data
ctwa.lead.createdSomeone arrives from a Click-to-WhatsApp ad — with ad attribution
cart.recoveredAn abandoned-cart message converts
approval.approved / approval.rejectedApproval outcomes — rejection includes the reason
interaction.responded / .reply / .completedOption taps, each captured reply, and the final bundle
lead.createdAn agent creates an internal-type lead from a chat
test.pingYou pressed the test button

Delivery format

POST your-endpoint ← ChatReach
Headers:
  Content-Type: application/json
  X-ChatReach-Event: message.received
  X-ChatReach-Signature: 3f1a9c…   (HMAC-SHA256 of the raw body)

Body:
{
  "event": "message.received",
  "timestamp": "2026-07-11T12:00:00Z",
  "data": {
    "messageId": 88231,
    "contactId": "…",
    "phone": "27821234567",
    "name": "John Smith",
    "type": "image",
    "body": null,
    "mediaUrl": "https://yourdomain.co.za/media/wamid_abc.jpg",
    "receivedAt": "2026-07-11T11:59:58Z"
  }
}

Verify the signature (4 lines)

C#
using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(signingSecret));
var computed = Convert.ToHexString(
    hmac.ComputeHash(Encoding.UTF8.GetBytes(rawRequestBody))).ToLowerInvariant();
var valid = computed == Request.Headers["X-ChatReach-Signature"];
Node.js
const crypto = require('crypto');
const computed = crypto.createHmac('sha256', signingSecret)
  .update(rawBody).digest('hex');
const valid = computed === req.headers['x-chatreach-signature'];
PHP
$computed = hash_hmac('sha256', $rawBody, $signingSecret);
$valid = hash_equals($computed, $_SERVER['HTTP_X_CHATREACH_SIGNATURE']);

Always compute over the raw request body — parse the JSON after verifying, never before re-serializing.

Retries & reliability

BehaviorDetail
SuccessAny 2xx response within 15 seconds
RetriesFailures retry at +5s, +30s and +2min before marking the delivery failed
Delivery logEvery attempt (status code, response snippet, timing) is visible on the Integrations page
OrderingBest-effort per event; use timestamps for strict ordering on your side
IdempotencyRetries resend the same payload — dedupe on data.messageId / entity IDs

Tip: respond 200 immediately and process asynchronously. Slow endpoints trigger unnecessary retries.

Point us at your endpoint

Test ping to production events in under five minutes. Free trial includes unlimited webhooks.

Start Free Trial