Skip to main content
The Query API is the read path for your events. It returns the events that the GrainQL Tag and Analytics Web sent, as JSON, so that you can export them or show them in your own dashboard. The Query API needs the Starter plan or higher. Read Plans and limits.

Base URL

https://queryapis.grainql.com/v1/api/query
Every path on this page and on the endpoint pages is relative to the base URL.

Authentication

Every request carries an API key in the X-API-Key header and a JSON content type.
Create the key in the dashboard:
  1. Open Settings, then API keys, at https://grainql.com/dashboard/settings/api-keys.
  2. Click Create key.
  3. Enter a name for the key.
  4. Under Access, select Query API.
  5. Copy the key. The dashboard shows it one time.
The Query API key is independent of the Analytics Web authStrategy. The key works when the SDK uses NONE, SERVER_SIDE, or JWT. Read Authentication.
Keep the API key in an environment variable on a server. Do not commit it to version control, and do not put it in browser code.

Endpoints

{tenantAlias} is the tenant alias that the dashboard shows. It is not the tenant UUID. A UUID in the path returns 404. Filters are the same on the query and count endpoints. Read Filters. The Query API does not write events. Send events with the GrainQL Tag or Analytics Web. Analytics Web has no Query API methods, so call these endpoints with an HTTP client.

Rate limits

The limit applies per workspace. Every API key of the workspace counts against the same limit. The limit is the same on every plan.

Rate limit headers

Every response carries three headers:
A request over the limit gets 429 and a Retry-After header with a number of seconds:
If the API returns 429, wait Retry-After seconds, then retry the request one time.

Errors

Every error body is a JSON object with an error string. A 429 body also has message and retryAfter. A filter with an unknown property path, an unknown operator, or a value of the wrong type also returns an error body. Read Filters.

Request format

The two POST endpoints take a JSON body. GET /events/{tenantAlias} takes no body.

Response format

POST /{tenantAlias} returns an array of event objects:
POST /count/{tenantAlias} returns one object:
GET /events/{tenantAlias} returns an array of strings:

Limits