Webhooks
Receive ticket, message and inbox events over HTTPS and verify their signatures.
Inboxes can be configured with webhook endpoints that receive events as JSON via HTTPS POST. Configure them in the inbox settings or via the API with the webhooks field of POST /v1/inboxes or PATCH /v1/inboxes/{id}. Each event is only sent to the webhooks of the inbox it belongs to.
A signing secret (whsec_...) is generated for each webhook that does not have one and is returned in the inbox webhooks array. The webhooks field replaces the whole list: to keep an existing webhook and its secret, send it back with its secret; an entry sent without a secret gets a new one.
Events
| Event | Fired when |
|---|---|
| ticket.created | A new ticket is created in the inbox: via POST /v1/tickets, the dashboard, an inbound email, a form submission, the public portal or a scheduling booking. Tickets started with POST /v1/tickets/compose do not fire it. |
| ticket.updated | A ticket is edited via PATCH /v1/tickets/{id} or through the equivalent ticket edit in the dashboard. Actions performed with /v1/tickets/{id}/manage, and status changes caused by new messages, do not fire it. |
| ticket.deleted | A ticket is permanently deleted (DELETE /v1/tickets/{id} or from the dashboard). |
| message.created | A message is added to a ticket: via POST /v1/tickets/{id}/messages (drafts are skipped until sent with /send), the dashboard (internal notes excluded), an inbound customer email or the public portal. |
| inbox.updated | The inbox settings are changed (PATCH /v1/inboxes/{id} or the dashboard). |
| inbox.deleted | The inbox is deleted (DELETE /v1/inboxes/{id} or the dashboard). |
Delivery
Each delivery is a POST request with a JSON body and these headers:
| Header | Value |
|---|---|
| Content-Type | application/json |
| User-Agent | TickOS-Webhooks/1.0 |
| X-Webhook-Event | The event name, e.g. ticket.created. |
| X-Tickos-Signature | t={unix_timestamp},v1={hmac_sha256_hex}. Only sent when the webhook has a secret. |
The body is an envelope with the event name, an ISO 8601 timestamp and the event data. data always includes the inbox; ticket events add ticket and customer, message events add message and ticket, and inbox events carry the inbox fields.
- Respond with any 2xx status to acknowledge the delivery.
- Each delivery times out after 10 seconds.
- Deliveries are attempted once: failed or timed-out deliveries are not retried. Use the API (e.g. GET /v1/tickets?updated_after=...) to reconcile if your endpoint was unavailable.
- Events are sent independently, so they may arrive out of order. Use timestamp and the resource updated_at to order them.
Verifying signatures
When the webhook has a secret, every delivery carries an X-Tickos-Signature header containing a timestamp and an HMAC-SHA256 signature:
To verify, compute HMAC-SHA256(secret, "{timestamp}.{raw_body}") and compare it with v1 using a constant-time comparison. Use the raw request body exactly as received, before parsing it as JSON:
Automation webhook steps
The webhook step of an automation is a separate mechanism: it calls the URL configured in the step (with its own method, headers and optional custom payload) when a contact reaches that step. Its default payload uses the event name automation.step.webhook and a different structure (automation, enrollment, customer and trigger data). See the Automations page for details.