Webhooks
Webhooks let Resool notify your own systems the moment something happens in your workspace. You add an endpoint (a URL on your server) and pick events such as Message received, Contact created or Deal won. Each time one of those events happens, Resool sends a signed HTTPS POST with the details, retries if your server doesn't answer, and keeps a log of recent deliveries. Use webhooks to sync data to your CRM or data warehouse, trigger your own automations, or alert another tool in real time.
Before you begin
- Only workspace Owners and Admins can add and manage webhook endpoints.
- Your endpoint must be a public
httpsaddress. Addresses on private networks are refused.
Events you can send
| Event in Resool | Event type | Sent when |
|---|---|---|
| Contact created | contact.created | A contact is added, by a teammate, an import or a new chat. |
| Conversation started | conversation.created | A new conversation starts on any channel. |
| Message received | message.received | A customer's message arrives. |
| Conversation closed | conversation.closed | A conversation is closed. |
| Conversation assigned | conversation.assigned | A conversation is assigned. |
| Tag added to contact | contact.tag_added | A tag is added to a contact. |
| Ticket created | ticket.created | A ticket is opened, from any source. |
| Ticket updated | ticket.updated | A ticket's status, priority, assignee or other fields change. |
| Task created | task.created | A task is created. |
| Task completed | task.completed | A task is marked done. |
| Recording watched | recording.viewed | Someone watches a shared recording. |
| Deal created | deal.created | A sales deal is created. |
| Deal won | deal.won | A deal is marked won. |
| Deal lost | deal.lost | A deal is marked lost. |
How to add a webhook endpoint
- Go to
Settings › Appsand open the Developer tools tab. - Click Connect (or Manage) on the Webhooks card. The Webhooks page opens.
- Click Add endpoint.
- Fill in the form:
- Endpoint address: your public
httpsURL. - Description (optional): a note for your team, for example "Data warehouse".
- Events to send: tick at least one event.
- Endpoint address: your public
- Click Add endpoint.
Settings › Apps › Developer tools › Webhooks › Add endpoint
The "Add endpoint" dialog with an https Endpoint address, a Description, and the Events to send checklist with Message received, Contact created and Deal won ticked.
File: screenshots/webhooks-add-endpoint.png
- The Copy the signing secret dialog shows the endpoint's secret. Copy it and store it on your server. You use it to verify that requests really come from Resool. Click Done.
You can copy the secret again later from the endpoint's menu.
What each request looks like
Resool sends a POST with a JSON body and these headers:
POST /your/endpoint
Content-Type: application/json
User-Agent: Resool-Webhooks/1.0
Resool-Event: message.received
Resool-Delivery: 7c2f… (unique per delivery)
Resool-Signature: t=1790990000,v1=5b2c…
{
"id": "evt_9f1c…",
"type": "message.received",
"createdAt": "2026-10-01T10:00:00.000Z",
"data": {
"id": "01a0…",
"conversationId": "01a0…",
"contactId": "01a0…",
"channelType": "whatsapp",
"body": "Hello!",
"attachments": 0,
"createdAt": "2026-10-01T10:00:00.000Z"
}
}
id identifies the event, type is the event type, and data holds the record that changed.
How to verify the signature
Resool-Signature contains a Unix timestamp t and v1, the hex HMAC-SHA256 of "<t>.<raw body>" using the endpoint's signing secret. Compute the same value from the raw request body (before parsing the JSON), compare it in constant time, and reject requests whose timestamp is more than 5 minutes old.
import { createHmac, timingSafeEqual } from 'node:crypto';
function verifyResool(rawBody, header, secret) {
const { t, v1 } = Object.fromEntries(header.split(',').map((p) => p.split('=')));
if (Math.abs(Date.now() / 1000 - Number(t)) > 300) return false;
const expected = createHmac('sha256', secret).update(`${t}.${rawBody}`).digest('hex');
return v1?.length === expected.length && timingSafeEqual(Buffer.from(expected), Buffer.from(v1));
}
import hmac, hashlib, time
def verify_resool(raw_body: bytes, header: str, secret: str) -> bool:
parts = dict(p.split("=", 1) for p in header.split(","))
if abs(time.time() - int(parts["t"])) > 300:
return False
signed = parts["t"].encode() + b"." + raw_body
expected = hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, parts.get("v1", ""))
How deliveries and retries work
- Answer with any
2xxstatus within 10 seconds. Do slow work after you respond. Redirects aren't followed and count as a failure. - If a delivery fails, Resool retries after 1 minute, 5 minutes, 30 minutes, 2 hours, 6 hours, 12 hours and 24 hours. If the last retry also fails, the delivery is marked Failed.
- An endpoint that fails 20 deliveries in a row is switched off and shows Turned off after failures. Before that, it shows how many failures happened in a row.
- Events are recorded together with the change that caused them, so you never get an event for a change that didn't happen.
- A delivery can arrive more than once, and events can arrive out of order. Use the event
idto ignore duplicates.
How to manage endpoints
Each endpoint on the Webhooks page shows its address, the number of events, and its description. Use the switch to pause or resume sending. The ⋯ menu has:
- Recent deliveries: the last 50 deliveries with their event, status (Pending, Delivered or Failed), number of attempts and response. Click Retry on a failed delivery to send it again.
- Send test event: queues a sample of the endpoint's first event, with the ID
evt_test, so you can check your endpoint and your signature check. - Copy signing secret: copies the secret again.
- Edit endpoint: change the address, description or events.
- Delete: confirm Remove this endpoint? to stop sending events to it.
Settings › Apps › Developer tools › Webhooks
The Webhooks page with two endpoints: one active with "3 events · Data warehouse", one with the red "Turned off after failures" badge; the ⋯ menu of the first one open showing Recent deliveries, Send test event, Copy signing secret, Edit endpoint and Delete.
File: screenshots/webhooks-endpoint-list.png
Settings › Apps › Developer tools › Webhooks › ⋯ › Recent deliveries
The Recent deliveries dialog with a list of deliveries: several Delivered, one Failed with "3 attempts" and the Retry button.
File: screenshots/webhooks-recent-deliveries.png
Endpoints created by Zapier, Make or n8n appear in the list with Added through the API. They're removed automatically when you turn the automation off in that tool.
FAQ and troubleshooting
My endpoint was turned off. How do I turn it back on?
Fix the problem on your server first. Then turn the endpoint's switch off and on again: this resets the failure count and sending resumes. Use Send test event to confirm it works.
Deliveries fail with a timeout
What you can do:
- Respond with
200as soon as you've received the request, then process it in the background. - Make sure the endpoint isn't redirecting (for example from
httptohttpsor to a URL with a trailing slash).
My signature check always fails
What you can do:
- Compute the HMAC over the raw body exactly as received, not over re-serialised JSON.
- Use the secret from Copy signing secret for this endpoint. Each endpoint has its own secret.
- Check that your server's clock is correct, because requests older than 5 minutes should be rejected.
Why was my endpoint address refused?
The address must start with https://, must not contain a username or password, and must point to a public server, not a private or local network.
Can I receive events for only one channel?
Webhooks send every event of the chosen types for the whole workspace. Filter on your side using fields in data, such as channelType.