frequentix
Developer docs

Build on the same API the product runs on.

The storefront, console and scanner are all clients of the frequentix API. These pages document the surface you can use too — OAuth clients, REST reads and signed webhooks — with worked examples our test suite verifies.

Documentation menu

Webhook event catalogue

Eleven events can be subscribed to, grouped here by family. Each entry shows the exact fields of the envelope’s data object and a full example delivery. Delivery mechanics — signatures, retries, ordering — are covered in the webhooks guide.

Orders

The order lifecycle: confirmation, money returned, and cancellation.

order.created

Fires once an order confirms — for paid and free orders alike — after the transaction has committed, so the order and its tickets are readable by the time the delivery arrives.

orderstring

Order reference.

statusstring

paid for a paid order, free_confirmed for a free one.

currencystring

Uppercase ISO 4217 currency code.

totalinteger

Order total in minor units (pence, cents).

application_feeinteger

Platform fee taken from the total, in minor units.

eventstring | null

Reference of the event the order belongs to.

contact_emailstring | null

The buyer's email address, when a contact is attached.

ticketsinteger

Number of tickets issued on the order.

Example delivery · order.created
{
  "event": "order.created",
  "created_at": "2026-08-14T19:04:11+01:00",
  "api_version": "2026-08-01",
  "data": {
    "order": "ord_01k1p3v9qe6rwyx0m5h8t2c4nf",
    "status": "paid",
    "currency": "GBP",
    "total": 8250,
    "application_fee": 165,
    "event": "evt_01k0zqj4d8v6snb2x9e7g3m5cr",
    "contact_email": "amelia.hart@example.com",
    "tickets": 3
  }
}

order.refunded

Fires for every refund against an order, whether issued from the console or made directly in the Stripe dashboard and reconciled afterwards. refund and fee_reversed are present only for refunds issued through frequentix; a dashboard-made refund is reconciled from Stripe's records, which carry neither.

orderstring

Order reference.

refundstring

Refund reference. Omitted when the refund was made in the Stripe dashboard.

amountinteger

Amount returned by this refund, in minor units.

fee_reversedinteger

Platform fee returned with this refund, in minor units. Omitted for dashboard-made refunds.

fully_refundedboolean

Whether the whole order is now settled as refunded.

Example delivery · order.refunded
{
  "event": "order.refunded",
  "created_at": "2026-08-20T11:30:02+01:00",
  "api_version": "2026-08-01",
  "data": {
    "order": "ord_01k1p3v9qe6rwyx0m5h8t2c4nf",
    "refund": "ref_01k2e0qcsg6vy9x4n7f3d8w5jm",
    "amount": 2750,
    "fee_reversed": 55,
    "fully_refunded": false
  }
}

order.cancelled

Fires when a confirmed order — paid or free — is cancelled, voiding its tickets and returning capacity to the pool. A cancellation never moves money; listen for order.refunded to know when funds are returned.

orderstring

Order reference.

reasonstring | null

The organiser-supplied cancellation reason, when given.

Example delivery · order.cancelled
{
  "event": "order.cancelled",
  "created_at": "2026-08-18T16:45:29+01:00",
  "api_version": "2026-08-01",
  "data": {
    "order": "ord_01k1p3v9qe6rwyx0m5h8t2c4nf",
    "reason": "Duplicate booking"
  }
}

Tickets

Individual tickets being scanned at the door or edited.

ticket.scanned

Fires on every scan verdict, from the scanner app and box-office check-in alike — denials included, so your systems see the same stream the door does. reason is a stable key: scanning.allowed on success, or a denial key such as scanning.already_scanned, scanning.wrong_entry_point, scanning.outside_validity_window, scanning.outside_session_window, scanning.session_cancelled, scanning.ticket_cancelled or scanning.ticket_refunded.

ticketstring

Ticket reference.

eventstring

Event reference.

resultstring

allowed or denied.

reasonstring

Stable verdict key, e.g. scanning.allowed.

scanner_locationstring | null

Reference of the entry point that scanned, when one was set.

scanned_atstring

When the scan happened, ISO 8601.

