API and webhooks

Receive events with webhooks

Events, request format, signature check and retries. Available on Team and Business.

Updated on November 6th, 20263 min readAs Markdown

A webhook sends an HTTPS POST to your server when something happens in your workspace, for example when a conversation starts or a contact changes. Set them up under Settings → Workspace → API & webhooks → Add webhook.

Webhooks are part of the Team plan (5 endpoints) and the Business plan (25 endpoints). Only owners and admins can manage them.

Events

Event Sent when
conversation.created A conversation starts
conversation.updated Status, assignment or labels of a conversation change
conversation.closed A conversation is resolved
message.created A new message arrives or is sent. Internal notes are not included.
contact.created A contact is saved
contact.updated A contact changes
rating.created A visitor rates a conversation

Send test sends a webhook.test event to check your endpoint. You can't subscribe to it.

The request

Every request is a POST with a JSON body:

{
  "id": "cm3x9…",
  "event": "conversation.created",
  "createdAt": "2026-11-06T09:12:44.120Z",
  "workspaceId": "cm1a2…",
  "data": { }
}

data holds the object the event is about. To see its exact fields, open the webhook, go to Deliveries and look at Sent for any delivery.

Headers:

Header Value
X-Asktrix-Event The event name
X-Asktrix-Delivery The delivery ID. It's the same as id in the body and doesn't change between retries.
X-Asktrix-Signature t=<unix timestamp>,v1=<signature>
User-Agent asktrix-webhooks/1

Answer with any 2xx status within 10 seconds. Redirects are not followed and count as a failure.

Check the signature

Each webhook has its own Signing secret (it starts with whsec_). The signature is an HMAC-SHA256, in hex, of the timestamp, a dot, and the raw request body.

Check it before you trust the request:

  1. Read t and v1 from the X-Asktrix-Signature header.
  2. Reject the request if t is more than 5 minutes away from your server time.
  3. Compute HMAC-SHA256 of <t>.<raw body> with your secret.
  4. Compare it with v1 in constant time.

Use the raw body exactly as received. If your framework parses the JSON first and you serialize it again, the signature won't match.

Node.js example:

import { createHmac, timingSafeEqual } from "node:crypto";

export function isValidAsktrixRequest(rawBody, header, secret) {
  const parts = Object.fromEntries(header.split(",").map((p) => p.trim().split("=")));
  const t = Number(parts.t);
  if (!t || Math.abs(Date.now() / 1000 - t) > 300) return false;
  const expected = createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex");
  const given = String(parts.v1 ?? "");
  return given.length === expected.length && timingSafeEqual(Buffer.from(given), Buffer.from(expected));
}

Rotate creates a new secret. The old one stops working immediately, so update your server right after rotating.

Retries

If a delivery fails (timeout, connection error or a status outside 2xx), we try again after 1 minute, 5 minutes, 30 minutes, 2 hours and 6 hours. That's six attempts in total. A retry has the same id, so you can skip duplicates.

If your endpoint keeps failing (20 failed attempts in a row, and a delivery has used up all six attempts), the webhook is switched off and the owners and admins of the workspace get a notification. In practice that means hours of failures, not a short outage. Fix your endpoint, then switch the webhook back on with Webhook active.

Delivery log

Deliveries shows the last 30 days per webhook: status, attempts, duration, what we sent and what your server answered. Filter by Failed and use Resend to deliver a single event again.

Limits

  • The endpoint URL must use https:// and be reachable from the internet. Private and local addresses are blocked.
  • Webhooks only fire while your workspace is on a plan that includes them. After a downgrade, your endpoints are kept but receive nothing.

For every event payload and verification code in Node.js, Python and PHP, see the webhook developer docs.

Was this article helpful?