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

Authentication

The API uses OAuth 2.0 client credentials — a machine-to-machine grant with no user redirect flow. A client belongs to one organiser; its tokens read that organiser’s data and nobody else’s.

How it works

  1. An organiser admin creates an API client in the console and chooses its scopes and event access.
  2. Your system exchanges the client id and secret for a bearer token at the token endpoint.
  3. Every API request carries Authorization: Bearer <token>. Scopes are enforced on every route, and the tenant is pinned from the token itself.

Creating a client

In the console, open Settings → Integrations. Managing clients requires the integrations permission and a multi-factor-verified session.

  • The secret is shown once, at creation. Store it in a secret manager; it cannot be retrieved again.
  • There is no secret rotation — create a replacement client, move your integration over, then revoke the old one. Revoking a client also revokes its outstanding tokens.
  • A client’s event access can be edited after creation, and the change applies to already-issued tokens on their next request. Its scopes are fixed at creation — to change them, create a replacement client and revoke the old one.

Minting and caching tokens

Request a token
curl https://api.frequentix.com/oauth/token \
  -d grant_type=client_credentials \
  -d client_id=9e2c7a54-31d8-4a0b-9f3e-6b8d24c95a17 \
  -d client_secret=$FREQUENTIX_CLIENT_SECRET \
  -d "scope=events:read orders:read"
Response
{
  "token_type": "Bearer",
  "expires_in": 31536000,
  "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9…"
}
  • scope is space-separated — always request the scopes you need. Requesting one the client wasn’t granted is silently filtered out, so a superset request yields exactly what was granted; omitting scope mints a token with no scopes at all, which every scoped endpoint refuses.
  • Cache the token and reuse it until expires_in elapses — don’t mint one per request. On a 401, mint a fresh token and retry once.
  • Treat tokens like passwords: server-side only, never in a browser or mobile app.

Scopes

Grant a client only what its integration needs — reads for reporting and CRM sync, the writes for automation:

events:readList events; fetch one event with its ticket types.
orders:readList an event's orders or the organiser-wide feed; fetch one order by reference.
tickets:readList an event's tickets (filterable by order or status); fetch one ticket with its holder.
contacts:readList contacts, look one up by email, fetch one by reference.
scans:writeCheck a ticket in online — same rules as the door.
contacts:writeUpsert a contact by email — the CRM-to-frequentix sync direction.
webhooks:writeSubscribe, list and remove this client's own webhook subscriptions (REST hooks).
scans:readList an event's entry scans — the arrival feed pollers and webhook backfills read.

A token without the required scope receives a 403; see Errors & rate limits.

Event scoping

Independently of scopes, a client is granted either every event of its organiser or a selected list. Scoping is enforced fresh on each request:

  • Listing endpoints return only events the client covers.
  • Fetching anything outside the client’s scope returns a 404 — indistinguishable from an event that doesn’t exist, so existence is never revealed.
  • Re-scoping a client in the console applies immediately, including to tokens already issued.