Example delivery · ticket.scanned
{
  "event": "ticket.scanned",
  "created_at": "2026-10-02T19:12:44+01:00",
  "api_version": "2026-08-01",
  "data": {
    "ticket": "tkt_01k1p3vazh5cw9x2r7m4e8t0bd",
    "event": "evt_01k0zqj4d8v6snb2x9e7g3m5cr",
    "result": "allowed",
    "reason": "scanning.allowed",
    "scanner_location": "loc_01k1p2tafd3vw6x8m5e9c2b7hs",
    "scanned_at": "2026-10-02T19:12:44+01:00"
  }
}

ticket.updated

Fires when an existing ticket is edited — a status change, reassignment or detail update. Each change increments revision, so out-of-order deliveries can be sequenced. There is deliberately no ticket.deleted event.

ticketstring

Ticket reference.

eventstring

Event reference.

statusstring

valid, cancelled, refunded or checked_in.

ticket_typestring | null

Reference of the ticket's type.

revisioninteger

Monotonic edit counter for this ticket.

updated_atstring | null

When the change was made, ISO 8601.

Example delivery · ticket.updated
{
  "event": "ticket.updated",
  "created_at": "2026-09-30T09:21:07+01:00",
  "api_version": "2026-08-01",
  "data": {
    "ticket": "tkt_01k1p3vazh5cw9x2r7m4e8t0bd",
    "event": "evt_01k0zqj4d8v6snb2x9e7g3m5cr",
    "status": "cancelled",
    "ticket_type": "tt_01k0zqj5ae8txcv3m7d9e2b4hs",
    "revision": 3,
    "updated_at": "2026-09-30T09:21:07+01:00"
  }
}

Add-ons

Purchased extras being redeemed at the venue.

add_on.redeemed

Fires when a unit of a purchased add-on — a drink token claimed, merch collected — is redeemed at the door or box office. A replayed redemption (the same client_reference retried) does not fire again.

order_linestring

Reference of the order line being redeemed (oln_…).

add_onstring | null

Reference of the add-on (adn_…).

eventstring

Event reference.

quantityinteger

Units redeemed in this action.

remaininginteger

Units still unredeemed on the line afterwards.

scanner_locationstring | null

Reference of the entry point that redeemed, when one was set.

redeemed_atstring

When the redemption happened, ISO 8601.

Example delivery · add_on.redeemed
{
  "event": "add_on.redeemed",
  "created_at": "2026-10-02T20:05:31+01:00",
  "api_version": "2026-08-01",
  "data": {
    "order_line": "oln_01k1p4wbvj6dy1z6n9h5f3e8ta",
    "add_on": "adn_01k0zqj6gbn04x9w2e7t5c3d8m",
    "event": "evt_01k0zqj4d8v6snb2x9e7g3m5cr",
    "quantity": 1,
    "remaining": 1,
    "scanner_location": "loc_01k1p2tafd3vw6x8m5e9c2b7hs",
    "redeemed_at": "2026-10-02T20:05:31+01:00"
  }
}

Payments

Card disputes raised against your charges.

charge.disputed

Fires when Stripe reports a dispute against one of your charges. The identifiers are Stripe's — a dispute and charge id, not frequentix references — and every field can be null depending on what Stripe sends.

disputestring | null

Stripe dispute id (dp_…).

chargestring | null

Stripe charge id (ch_…).

amountinteger | null

Disputed amount in Stripe's minor units.

reasonstring | null

Stripe's dispute reason, e.g. fraudulent.

Example delivery · charge.disputed
{
  "event": "charge.disputed",
  "created_at": "2026-08-27T08:14:52+01:00",
  "api_version": "2026-08-01",
  "data": {
    "dispute": "dp_1Q8XkT2c9aWv5RhM0nB3pDfE",
    "charge": "ch_3Q8XkR2c9aWv5RhM1kV9tYzL",
    "amount": 5500,
    "reason": "fraudulent"
  }
}

Waitlists

People joining, being offered and taking up waitlist places.

waitlist.joined

Fires when a new entry joins a waitlist for a sold-out ticket type or add-on.

waitlist_entrystring

Waitlist entry reference.

statusstring

The entry's status — waiting at the moment this event fires.

emailstring

The waiter's email address.

quantityinteger

Number of places requested.

eventstring | null

Reference of the event the waitlist belongs to.

sellablestring | null

