Webhooks
A webhook lets SmartChat tell your software that something happened, for example a new contact or a message that was delivered. You register an endpoint (an https address) and choose the events you want. SmartChat sends each event to the endpoint as a POST with a JSON body.
Set one up in Set up a webhook. The list of events is on the events page.
#What you receive
Headers:
| Header | Meaning |
|---|---|
SmartChat-Signature | t=<unix seconds>,v1=<hex>. Proves the delivery is from SmartChat. How to check it. |
SmartChat-Event-Id | ID of the event (evt_...). Same for every endpoint. |
SmartChat-Event-Type | The event name, for example contact.created. |
SmartChat-Delivery-Id | ID of this delivery (whd_...). |
SmartChat-Delivery-Attempt | Number of this try, starting at 1. |
User-Agent | SmartChat-Webhooks/2 |
Content-Type | application/json |
Body:
{
"id": "evt_0f8c1a2e4b7d4c3e9a5b6d7e8f901234",
"object": "event",
"type": "contact.opted_out",
"api_version": "2026-10-25",
"created_at": "2026-10-25T09:41:07.412Z",
"sequence": 128734,
"account_id": "acc_0f8c1a2e4b7d4c3e9a5b6d7e8f901234",
"livemode": true,
"request_id": "req_01JAB9C3X7K2M4N5P6Q7R8S9T0",
"data": {
"object": { "object": "contact", "id": "con_0f8c1a2e4b7d4c3e9a5b6d7e8f901234", "optin_whatsapp": "opted_out" },
"previous_attributes": { "optin_whatsapp": "confirmed" }
}
}| Field | Meaning |
|---|---|
id | Event ID. Use it to find duplicates. |
type | Event name. |
created_at | When the event happened, with milliseconds, in UTC. |
sequence | A counter to sort events. |
request_id | The ID of the API call that caused the event, if there was one. |
data.object | The object the event is about. |
data.previous_attributes | For changes: the old values of the changed fields. |
The body is at most 256 KB. If it would be larger, data.object is cut to object and id and the body gets "truncated": true. Read the full object with the API.
#What you must do
- Check the signature with the raw body. Code in shell, Python and TypeScript.
- Answer fast with any 2xx status. SmartChat waits 10 seconds. Do the real work after you answered.
- Expect duplicates. Delivery is at least once. Keep the
idof events you handled and skip repeats. - Do not rely on order. Events can arrive out of order. Use
sequenceorcreated_atto sort. - Use https. Only https on port 443 is allowed, without a user name or password in the address, and without redirects. Internal and private addresses are refused (
webhook_url_invalid). SmartChat checks the address when you save it and again at every connection.
An account can have up to 20 endpoints. The same address twice in one account is a conflict. Endpoints belong to the account, not to a key: revoking the key that created an endpoint does not stop it.
#Failures
If your endpoint does not answer with 2xx, SmartChat tries again later. The schedule, the health states of an endpoint and what happens at the end are on Retries and health.