Developers

Webhooks

Receive events as they happen and verify their signature.

Webhooks POST a JSON event to your URL when something happens. Create endpoints in Tixxy at Organisation > Settings > Webhooks or through the API (webhooks:manage).

Events

TypeSent when
order.createdAn order was placed: in the shop, by hand, by import or through the API
order.paidAn order on invoice was marked as paid
order.cancelledAn order was cancelled
order.refundedA refund of an order was completed
ticket.checked_inA ticket was scanned at the entrance
ticket.invalidatedA ticket was made invalid
event.createdAn event was created
event.updatedThe name, dates, sale period or location of an event changed

Payload

{
  "id": "whevt_01J...",
  "object": "event",
  "type": "order.created",
  "created": "2026-10-01T12:00:00Z",
  "livemode": true,
  "data": {
    "object": { "id": "ord_01J...", "object": "order" }
  }
}

data.object is the same object the matching GET endpoint returns. Personal data is only included when the endpoint was set up to receive it.

Verify the signature

Every request carries a Tixxy-Signature header:

Tixxy-Signature: t=1790000000,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd

Compute an HMAC-SHA256 of {t}.{raw request body} with your endpoint's signing secret and compare it with v1. Reject requests where t is more than five minutes old.

import crypto from 'node:crypto';

export function verify(rawBody, header, secret) {
  const parts = Object.fromEntries(header.split(',').map((part) => part.split('=')));
  const expected = crypto.createHmac('sha256', secret).update(`${parts.t}.${rawBody}`).digest('hex');
  const fresh = Math.abs(Date.now() / 1000 - Number(parts.t)) < 300;

  return fresh && crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1));
}

Delivery

  • Answer with any 2xx status within 10 seconds. Do the real work afterwards, for example on a queue.
  • Failed deliveries are retried for about a day with increasing delays.
  • An endpoint that keeps failing for three days is switched off; its owners get an email.
  • The same event can arrive more than once. Store id and skip events you already processed.
  • Redirects are not followed, and endpoints must be public HTTPS URLs.

On this page