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

Every subscribable event — 19 of them — 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, edited, or changing hands.

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"
  }
}

ticket.transferred

Fires when a recipient accepts a transfer offer. The swap retires the old ticket (its reference and QR stop working everywhere) and issues a replacement to the recipient under a fresh zero-total order, so both sides are named: retire from_ticket, adopt to_ticket, in one event. A face-value resale runs the same swap but announces itself as resale.completed instead.

transferstring

Transfer reference (ttr_…).

eventstring

Event reference.

from_ticketstring | null

The retired ticket's reference — no longer admits.

to_ticketstring | null

The replacement ticket's reference, issued to the recipient.

to_orderstring | null

The recipient's zero-total order reference.

recipient_emailstring

Who the ticket went to.

accepted_atstring | null

When the swap completed, ISO 8601.

Example delivery · ticket.transferred
{
  "event": "ticket.transferred",
  "created_at": "2026-09-12T18:40:53+01:00",
  "api_version": "2026-08-01",
  "data": {
    "transfer": "ttr_01k2f8m3nq7vw4x9e6t0c5d8hb",
    "event": "evt_01k0zqj4d8v6snb2x9e7g3m5cr",
    "from_ticket": "tkt_01k1p3vazh5cw9x2r7m4e8t0bd",
    "to_ticket": "tkt_01k2h0p5qs9vx6y1g8w3e7f0km",
    "to_order": "ord_01k2h1q6rt0wx7y2h9v4f8g1mn",
    "recipient_email": "jamie.osei@example.com",
    "accepted_at": "2026-09-12T18:40:53+01:00"
  }
}

ticket.swapped

Fires when a dated ticket is moved to another date of the same run — by the buyer from their order page, or by the organiser's team from the console. The move retires the old ticket (its reference and QR stop working everywhere) and issues a replacement on the new date under the *same* order, so both tickets and both dates are named: retire from_ticket, adopt to_ticket, in one event. Same ticket type and no money moves; a cross-type change is not a swap.

swapstring

Swap reference (swp_…).

eventstring

Event reference.

orderstring | null

The order both tickets belong to.

from_ticketstring | null

The retired ticket's reference — no longer admits.

to_ticketstring | null

The replacement ticket's reference, on the new date.

from_sessionstring | null

The date the ticket left.

to_sessionstring | null

The date the ticket now admits on.

actor"buyer" | "staff"

Who moved it: the buyer, or a member of the organiser's team.

swapped_atstring | null

When the move completed, ISO 8601.

Example delivery · ticket.swapped
{
  "event": "ticket.swapped",
  "created_at": "2026-09-14T10:12:41+01:00",
  "api_version": "2026-08-01",
  "data": {
    "swap": "swp_01k2j4r7st1xy8z3j0w5g9h2np",
    "event": "evt_01k0zqj4d8v6snb2x9e7g3m5cr",
    "order": "ord_01k1p3v9yg4bw8x1q6m2d7e5ta",
    "from_ticket": "tkt_01k1p3vazh5cw9x2r7m4e8t0bd",
    "to_ticket": "tkt_01k2j4s8tv2yz9a4k1x6h0j3pq",
    "from_session": "ses_01k1m2n3p4q5r6s7t8v9w0x1y2",
    "to_session": "ses_01k1m2n3p4q5r6s7t8v9w0x1z3",
    "actor": "buyer",
    "swapped_at": "2026-09-14T10:12:41+01:00"
  }
}

Resale

Face-value resale (Exchange): tickets listed and resold through the waitlist queue.

resale.listed

Fires when a holder lists a ticket for resale. Nothing changes about the ticket itself — it stays valid and scannable unless the listing actually sells. face_value is frozen at listing time: the per-unit price the seller originally paid, post-discount and tax-inclusive.

listingstring

Listing reference (rsl_…).

eventstring

Event reference.

ticketstring

The listed ticket's reference.

ticket_typestring | null

Reference of the ticket's type.

face_valueinteger

The frozen resale price — what the buyer pays and the seller is refunded — in minor units.

currencystring

Uppercase ISO 4217 currency code.

listed_atstring

When the listing was created, ISO 8601.

Example delivery · resale.listed
{
  "event": "resale.listed",
  "created_at": "2026-09-10T13:02:19+01:00",
  "api_version": "2026-08-01",
  "data": {
    "listing": "rsl_01k2g9n4pr8tw5x0f7v2d6e9jc",
    "event": "evt_01k0zqj4d8v6snb2x9e7g3m5cr",
    "ticket": "tkt_01k1p3vazh5cw9x2r7m4e8t0bd",
    "ticket_type": "tt_01k0zqj5ae8txcv3m7d9e2b4hs",
    "face_value": 18500,
    "currency": "GBP",
    "listed_at": "2026-09-10T13:02:19+01:00"
  }
}

resale.completed

Fires once the buyer's payment succeeds and the ownership swap settles: the seller's ticket is retired (from_ticket), the buyer holds a fresh one (to_ticket) on their own face-value order, and the listing is complete. The seller's face-value refund is queued at the same moment and may still be in flight when the delivery arrives.

listingstring

Listing reference (rsl_…).

eventstring

Event reference.

from_ticketstring | null

The seller's retired ticket — no longer admits.

to_ticketstring | null

The buyer's replacement ticket.

to_orderstring | null

The buyer's face-value order reference.

face_valueinteger

What the buyer paid for the seat (before their booking fee) and the seller is refunded, in minor units.

currencystring

Uppercase ISO 4217 currency code.