Reference of what is waited on — a ticket type (tt_…) or add-on (adn_…).

orderstring | null

Reference of the order the entry converted into — null until waitlist.converted.

Example delivery · waitlist.joined
{
  "event": "waitlist.joined",
  "created_at": "2026-08-16T12:08:19+01:00",
  "api_version": "2026-08-01",
  "data": {
    "waitlist_entry": "wle_01k2d9pbrf5tx8w3m6e2c7v4hn",
    "status": "waiting",
    "email": "theo.marsh@example.com",
    "quantity": 2,
    "event": "evt_01k0zqj4d8v6snb2x9e7g3m5cr",
    "sellable": "tt_01k0zqj5famz3w8p6t2v0c9d4e",
    "order": null
  }
}

waitlist.offered

Fires when freed capacity is offered to an entry — the buyer has a limited window to complete their purchase before the offer expires.

waitlist_entrystring

Waitlist entry reference.

statusstring

The entry's status — offered at the moment this event fires.

emailstring

The waiter's email address.

quantityinteger

Number of places requested.

eventstring | null

Reference of the event the waitlist belongs to.

sellablestring | null

Reference of what is waited on — a ticket type (tt_…) or add-on (adn_…).

orderstring | null

Reference of the order the entry converted into — null until waitlist.converted.

Example delivery · waitlist.offered
{
  "event": "waitlist.offered",
  "created_at": "2026-08-19T09:00:03+01:00",
  "api_version": "2026-08-01",
  "data": {
    "waitlist_entry": "wle_01k2d9pbrf5tx8w3m6e2c7v4hn",
    "status": "offered",
    "email": "theo.marsh@example.com",
    "quantity": 2,
    "event": "evt_01k0zqj4d8v6snb2x9e7g3m5cr",
    "sellable": "tt_01k0zqj5famz3w8p6t2v0c9d4e",
    "order": null
  }
}

waitlist.converted

Fires when an offered entry completes checkout. order carries the resulting order's reference — expect a matching order.created delivery too.

waitlist_entrystring

Waitlist entry reference.

statusstring

The entry's status — converted at the moment this event fires.

emailstring

The waiter's email address.

quantityinteger

Number of places requested.

eventstring | null

Reference of the event the waitlist belongs to.

sellablestring | null

Reference of what is waited on — a ticket type (tt_…) or add-on (adn_…).

orderstring | null

Reference of the order the entry converted into — null until waitlist.converted.

Example delivery · waitlist.converted
{
  "event": "waitlist.converted",
  "created_at": "2026-08-19T09:41:57+01:00",
  "api_version": "2026-08-01",
  "data": {
    "waitlist_entry": "wle_01k2d9pbrf5tx8w3m6e2c7v4hn",
    "status": "converted",
    "email": "theo.marsh@example.com",
    "quantity": 2,
    "event": "evt_01k0zqj4d8v6snb2x9e7g3m5cr",
    "sellable": "tt_01k0zqj5famz3w8p6t2v0c9d4e",
    "order": "ord_01k2f1rdth8wz1y6p9h5f0d3ka"
  }
}

Sessions

Changes to the dated occurrences of a recurring event.

session.cancelled

Fires when one dated occurrence of a recurring event is cancelled — whether or not anything was sold, since an unsold night still changes a published schedule an integration may be mirroring. Sold tickets deliberately stay valid and refundable; tickets counts the still-valid tickets outstanding, so don't assume zero when reconciling.

sessionstring

Session reference.

eventstring

Event reference.

namestring | null

The session's display name.

starts_atstring

Session start, ISO 8601.

ends_atstring

Session end, ISO 8601.

ticketsinteger

Still-valid tickets outstanding for the session.

Example delivery · session.cancelled
{
  "event": "session.cancelled",
  "created_at": "2026-11-01T10:15:36+00:00",
  "api_version": "2026-08-01",
  "data": {
    "session": "ses_01k2c8ndqe4vw7x9m2t5b3h8fa",
    "event": "evt_01k0zqj4d8v6snb2x9e7g3m5cr",
    "name": "Evening show — 14 November",
    "starts_at": "2026-11-14T19:30:00+00:00",
    "ends_at": "2026-11-14T22:00:00+00:00",
    "tickets": 118
  }
}