API reference
Reads over your events, ticket types, orders, tickets and contacts, plus the narrow set of writes an integration actually needs: upserting contacts, checking tickets in, and managing webhook subscriptions. Field lists here mirror the API’s serializers exactly, and every example is schema-true.
Conventions
Base URL and versioning
Every endpoint lives under https://api.frequentix.com/v1. Requests carry Authorization: Bearer <token> — see Authentication.
Stability
Within /v1, documented fields are never removed or renamed, and their meaning doesn’t change. Evolution is additive: new fields, new endpoints and new webhook event names may appear at any time, so build clients that tolerate unknown keys. The webhook envelope and signature scheme are stable, and every delivery declares the api_version its payload was rendered under. If a breaking change is ever genuinely needed, it would ship opt-in, pinned per integration client — never as a surprise to existing integrations.
Responses and pagination
Responses wrap their result in a top-level data key. List endpoints return a paginator — 25 per page by default, ?per_page=N up to 100 — so page through with ?page=N and follow next_page_url until it is null:
dataarrayThe page of results.
current_pageintegerThis page's number.
per_pageintegerPage size — 25 by default; request more with ?per_page= up to 100.
totalintegerTotal results across all pages.
next_page_urlstring | nullAbsolute URL of the next page — null on the last. Follow it until null to read everything.
prev_page_urlstring | nullAbsolute URL of the previous page — null on the first.
frominteger | null1-based index of the first result on this page.
tointeger | null1-based index of the last result on this page.
last_pageintegerNumber of the final page.
first_page_urlstringAbsolute URL of the first page.
last_page_urlstringAbsolute URL of the final page.
pathstringThe endpoint URL without paging.
linksarrayPrev/number/next link objects, for building a pager UI.
Writes and idempotency
The two writes that create or change records — POST /integration/contacts and POST /integration/scans — require an Idempotency-Key header (any unique string up to 200 characters; a UUID is ideal). Retrying with the same key replays the stored response instead of running the request again, so a timeout can be retried safely. Reusing a key with a different body answers 409.
Object references
Every object is identified by a prefixed reference — a lowercase ULID like evt_01k0zqj4d8v6snb2x9e7g3m5cr. Treat references as opaque strings: match on the prefix if you must, never parse the tail.
evt_Eventtt_Ticket typeadn_Add-onord_Ordertkt_Ticketref_Refundses_Event sessionloc_Scanner locationwle_Waitlist entrywhk_Webhook subscriptionwhd_Webhook deliveryscn_Entry scanqst_Registration questionfld_Registration fieldMoney and dates
- Monetary amounts are integers in minor units (pence, cents) with an uppercase ISO 4217
currencyalongside —8250is £82.50. - REST timestamps are UTC in the form
2026-10-02T18:30:00.000000Z. Webhook payloads use offset ISO 8601 (2026-08-14T19:04:11+01:00) instead.
Fetching what changed
Every list endpoint takes ?updated_since=<ISO 8601> and switches into incremental mode: only rows updated on or after your pointer, oldest change first, and the response gains a top-level watermark beside data. The sync loop is three habits:
- Request the list with
updated_since=your stored pointer (use1970-01-01T00:00:00Zfor the first full import). - Walk
next_page_urluntil it is null, upserting rows into your copy keyed byreference. - Store the response’s
watermarkas your nextupdated_since.
curl "https://api.frequentix.com/v1/integration/orders?updated_since=2026-08-21T10%3A02%3A31Z" \
-H "Authorization: Bearer $FREQUENTIX_TOKEN"
{
"data": { "data": [ … ], "next_page_url": null, … },
"watermark": "2026-08-21T10:09:44.000000Z"
}The comparison is inclusive and the watermark sits a moment behind the clock, so nothing committing mid-poll can slip between two sweeps — the trade is that rows near the boundary can arrive twice. Upserting by reference makes re-delivery harmless; never treat the feed as append-only. In incremental mode pages are cursor-driven rather than numbered (a row changing mid-walk re-delivers later instead of shifting an unseen row out of a page), but the habit is unchanged — follow next_page_url:
dataarrayThe page of results, oldest change first.
per_pageintegerPage size — 25 by default; request more with ?per_page= up to 100.
next_page_urlstring | nullAbsolute URL of the next page — null once you have everything. Follow it until null.
prev_page_urlstring | nullAbsolute URL of the previous page — null on the first.
next_cursorstring | nullOpaque cursor the next-page URL carries; you never build one yourself.
prev_cursorstring | nullOpaque cursor for the previous page.
pathstringThe endpoint URL without paging.
Deletions and erasures
Removed rows disappear from default responses, which a sync cannot see. Add ?include_deleted=1 to receive tombstones: removed tickets and archived events carry deleted_at, and a contact erased under a data-protection request appears once as an identity-free stub (is_erased: true, every personal field null) — the signal to erase your copy as well. Every removal bumps updated_at, so tombstones flow through the same pointer loop.
What the pointer cannot see
Check-ins never touch the ticket row — a ticket’s updated_at (and its status) stay put when someone walks through the door. Arrivals live on the entry-scans list, which takes the same updated_since pointer, and on the ticket.scanned webhook. Registration answers likewise keep their own clock: editing an answer moves the answer’s answered_at, not the ticket’s updated_at.
List events
/v1/integration/eventsevents:readYour organiser's events, newest first. An event-scoped client sees only the events it was granted.
Query parameters
pageintegerPage number, starting at 1. Ignored when updated_since is present (cursor pages).
updated_sincestring (ISO 8601)Incremental mode: only rows updated on or after this instant, oldest change first, cursor-paged, with a top-level watermark to use as your next pointer. Inclusive — expect re-delivery around the boundary and dedupe by reference. See “Fetching what changed”.
include_deletedbooleanAlso return removed rows as tombstones (deleted_at set; erased contacts as identity-free stubs), so a sync can drop its copies. Off by default.
Event object
referencestringEvent reference (evt_…).
slugstringURL slug — accepted interchangeably with the reference in paths.
namestringEvent name.
statusstringdraft or published.
starts_atstring | nullEvent start, UTC.
ends_atstring | nullEvent end, UTC.
timezonestringIANA timezone the event runs in, e.g. Europe/London.
currencystringUppercase ISO 4217 currency code.
updated_atstringWhen the event last changed, UTC — what ?updated_since= compares against.
deleted_atstring | nullSet when the event has been archived. Archived events only appear under ?include_deleted=1.
Example
curl "https://api.frequentix.com/v1/integration/events" \
-H "Authorization: Bearer $FREQUENTIX_TOKEN"{
"data": {
"current_page": 1,
"data": [
{
"reference": "evt_01k2h6vcwj1ya3z8r1k7g5f0nd",
"slug": "northlight-sessions-winter-special",
"name": "Northlight Sessions — Winter Special",
"status": "draft",
"starts_at": "2027-01-22T19:00:00.000000Z",
"ends_at": "2027-01-22T23:00:00.000000Z",
"timezone": "Europe/London",
"currency": "GBP",
"updated_at": "2026-08-19T16:47:03.000000Z",
"deleted_at": null
},
{
"reference": "evt_01k0zqj4d8v6snb2x9e7g3m5cr",
"slug": "northlight-sessions-autumn-run",
"name": "Northlight Sessions — Autumn Run",
"status": "published",
"starts_at": "2026-10-02T18:30:00.000000Z",
"ends_at": "2026-12-19T22:30:00.000000Z",
"timezone": "Europe/London",
"currency": "GBP",
"updated_at": "2026-08-18T09:12:40.000000Z",
"deleted_at": null
}
],
"first_page_url": "https://api.frequentix.com/v1/integration/events?page=1",
"from": 1,
"last_page": 1,
"last_page_url": "https://api.frequentix.com/v1/integration/events?page=1",
"links": [
{
"url": null,
"label": "« Previous",
"active": false
},
{
"url": "https://api.frequentix.com/v1/integration/events?page=1",
"label": "1",
"active": true
},
{
"url": null,
"label": "Next »",
"active": false
}
],
"next_page_url": null,
"path": "https://api.frequentix.com/v1/integration/events",
"per_page": 25,
"prev_page_url": null,
"to": 2,
"total": 2
}
}Draft events are included — check status before treating an event as live.
With ?updated_since=, only events changed since your pointer, plus a watermark for the next poll.
Retrieve an event
/v1/integration/events/{eventKey}events:readOne event with its ticket types, including live availability counters.
Path parameters
eventKeystringThe event's reference (evt_…) or its slug — both are accepted.
Event object
referencestringEvent reference (evt_…).
slugstringURL slug — accepted interchangeably with the reference in paths.
namestringEvent name.
statusstringdraft or published.
starts_atstring | nullEvent start, UTC.
ends_atstring | nullEvent end, UTC.
timezonestringIANA timezone the event runs in, e.g. Europe/London.
currencystringUppercase ISO 4217 currency code.
updated_atstringWhen the event last changed, UTC — what ?updated_since= compares against.
deleted_atstring | nullSet when the event has been archived. Archived events only appear under ?include_deleted=1.
ticket_types[] — Ticket type object
referencestringTicket type reference (tt_…).
namestringTicket type name.
priceintegerPrice in minor units (pence, cents).
currencystringUppercase ISO 4217 currency code.
is_activebooleanWhether it is on sale.
totalinteger | nullCapacity — null when inventory is unlimited.
soldinteger | nullTickets sold so far.
Example
curl "https://api.frequentix.com/v1/integration/events/evt_01k0zqj4d8v6snb2x9e7g3m5cr" \
-H "Authorization: Bearer $FREQUENTIX_TOKEN"{
"data": {
"reference": "evt_01k0zqj4d8v6snb2x9e7g3m5cr",
"slug": "northlight-sessions-autumn-run",
"name": "Northlight Sessions — Autumn Run",
"status": "published",
"starts_at": "2026-10-02T18:30:00.000000Z",
"ends_at": "2026-12-19T22:30:00.000000Z",
"timezone": "Europe/London",
"currency": "GBP",
"updated_at": "2026-08-18T09:12:40.000000Z",
"deleted_at": null,
"ticket_types": [
{
"reference": "tt_01k0zqj5ae8txcv3m7d9e2b4hs",
"name": "General admission",
"price": 2750,
"currency": "GBP",
"is_active": true,
"total": 350,
"sold": 214
},
{
"reference": "tt_01k0zqj5famz3w8p6t2v0c9d4e",
"name": "Front row",
"price": 4500,
"currency": "GBP",
"is_active": true,
"total": 40,
"sold": 40
}
]
}
}An unknown key, another organiser's event, or an event outside your client's scope all return the same 404 — existence is never revealed.
List an event's orders
/v1/integration/events/{eventKey}/ordersorders:readThe event's orders, newest first, with buyer contact details.
Path parameters
eventKeystringThe event's reference (evt_…) or its slug — both are accepted.
Query parameters
pageintegerPage number, starting at 1. Ignored when updated_since is present (cursor pages).
updated_sincestring (ISO 8601)Incremental mode: only rows updated on or after this instant, oldest change first, cursor-paged, with a top-level watermark to use as your next pointer. Inclusive — expect re-delivery around the boundary and dedupe by reference. See “Fetching what changed”.
Order object
referencestringOrder reference (ord_…).
statusstringdraft, pending_payment, awaiting_approval, paid, free_confirmed, cancelled or refunded.
currencystringUppercase ISO 4217 currency code.
subtotalintegerLine-item total before discounts and tax, in minor units.
discount_totalintegerDiscounts applied, in minor units.
tax_totalintegerTax charged, in minor units.
totalintegerAmount paid, in minor units.
contactobject | nullBuyer contact — {email, first_name, last_name} — or null when none is attached.
confirmed_atstring | nullWhen the order confirmed, UTC.
created_atstringWhen the order was created, UTC.
updated_atstringWhen the order last changed (status moves, refunds, …), UTC — what ?updated_since= compares against.
Example
curl "https://api.frequentix.com/v1/integration/events/northlight-sessions-autumn-run/orders?page=1" \
-H "Authorization: Bearer $FREQUENTIX_TOKEN"{
"data": {
"current_page": 1,
"data": [
{
"reference": "ord_01k2f1rdth8wz1y6p9h5f0d3ka",
"status": "paid",
"currency": "GBP",
"subtotal": 9000,
"discount_total": 0,
"tax_total": 0,
"total": 9000,
"contact": {
"email": "theo.marsh@example.com",
"first_name": "Theo",
"last_name": "Marsh"
},
"confirmed_at": "2026-08-21T10:02:33.000000Z",
"created_at": "2026-08-21T09:58:12.000000Z",
"updated_at": "2026-08-21T10:02:33.000000Z"
},
{
"reference": "ord_01k1p3v9qe6rwyx0m5h8t2c4nf",
"status": "paid",
"currency": "GBP",
"subtotal": 8250,
"discount_total": 0,
"tax_total": 0,
"total": 8250,
"contact": {
"email": "amelia.hart@example.com",
"first_name": "Amelia",
"last_name": "Hart"
},
"confirmed_at": "2026-08-14T18:04:11.000000Z",
"created_at": "2026-08-14T18:01:47.000000Z",
"updated_at": "2026-08-14T18:04:11.000000Z"
}
],
"first_page_url": "https://api.frequentix.com/v1/integration/events/northlight-sessions-autumn-run/orders?page=1",
"from": 1,
"last_page": 1,
"last_page_url": "https://api.frequentix.com/v1/integration/events/northlight-sessions-autumn-run/orders?page=1",
"links": [
{
"url": null,
"label": "« Previous",
"active": false
},
{
"url": "https://api.frequentix.com/v1/integration/events/northlight-sessions-autumn-run/orders?page=1",
"label": "1",
"active": true
},
{
"url": null,
"label": "Next »",
"active": false
}
],
"next_page_url": null,
"path": "https://api.frequentix.com/v1/integration/events/northlight-sessions-autumn-run/orders",
"per_page": 25,
"prev_page_url": null,
"to": 2,
"total": 2
}
}Orders of every status are returned — filter on status (paid, free_confirmed, refunded, …) for settled revenue.
With ?updated_since=, refunds and cancellations surface too: any status move bumps updated_at.
Who am I
/v1/integration/meany scopeThe organiser this token acts for and what the client may do. Automation platforms use it as the connection test and label.
Identity object
organiserobject{reference, display_name} — whose data this token reads.
clientobject{id, name, scopes, all_events} — the client behind the token.
api_versionstringThe contract version this client is pinned to (date-stamped).
Example
curl "https://api.frequentix.com/v1/integration/me" \
-H "Authorization: Bearer $FREQUENTIX_TOKEN"{
"data": {
"organiser": {
"reference": "org_01k0zq2v7m4xerb8t5w9c3n6dh",
"display_name": "Northlight Live"
},
"client": {
"id": "9d3f2b1a-4c5e-6f70-8192-a3b4c5d6e7f8",
"name": "Zapier",
"scopes": [
"orders:read",
"tickets:read",
"webhooks:write"
],
"all_events": true
},
"api_version": "2026-08-01"
}
}List orders (organiser-wide)
/v1/integration/ordersorders:readEvery event's orders in one feed, newest first — the polling shape for automations not pinned to one event. Each order carries its event reference.
Query parameters
pageintegerPage number, starting at 1. Ignored when updated_since is present (cursor pages).
updated_sincestring (ISO 8601)Incremental mode: only rows updated on or after this instant, oldest change first, cursor-paged, with a top-level watermark to use as your next pointer. Inclusive — expect re-delivery around the boundary and dedupe by reference. See “Fetching what changed”.
Order object
referencestringOrder reference (ord_…).
statusstringdraft, pending_payment, awaiting_approval, paid, free_confirmed, cancelled or refunded.
currencystringUppercase ISO 4217 currency code.
subtotalintegerLine-item total before discounts and tax, in minor units.
discount_totalintegerDiscounts applied, in minor units.
tax_totalintegerTax charged, in minor units.
totalintegerAmount paid, in minor units.
contactobject | nullBuyer contact — {email, first_name, last_name} — or null when none is attached.
confirmed_atstring | nullWhen the order confirmed, UTC.
created_atstringWhen the order was created, UTC.
updated_atstringWhen the order last changed (status moves, refunds, …), UTC — what ?updated_since= compares against.
eventstring | nullReference of the event the order belongs to (evt_…).
Example
curl "https://api.frequentix.com/v1/integration/orders?updated_since=2026-08-21T10%3A00%3A00Z" \
-H "Authorization: Bearer $FREQUENTIX_TOKEN"{
"data": {
"current_page": 1,
"data": [
{
"reference": "ord_01k2f1rdth8wz1y6p9h5f0d3ka",
"status": "paid",
"currency": "GBP",
"subtotal": 9000,
"discount_total": 0,
"tax_total": 0,
"total": 9000,
"contact": {
"email": "theo.marsh@example.com",
"first_name": "Theo",
"last_name": "Marsh"
},
"confirmed_at": "2026-08-21T10:02:33.000000Z",
"created_at": "2026-08-21T09:58:12.000000Z",
"updated_at": "2026-08-21T10:02:33.000000Z",
"event": "evt_01k0zqj4d8v6snb2x9e7g3m5cr"
}
],
"first_page_url": "https://api.frequentix.com/v1/integration/orders?page=1",
"from": 1,
"last_page": 1,
"last_page_url": "https://api.frequentix.com/v1/integration/orders?page=1",
"links": [
{
"url": null,
"label": "« Previous",
"active": false
},
{
"url": "https://api.frequentix.com/v1/integration/orders?page=1",
"label": "1",
"active": true
},
{
"url": null,
"label": "Next »",
"active": false
}
],
"next_page_url": null,
"path": "https://api.frequentix.com/v1/integration/orders",
"per_page": 25,
"prev_page_url": null,
"to": 1,
"total": 1
}
}An event-scoped client sees only its events' orders here, exactly as on the per-event endpoint.
One organiser-wide updated_since pointer here syncs every event's orders in a single loop.
Retrieve an order
/v1/integration/orders/{reference}orders:readOne order by its reference, with its event.
Path parameters
referencestringThe order's reference (ord_…).
Order object
referencestringOrder reference (ord_…).
statusstringdraft, pending_payment, awaiting_approval, paid, free_confirmed, cancelled or refunded.
currencystringUppercase ISO 4217 currency code.
subtotalintegerLine-item total before discounts and tax, in minor units.
discount_totalintegerDiscounts applied, in minor units.
tax_totalintegerTax charged, in minor units.
totalintegerAmount paid, in minor units.
contactobject | nullBuyer contact — {email, first_name, last_name} — or null when none is attached.
confirmed_atstring | nullWhen the order confirmed, UTC.
created_atstringWhen the order was created, UTC.
updated_atstringWhen the order last changed (status moves, refunds, …), UTC — what ?updated_since= compares against.
eventstring | nullReference of the event the order belongs to (evt_…).
Example
curl "https://api.frequentix.com/v1/integration/orders/ord_01k2f1rdth8wz1y6p9h5f0d3ka" \
-H "Authorization: Bearer $FREQUENTIX_TOKEN"{
"data": {
"reference": "ord_01k2f1rdth8wz1y6p9h5f0d3ka",
"status": "paid",
"currency": "GBP",
"subtotal": 9000,
"discount_total": 0,
"tax_total": 0,
"total": 9000,
"contact": {
"email": "theo.marsh@example.com",
"first_name": "Theo",
"last_name": "Marsh"
},
"confirmed_at": "2026-08-21T10:02:33.000000Z",
"created_at": "2026-08-21T09:58:12.000000Z",
"updated_at": "2026-08-21T10:02:33.000000Z",
"event": "evt_01k0zqj4d8v6snb2x9e7g3m5cr"
}
}List an event's tickets
/v1/integration/events/{eventKey}/ticketstickets:readIssued tickets with their holders, newest first. Filter by order to turn an order into its attendees — one item per person.
Path parameters
eventKeystringThe event's reference (evt_…) or its slug — both are accepted.
Query parameters
pageintegerPage number, starting at 1. Ignored when updated_since is present (cursor pages).
orderstringOnly this order's tickets (ord_…). Unknown orders 404.
statusstringvalid, checked_in, cancelled or refunded. Arrivals are not reported through this field — read the entry-scans list or ticket.scanned webhooks.
updated_sincestring (ISO 8601)Incremental mode: only rows updated on or after this instant, oldest change first, cursor-paged, with a top-level watermark to use as your next pointer. Inclusive — expect re-delivery around the boundary and dedupe by reference. See “Fetching what changed”.
include_deletedbooleanAlso return removed rows as tombstones (deleted_at set; erased contacts as identity-free stubs), so a sync can drop its copies. Off by default.
includestringanswers adds each ticket's registration answers to the list items (always present on the single-ticket read).
Ticket object
referencestringTicket reference (tkt_…).
statusstringvalid, checked_in, cancelled or refunded. Check-ins never appear here (or move updated_at): arrivals live on the scan record — consume ticket.scanned webhooks or the entry-scans list.
ticket_typeobject | nullThe type — {reference, name}.
contactobject | nullThe holder — {reference, email, first_name, last_name}. Reassignment repoints this, so it is the person at the door, not necessarily the buyer.
orderstring | nullOrder reference (ord_…).
sessionobject | nullFor multi-date runs: the occurrence this ticket admits to — {reference, name, starts_at}; null on a single-date event.
seat_labelstring | nullReserved seating: the seat ("Stalls · Row A · Seat 4"); null for GA.
created_atstringWhen the ticket was issued, UTC.
updated_atstringWhen the ticket last changed (reassignment, cancellation, …), UTC — what ?updated_since= compares against.
deleted_atstring | nullSet when the ticket was removed (superseded by a transfer or resale, or erased). Removed tickets only appear under ?include_deleted=1.
answers[] — Answer object (with `?include=answers`)
questionstringThe question's reference (qst_…) — an answer's identity is (ticket, question); there is no separate answer id.
fieldstringThe underlying field definition (fld_…), shared across events.
keystringThe field's machine key, stable per organiser — e.g. dietary.
labelstring | nullThe question as it was asked.
typestringField type — text, select, multiselect, date, country, ….
valuestring | number | boolean | array | nullThe answer as stored. Null when the question was asked but not answered — a different fact from the question being absent (not asked for this ticket's type).
value_labelsarray | nullFor choice types: the chosen options resolved to their labels, always as a list (one element on a single select). Choice options have no ids — value is the stable key, this is the wording.
answered_atstring | nullWhen the answer row last changed, UTC. This is the only change signal: editing answers moves nothing on the ticket, and a data-protection erasure nulls value while moving this.
Example
curl "https://api.frequentix.com/v1/integration/events/evt_01k0zqj4d8v6snb2x9e7g3m5cr/tickets?order=ord_01k2f1rdth8wz1y6p9h5f0d3ka" \
-H "Authorization: Bearer $FREQUENTIX_TOKEN"{
"data": {
"current_page": 1,
"data": [
{
"reference": "tkt_01k2f1rf2p9xz4w7b1m6d8e0hs",
"status": "valid",
"ticket_type": {
"reference": "tt_01k0zqj5ae8txcv3m7d9e2b4hs",
"name": "General admission"
},
"contact": {
"reference": "con_01k2f1rdz44qh8n2v5x9b7c1mf",
"email": "theo.marsh@example.com",
"first_name": "Theo",
"last_name": "Marsh"
},
"order": "ord_01k2f1rdth8wz1y6p9h5f0d3ka",
"session": null,
"seat_label": null,
"created_at": "2026-08-21T10:02:34.000000Z",
"updated_at": "2026-08-21T10:02:34.000000Z",
"deleted_at": null
}
],
"first_page_url": "https://api.frequentix.com/v1/integration/events/evt_01k0zqj4d8v6snb2x9e7g3m5cr/tickets?page=1",
"from": 1,
"last_page": 1,
"last_page_url": "https://api.frequentix.com/v1/integration/events/evt_01k0zqj4d8v6snb2x9e7g3m5cr/tickets?page=1",
"links": [
{
"url": null,
"label": "« Previous",
"active": false
},
{
"url": "https://api.frequentix.com/v1/integration/events/evt_01k0zqj4d8v6snb2x9e7g3m5cr/tickets?page=1",
"label": "1",
"active": true
},
{
"url": null,
"label": "Next »",
"active": false
}
],
"next_page_url": null,
"path": "https://api.frequentix.com/v1/integration/events/evt_01k0zqj4d8v6snb2x9e7g3m5cr/tickets",
"per_page": 25,
"prev_page_url": null,
"to": 1,
"total": 1
}
}Cancelled-and-superseded tickets (transfers, resale) are excluded, exactly as in the console — unless you ask for tombstones with ?include_deleted=1, which serves them with deleted_at set so a sync can drop its copies.
With ?updated_since=, reassignments, cancellations and removals surface incrementally.
Retrieve a ticket
/v1/integration/tickets/{reference}tickets:readOne ticket by reference, with its holder, its event and the registration answers provided when it was bought.
Path parameters
referencestringThe ticket's reference (tkt_…).
Ticket object (plus `event`)
referencestringTicket reference (tkt_…).
statusstringvalid, checked_in, cancelled or refunded. Check-ins never appear here (or move updated_at): arrivals live on the scan record — consume ticket.scanned webhooks or the entry-scans list.
ticket_typeobject | nullThe type — {reference, name}.
contactobject | nullThe holder — {reference, email, first_name, last_name}. Reassignment repoints this, so it is the person at the door, not necessarily the buyer.
orderstring | nullOrder reference (ord_…).
sessionobject | nullFor multi-date runs: the occurrence this ticket admits to — {reference, name, starts_at}; null on a single-date event.
seat_labelstring | nullReserved seating: the seat ("Stalls · Row A · Seat 4"); null for GA.
created_atstringWhen the ticket was issued, UTC.
updated_atstringWhen the ticket last changed (reassignment, cancellation, …), UTC — what ?updated_since= compares against.
deleted_atstring | nullSet when the ticket was removed (superseded by a transfer or resale, or erased). Removed tickets only appear under ?include_deleted=1.
eventstring | nullReference of the ticket's event (evt_…).
answers[] — Answer object
questionstringThe question's reference (qst_…) — an answer's identity is (ticket, question); there is no separate answer id.
fieldstringThe underlying field definition (fld_…), shared across events.
keystringThe field's machine key, stable per organiser — e.g. dietary.
labelstring | nullThe question as it was asked.
typestringField type — text, select, multiselect, date, country, ….
valuestring | number | boolean | array | nullThe answer as stored. Null when the question was asked but not answered — a different fact from the question being absent (not asked for this ticket's type).
value_labelsarray | nullFor choice types: the chosen options resolved to their labels, always as a list (one element on a single select). Choice options have no ids — value is the stable key, this is the wording.
answered_atstring | nullWhen the answer row last changed, UTC. This is the only change signal: editing answers moves nothing on the ticket, and a data-protection erasure nulls value while moving this.
Example
curl "https://api.frequentix.com/v1/integration/tickets/tkt_01k2f1rf2p9xz4w7b1m6d8e0hs" \
-H "Authorization: Bearer $FREQUENTIX_TOKEN"{
"data": {
"reference": "tkt_01k2f1rf2p9xz4w7b1m6d8e0hs",
"status": "valid",
"ticket_type": {
"reference": "tt_01k0zqj5ae8txcv3m7d9e2b4hs",
"name": "General admission"
},
"contact": {
"reference": "con_01k2f1rdz44qh8n2v5x9b7c1mf",
"email": "theo.marsh@example.com",
"first_name": "Theo",
"last_name": "Marsh"
},
"order": "ord_01k2f1rdth8wz1y6p9h5f0d3ka",
"session": null,
"seat_label": null,
"created_at": "2026-08-21T10:02:34.000000Z",
"updated_at": "2026-08-21T10:02:34.000000Z",
"deleted_at": null,
"event": "evt_01k0zqj4d8v6snb2x9e7g3m5cr",
"answers": [
{
"question": "qst_01k1c8mw2e5rv7x0b3d6f9g2hj",
"field": "fld_01k1c8kt9q3nw6y8z1a4c7e0gm",
"key": "dietary",
"label": "Dietary requirements",
"type": "select",
"value": "vegan",
"value_labels": [
"Vegan"
],
"answered_at": "2026-08-21T10:01:58.000000Z"
},
{
"question": "qst_01k1c8p04u7tx9z2b5d8f1h4jn",
"field": "fld_01k1c8n52s5pw8y0a3c6e9g2im",
"key": "accessibility",
"label": "Access requirements we should know about",
"type": "text",
"value": null,
"value_labels": null,
"answered_at": null
}
]
}
}The answers are the buyer's registration — one submission per order — so every ticket on an order carries the same set. A question asked but left blank appears with value: null; a question not applicable to this ticket's type is absent.
List contacts
/v1/integration/contactscontacts:readYour organiser's contacts, newest first. ?email= is an exact, case-insensitive lookup — the "find contact" step.
Query parameters
pageintegerPage number, starting at 1. Ignored when updated_since is present (cursor pages).
emailstringExact email to look up (case-insensitive).
updated_sincestring (ISO 8601)Incremental mode: only rows updated on or after this instant, oldest change first, cursor-paged, with a top-level watermark to use as your next pointer. Inclusive — expect re-delivery around the boundary and dedupe by reference. See “Fetching what changed”.
include_deletedbooleanAlso return removed rows as tombstones (deleted_at set; erased contacts as identity-free stubs), so a sync can drop its copies. Off by default.
Contact object
referencestringContact reference (con_…).
emailstring | nullEmail address — the identity key. Null on an erased contact's stub.
first_namestring | nullFirst name.
last_namestring | nullLast name.
mobilestring | nullMobile number.
unsubscribed_atstring | nullWhen they unsubscribed from marketing email. If you email this list from your own tools, exclude anyone with a value here.
is_erasedbooleanTrue on the stub of a contact erased under a data-protection request: the reference survives so you can find your copy, every identity field is null, and your copy should be erased too.
erased_atstring | nullWhen the erasure happened, UTC.
created_atstringWhen the contact was created, UTC.
updated_atstringWhen the contact last changed, UTC — what ?updated_since= compares against. Erasure moves it, so a sweep picks the stub up.
Example
curl "https://api.frequentix.com/v1/integration/contacts?email=theo.marsh%40example.com" \
-H "Authorization: Bearer $FREQUENTIX_TOKEN"{
"data": {
"current_page": 1,
"data": [
{
"reference": "con_01k2f1rdz44qh8n2v5x9b7c1mf",
"email": "theo.marsh@example.com",
"first_name": "Theo",
"last_name": "Marsh",
"mobile": null,
"unsubscribed_at": null,
"is_erased": false,
"erased_at": null,
"created_at": "2026-08-21T09:58:12.000000Z",
"updated_at": "2026-08-21T09:58:12.000000Z"
}
],
"first_page_url": "https://api.frequentix.com/v1/integration/contacts?page=1",
"from": 1,
"last_page": 1,
"last_page_url": "https://api.frequentix.com/v1/integration/contacts?page=1",
"links": [
{
"url": null,
"label": "« Previous",
"active": false
},
{
"url": "https://api.frequentix.com/v1/integration/contacts?page=1",
"label": "1",
"active": true
},
{
"url": null,
"label": "Next »",
"active": false
}
],
"next_page_url": null,
"path": "https://api.frequentix.com/v1/integration/contacts",
"per_page": 25,
"prev_page_url": null,
"to": 1,
"total": 1
}
}Contacts erased under a data-protection request are absent by default. With ?include_deleted=1 they appear as identity-free stubs (is_erased: true, every personal field null) — the signal to erase your copy too. Erasure bumps updated_at, so an incremental sweep picks the stub up.
Retrieve a contact
/v1/integration/contacts/{reference}contacts:readOne contact by reference.
Path parameters
referencestringThe contact's reference (con_…).
Contact object
referencestringContact reference (con_…).
emailstring | nullEmail address — the identity key. Null on an erased contact's stub.
first_namestring | nullFirst name.
last_namestring | nullLast name.
mobilestring | nullMobile number.
unsubscribed_atstring | nullWhen they unsubscribed from marketing email. If you email this list from your own tools, exclude anyone with a value here.
is_erasedbooleanTrue on the stub of a contact erased under a data-protection request: the reference survives so you can find your copy, every identity field is null, and your copy should be erased too.
erased_atstring | nullWhen the erasure happened, UTC.
created_atstringWhen the contact was created, UTC.
updated_atstringWhen the contact last changed, UTC — what ?updated_since= compares against. Erasure moves it, so a sweep picks the stub up.
Example
curl "https://api.frequentix.com/v1/integration/contacts/con_01k2f1rdz44qh8n2v5x9b7c1mf" \
-H "Authorization: Bearer $FREQUENTIX_TOKEN"{
"data": {
"reference": "con_01k2f1rdz44qh8n2v5x9b7c1mf",
"email": "theo.marsh@example.com",
"first_name": "Theo",
"last_name": "Marsh",
"mobile": null,
"unsubscribed_at": null,
"is_erased": false,
"erased_at": null,
"created_at": "2026-08-21T09:58:12.000000Z",
"updated_at": "2026-08-21T09:58:12.000000Z"
}
}Create or update a contact
/v1/integration/contactscontacts:writeUpsert by email: creates the contact (201) or updates the fields you provide on the existing one (200). Fields you omit are never touched, and the email is only ever the match key.
Query parameters
emailstring (body, required)The identity key — matched case-insensitively.
first_name / last_name / mobilestring (body, optional)Set only the fields you send.
Contact object
referencestringContact reference (con_…).
emailstring | nullEmail address — the identity key. Null on an erased contact's stub.
first_namestring | nullFirst name.
last_namestring | nullLast name.
mobilestring | nullMobile number.
unsubscribed_atstring | nullWhen they unsubscribed from marketing email. If you email this list from your own tools, exclude anyone with a value here.
is_erasedbooleanTrue on the stub of a contact erased under a data-protection request: the reference survives so you can find your copy, every identity field is null, and your copy should be erased too.
erased_atstring | nullWhen the erasure happened, UTC.
created_atstringWhen the contact was created, UTC.
updated_atstringWhen the contact last changed, UTC — what ?updated_since= compares against. Erasure moves it, so a sweep picks the stub up.
Example
curl -X POST "https://api.frequentix.com/v1/integration/contacts" \
-H "Authorization: Bearer $FREQUENTIX_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 4f9e2b7c-1d0a-4c3e-9f68-2a5b7c9d1e3f" \
-d '{"email": "amelia.hart@example.com", "first_name": "Amelia"}'{
"data": {
"reference": "con_01k2p8xw3m6yq1v4b9d2f5g8hj",
"email": "amelia.hart@example.com",
"first_name": "Amelia",
"last_name": null,
"mobile": null,
"unsubscribed_at": null,
"is_erased": false,
"erased_at": null,
"created_at": "2026-08-22T14:11:05.000000Z",
"updated_at": "2026-08-22T14:11:05.000000Z"
}
}Requires an Idempotency-Key header; replaying the same key returns the stored response instead of re-running.
A contact erased under a data-protection request answers 422 with code contacts.erased and is never recreated.
Check in a ticket
/v1/integration/scansscans:writeRecord an online entry scan by ticket reference — the same evaluator as the door, so scan-once, session windows and validity windows all apply, and the organiser's ticket.scanned webhook fires.
Query parameters
ticketstring (body, required)The ticket's reference (tkt_…).
Verdict object
allowedbooleanWhether the holder may enter.
reasonstringMachine-readable verdict key, e.g. scanning.allowed, scanning.already_scanned.
messagestringThe verdict as a sentence.
sessionobject | nullWhich date the ticket is for — the whole answer on scanning.outside_session_window.
seat_labelstring | nullThe seat, so the door can direct the attendee; null for GA.
scanobjectThe recorded scan — {reference, result, scanned_at}.
Example
curl -X POST "https://api.frequentix.com/v1/integration/scans" \
-H "Authorization: Bearer $FREQUENTIX_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 7a1c9e3f-5b2d-4e60-8f97-3c6d8e0f2a4b" \
-d '{"ticket": "tkt_01k2f1rf2p9xz4w7b1m6d8e0hs"}'{
"allowed": true,
"reason": "scanning.allowed",
"message": "Entry allowed.",
"session": null,
"seat_label": null,
"scan": {
"reference": "scn_01k2p9av6r8tw2x5c0e3g6h9jk",
"result": "allowed",
"scanned_at": "2026-08-22T18:41:27.000000Z"
}
}An admitted scan answers 200; a denial answers 422 with the same verdict shape and allowed: false — read reason, don't treat the status alone as failure.
Requires an Idempotency-Key header. A replay returns the first verdict — on a scan-once ticket that is the difference between a repeated "allowed" and a wrong "already scanned".
List an event's entry scans
/v1/integration/events/{eventKey}/scansscans:readThe arrival feed: every recorded entry scan — admitted and denied — newest first. Check-ins never touch the ticket itself, so this list (or the ticket.scanned webhook) is the only place arrivals appear.
Path parameters
eventKeystringThe event's reference (evt_…) or its slug — both are accepted.
Query parameters
pageintegerPage number, starting at 1. Ignored when updated_since is present (cursor pages).
updated_sincestring (ISO 8601)Incremental mode: only rows updated on or after this instant, oldest change first, cursor-paged, with a top-level watermark to use as your next pointer. Inclusive — expect re-delivery around the boundary and dedupe by reference. See “Fetching what changed”.
Scan object
referencestringScan reference (scn_…).
ticketstring | nullThe scanned ticket (tkt_…).
resultstringallowed or denied.
reasonstringVerdict key — scanning.allowed, scanning.already_scanned, ….
scanner_locationobject | nullThe lane that scanned — {reference, name} — or null for online and staff check-ins.
sessionobject | nullThe occurrence the scan resolved to — {reference, name, starts_at}; null on single-date events.
scanned_atstringWhen the device scanned, UTC — device time, hours old on offline uploads.
created_atstringWhen the platform recorded the row, UTC.
updated_atstringWhat ?updated_since= compares against. Scans never change, so this is the moment the row landed — late offline uploads enter your sweep when they arrive.
Example
curl "https://api.frequentix.com/v1/integration/events/evt_01k0zqj4d8v6snb2x9e7g3m5cr/scans?updated_since=2026-10-02T18%3A00%3A00Z" \
-H "Authorization: Bearer $FREQUENTIX_TOKEN"{
"data": {
"current_page": 1,
"data": [
{
"reference": "scn_01k2p9av6r8tw2x5c0e3g6h9jk",
"ticket": "tkt_01k2f1rf2p9xz4w7b1m6d8e0hs",
"result": "allowed",
"reason": "scanning.allowed",
"scanner_location": {
"reference": "loc_01k0zqj6bh2uy5w8x1a4c7e0fn",
"name": "Main doors"
},
"session": null,
"scanned_at": "2026-10-02T18:41:27.000000Z",
"created_at": "2026-10-02T19:03:04.000000Z",
"updated_at": "2026-10-02T19:03:04.000000Z"
}
],
"first_page_url": "https://api.frequentix.com/v1/integration/events/evt_01k0zqj4d8v6snb2x9e7g3m5cr/scans?page=1",
"from": 1,
"last_page": 1,
"last_page_url": "https://api.frequentix.com/v1/integration/events/evt_01k0zqj4d8v6snb2x9e7g3m5cr/scans?page=1",
"links": [
{
"url": null,
"label": "« Previous",
"active": false
},
{
"url": "https://api.frequentix.com/v1/integration/events/evt_01k0zqj4d8v6snb2x9e7g3m5cr/scans?page=1",
"label": "1",
"active": true
},
{
"url": null,
"label": "Next »",
"active": false
}
],
"next_page_url": null,
"path": "https://api.frequentix.com/v1/integration/events/evt_01k0zqj4d8v6snb2x9e7g3m5cr/scans",
"per_page": 25,
"prev_page_url": null,
"to": 1,
"total": 1
}
}scanned_at is the device's clock; updated_at is the platform's. The incremental pointer walks updated_at, so scans a device batched offline and uploaded later still enter your sweep when they land — a scanned_at cursor would miss them.
Denied attempts appear too, with their reason — useful for door-fraud reporting; filter on result yourself if you only want admissions.
Create a webhook subscription
/v1/integration/webhookswebhooks:writeSubscribe a URL to one or more event names (the REST-hook model automation platforms use). Deliveries ride the ordinary webhook pipeline: signed, retried, auto-disabled on repeated failure.
Query parameters
urlstring (body, required)A public https/http endpoint — internal addresses are refused.
eventsarray (body, required)Event names from the subscribable catalogue.
eventstring (body, optional)Pin the subscription to one event (evt_…). Required for clients limited to specific events; omit for organiser-wide.
Subscription object (create includes `secret`)
referencestringSubscription reference (whk_…).
urlstringThe endpoint deliveries are POSTed to.
eventsarrayThe event names this subscription receives.
eventstring | nullReference of the single event the subscription is pinned to; null means organiser-wide.
is_activebooleanWhether deliveries are live.
disabled_reasonstring | nullWhy the subscription was deactivated (repeated failures, or its client being revoked).
created_atstringWhen it was created, UTC.
secretstringSigning secret (whsec_…) — present on the create response only, never shown again.
Example
curl -X POST "https://api.frequentix.com/v1/integration/webhooks" \
-H "Authorization: Bearer $FREQUENTIX_TOKEN" \
-H "Content-Type: application/json" \
-d '{"url": "https://hooks.example.com/frequentix", "events": ["order.created"]}'{
"data": {
"reference": "whk_01k2pa3c8t0vx4z7d2f5h8j1kn",
"url": "https://hooks.example.com/frequentix",
"events": [
"order.created"
],
"event": null,
"is_active": true,
"disabled_reason": null,
"created_at": "2026-08-22T15:02:48.000000Z",
"secret": "whsec_k3H9mQx2vT7bN4cW8pR1yD6fL0sJ5aZgEuVrOiMn"
}
}The signing secret is returned once, here, and never again.
A client may only see and delete its own subscriptions; ones configured in the console are invisible to it.
Creation is plan-gated exactly like the console (webhooks are a Pro feature); existing subscriptions keep delivering if the plan lapses.
List webhook subscriptions
/v1/integration/webhookswebhooks:writeThe subscriptions this client created, newest first — without secrets.
Query parameters
pageintegerPage number, starting at 1. Ignored when updated_since is present (cursor pages).
Subscription object
referencestringSubscription reference (whk_…).
urlstringThe endpoint deliveries are POSTed to.
eventsarrayThe event names this subscription receives.
eventstring | nullReference of the single event the subscription is pinned to; null means organiser-wide.
is_activebooleanWhether deliveries are live.
disabled_reasonstring | nullWhy the subscription was deactivated (repeated failures, or its client being revoked).
created_atstringWhen it was created, UTC.
Example
curl "https://api.frequentix.com/v1/integration/webhooks" \
-H "Authorization: Bearer $FREQUENTIX_TOKEN"{
"data": {
"current_page": 1,
"data": [
{
"reference": "whk_01k2pa3c8t0vx4z7d2f5h8j1kn",
"url": "https://hooks.example.com/frequentix",
"events": [
"order.created"
],
"event": null,
"is_active": true,
"disabled_reason": null,
"created_at": "2026-08-22T15:02:48.000000Z"
}
],
"first_page_url": "https://api.frequentix.com/v1/integration/webhooks?page=1",
"from": 1,
"last_page": 1,
"last_page_url": "https://api.frequentix.com/v1/integration/webhooks?page=1",
"links": [
{
"url": null,
"label": "« Previous",
"active": false
},
{
"url": "https://api.frequentix.com/v1/integration/webhooks?page=1",
"label": "1",
"active": true
},
{
"url": null,
"label": "Next »",
"active": false
}
],
"next_page_url": null,
"path": "https://api.frequentix.com/v1/integration/webhooks",
"per_page": 25,
"prev_page_url": null,
"to": 1,
"total": 1
}
}Delete a webhook subscription
/v1/integration/webhooks/{reference}webhooks:writeRemove one of this client's subscriptions; deliveries stop immediately.
Path parameters
referencestringThe subscription's reference (whk_…).
Response
messagestringConfirmation message.
Example
curl -X DELETE "https://api.frequentix.com/v1/integration/webhooks/whk_01k2pa3c8t0vx4z7d2f5h8j1kn" \
-H "Authorization: Bearer $FREQUENTIX_TOKEN"{
"message": "Webhook subscription deleted."
}