completed_atstring | null

When the resale settled, ISO 8601.

Example delivery · resale.completed
{
  "event": "resale.completed",
  "created_at": "2026-09-12T18:40:53+01:00",
  "api_version": "2026-08-01",
  "data": {
    "listing": "rsl_01k2g9n4pr8tw5x0f7v2d6e9jc",
    "event": "evt_01k0zqj4d8v6snb2x9e7g3m5cr",
    "from_ticket": "tkt_01k1p3vazh5cw9x2r7m4e8t0bd",
    "to_ticket": "tkt_01k2h0p5qs9vx6y1g8w3e7f0km",
    "to_order": "ord_01k2h1q6rt0wx7y2h9v4f8g1mn",
    "face_value": 18500,
    "currency": "GBP",
    "completed_at": "2026-09-12T18:40:53+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
  }
}

Leads

Exhibitors capturing visitor badges with frequentix Leads.

lead.captured

Fires when a stand team member captures a lead with frequentix Leads — online immediately, or on sync for a capture taken offline. Names the exhibitor, the event and the scanned badge.

leadstring

Lead reference.

eventstring

Event reference.

companystring

Reference of the exhibitor's company.

company_namestring

The exhibitor's display name.

licencestring

The lead-capture licence that made the scan.

ticketstring | null

Reference of the scanned badge's ticket.

statusstring

captured, unverified or declined.

captured_atstring

When the badge was scanned, ISO 8601.

Example delivery · lead.captured
{
  "event": "lead.captured",
  "created_at": "2026-09-12T11:22:47+01:00",
  "api_version": "2026-08-01",
  "data": {
    "lead": "led_01k2q4vx8b2ce5f0h3j6m9n2pr",
    "event": "evt_01k0zqj4d8v6snb2x9e7g3m5cr",
    "company": "com_01k2q4a7t5w8y1z4b7d0f3g6hk",
    "company_name": "Brightstand Displays",
    "licence": "llc_01k2q4c9v7x0z3a6c9e2g5j8kn",
    "ticket": "tkt_01k2f1rf2p9xz4w7b1m6d8e0hs",
    "status": "captured",
    "captured_at": "2026-09-12T11:22:47+01:00"
  }
}

Gift cards

Gift cards being sold and their value being spent.

gift_card.issued

Fires once per sold card, when the order that bought it confirms. Organiser-level — no event scoping, since a card is redeemable across all your events. The payload is deliberately PII-free: it never carries the card's code, the recipient or the buyer's message.

gift_cardstring

Reference of the card (gc_…).

initial_valueinteger

The load value, in minor units.

balanceinteger

The balance at issue — equal to initial_value.

currencystring

ISO 4217 code.

expires_atstring | null

When the card expires, ISO 8601 — null when it never does.

purchase_orderstring

Reference of the order that bought the card.

Example delivery · gift_card.issued
{
  "event": "gift_card.issued",
  "created_at": "2026-11-28T10:15:02+00:00",
  "api_version": "2026-08-01",
  "data": {
    "gift_card": "gc_01k5r8wx2m4np6q9s3v7y1b5de",
    "initial_value": 5000,
    "balance": 5000,
    "currency": "GBP",
    "expires_at": null,
    "purchase_order": "ord_01k5r8vt9c2df4g6h8j0k2m4np"
  }
}

gift_card.redeemed

Fires when an order part- or fully-paid by a gift card confirms and the card is debited. amount is what this order took; balance is what remains afterwards. Like gift_card.issued, the payload is PII-free.

gift_cardstring

Reference of the card (gc_…).

amountinteger

Value this order debited, in minor units.

balanceinteger

The card's remaining balance after the debit.

currencystring

ISO 4217 code.

orderstring

Reference of the order the card helped pay.

Example delivery · gift_card.redeemed
{
  "event": "gift_card.redeemed",
  "created_at": "2026-12-14T19:42:47+00:00",
  "api_version": "2026-08-01",
  "data": {
    "gift_card": "gc_01k5r8wx2m4np6q9s3v7y1b5de",
    "amount": 2000,
    "balance": 3000,
    "currency": "GBP",
    "order": "ord_01k6t2ab7e9fh1j3m5n7q9s2vx"
  }
}

Memberships

Membership terms beginning — first purchases and renewals alike.

membership.started

Fires once per membership sold, when the order that bought it confirms — a first purchase and a renewal both count, distinguished by renewed_from. Organiser-level — a membership spans your events, not the container event that sold it. The payload is deliberately PII-free: it never carries the member's claim link or contact details.

membershipstring

Reference of the membership (mem_…).

planstring | null

Reference of the membership plan (mpl_…).

orderstring | null

Reference of the order that bought the term.

starts_atstring

When the term starts, ISO 8601.

ends_atstring

When the term ends, ISO 8601.

renewed_fromstring | null

Reference of the term this one renews — null on a first purchase.

Example delivery · membership.started
{
  "event": "membership.started",
  "created_at": "2026-09-01T18:30:05+01:00",
  "api_version": "2026-08-01",
  "data": {
    "membership": "mem_01k7v3cd8f0gj2k4n6p8r0t3wy",
    "plan": "mpl_01k7v3ab5d9ef1h3m5n7q9s1vx",
    "order": "ord_01k7v3ef9g1hk3m5p7r9t1v4xz",
    "starts_at": "2026-09-01T18:30:04+01:00",
    "ends_at": "2027-09-01T18:30:04+01:00",
    "renewed_from": null
  }
}