Skip to content

GraphQL

Read a site's raw events through GraphQL, with the same keys, limits and plan as the raw event API, and the schema, examples and errors.

Reference4 min read

GraphQL reads the same events as the raw event API, with the same keys. It comes with the Growth plan.

Production
Address
https://api.bifrostorbit.com/insights/graphql
Staging
Address
https://api-stage.bifrostorbit.com/insights/graphql

https://app.bifrostorbit.com/insights/api/cdn/graphql is the same endpoint.

GraphQL only reads. Send events with the script or the server API.

Requests

Send a key that reads events, starting with ins_live_, as Authorization: Bearer <key> or x-api-key: <key>, and POST a JSON body:

query
Type
string
Means
The GraphQL document. Required.
variables
Type
object
Means
Values for the query's variables
operationName
Type
string
Means
Which operation to run when the document has several
Shell
curl 'https://api.bifrostorbit.com/insights/graphql' \  -H 'Authorization: Bearer ins_live_…' \  -H 'Content-Type: application/json' \  -d '{"query":"query ($site: String!) { events(site: $site, from: \"2026-10-01\", to: \"2026-10-02\", type: \"event\") { items { name at path revenue currency } next } }","variables":{"site":"SITE_KEY"}}'

GET works too, with query, variables (as JSON text) and operationName in the query string. URL-encode them.

Answers are JSON with data, and errors when something went wrong:

JSON
{ "data": { "events": { "items": [{ "name": "Booked", "at": "2026-10-01T09:14:03.000Z", "path": "/checkout/", "revenue": 1240, "currency": "EUR" }], "next": null } } }

Keys belong on your server or data tool, never in a web page, so the endpoint answers servers only.

Queries

events
Arguments
site: String!, from, to, name, type, limit: Int, cursor
Returns
EventPage!. A site's events, oldest first. The arguments work as the parameters of GET/events: without from and to, the last 24 hours; limit is 100 by default and at most 1,000.

Types

EventPage
Fields
items: [Event!]!, and next: pass it as cursor, with the same other arguments, for the next page. null on the last page.
Event
Fields
id, type, name, at, host, path, referrer, channel, utm { source medium campaign term content }, country, device, browser, os, properties, revenue, currency, contentId, label, visit, person

properties is JSON, which holds the details sent with the event and cannot be selected into. No visitor is identified, as in REST. person is set only with known users switched on.

Example

Every booking in October, a page at a time:

graphql
query Bookings($site: String!, $cursor: String) {  events(site: $site, name: "Booked", from: "2026-10-01", to: "2026-11-01", limit: 500, cursor: $cursor) {    items {      at      path      channel      country      revenue      currency      properties    }    next  }}
JSON
{ "site": "SITE_KEY" }

Ask again with cursor set to next until it is null.

Errors

Errors come in errors, each with a message, a code under extensions, and the path and locations of the field that failed when there is one. The codes are the same as in REST:

JSON
{  "data": null,  "errors": [    {      "message": "There is no site with that key in your organisation",      "locations": [{ "line": 1, "column": 3 }],      "path": ["events"],      "extensions": { "code": "unknown_site" }    }  ]}
400
When
No query, variables that are not a JSON object, a query that does not parse or does not match the schema (bad_request), one over the limits (query_too_deep, query_too_complex), a date or type that isn't valid (invalid), or a cursor this API didn't give out (invalid_cursor)
401
When
The key is missing, wrong or removed (unauthorized)
403
When
The key may only send events (wrong_scope), or your plan doesn't include the API (not_in_plan)
404
When
No site with that key in your organisation (unknown_site)
413
When
A query longer than 20,000 characters (query_too_large)
429
When
Too many requests (rate_limited). Wait a minute.
500
When
Something failed on our side (internal). Try again.
200
When
Success

Limits

  • Each key may make 60 GraphQL requests a minute, counted apart from the raw event API's 60.
  • A query may be at most 20,000 characters long, nest at most 10 levels and ask for at most 300 fields. Each alias and each use of a fragment counts.
  • Introspection is on and needs no key, so GraphQL tools can read the schema from the address. Introspection fields do not count towards the limits.
  • Every answer has Cache-Control: no-store. The newest events can take a few seconds to show up.

Was this page helpful?

Read next