Read a business’s data over the same GraphQL the Sessions app uses, authenticated with a server-to-server API key instead of a user session. The key is scoped to one business and sees a deliberately narrow, read-only slice of the schema.
How you call it
This API speaks GraphQL — you send a query for exactly the fields you want and get JSON back in the same shape, all over a single endpoint. New to GraphQL? The official documentation is the best place to start.
Endpoint
https://business.sessions.website/@<handle>/api/graphqlPOST your query to your business’s handle endpoint. The `@<handle>` segment is your business handle — the same one that appears in your Sessions URLs.
Authentication
There’s no user session — a scoped API key authenticates the request on its own, sent as a Bearer token over HTTPS.
Pagination
List fields use cursor pagination — pass `first` and an optional `after` cursor; each connection returns a `pageInfo` with `hasNextPage` and `endCursor`.
query {
activeBusiness {
participants(first: 25, after: "<cursor>") {
nodes { id }
pageInfo { hasNextPage endCursor }
}
}
}The read surface
Enter through `activeBusiness`, which resolves to the key’s own business, then traverse into participants and — from each participant — their registrations and purchases.
query {
activeBusiness {
id
name
participants(first: 25) {
nodes {
id
name
email
emailMarketingConsent { status at }
registrations(first: 10) {
nodes { id status confirmedAt activitySession { id } }
}
productPurchases(first: 10) {
nodes { id status pricePaid purchasedAt product { id } }
}
}
}
}
}A response is the same shape, with opaque GIDs you can carry into a webhook subscription or a follow-up query:
{
"data": {
"activeBusiness": {
"id": "gid://Sessions/Business/biz_3f9a",
"name": "Tremble Studios",
"participants": {
"nodes": [
{
"id": "gid://Sessions/BusinessParticipant/p_91ac",
"name": "Jordan Vega",
"email": "jordan@example.com",
"emailMarketingConsent": {"status": "granted", "at": "2026-06-01T14:32:08.000Z"},
"registrations": {
"nodes": [
{
"id": "gid://Sessions/ActivityRegistration/reg_77b2",
"status": "confirmed",
"confirmedAt": "2026-05-28T18:00:00.000Z",
"activitySession": {"id": "gid://Sessions/ActivitySession/s_4c10"}
}
]
},
"productPurchases": {"nodes": []}
}
]
}
}
}
}The surface is default-deny: only the fields shown here are reachable with a key. Anything else — internal columns, cross-area data, every mutation — returns a FORBIDDEN error, so the API can never widen by accident.
Rate limits
Requests are capped per key and, in aggregate, per business, so one client can’t starve the others and a business can’t multiply its budget by minting more keys.
Over the limit returns HTTP 429 with a Retry-After header (in seconds). Back off for that long, then retry.
Errors
Errors come back in the standard GraphQL `errors` array. Each carries a machine-readable `code` in its extensions.
`FORBIDDEN` — the key lacks the scope, or the field isn’t exposed externally. `RATE_LIMITED` — you’re over a rate limit; honour Retry-After.
Explore the types
The Business API reference lists every type and field a key can read, with the scope each one needs — generated straight from the live access policy, so it always matches what the API enforces.