Docs
Stats API
Pull a site's numbers as JSON: totals, a time series, breakdowns by source, page, country and more, and goals. The same filters as the dashboard, so what you build matches what you see.
Authentication
Create a key under Settings → API keys and send it as a bearer token. A key belongs to one workspace, can read every site in it, and is shown once, when it is created. The API is included in every paid plan.
Authorization: Bearer gl_live_xxxxxxxxxxxxxxxxxxxxxxxxBase URL: https://glai.io
/api/v1/stats
Everything the dashboard shows for one site and one date range, in one call. Name the site by its public id or its domain. Add one or more filters and every number in the answer is narrowed to the sessions that match (a source=Google filter shows Google's pages, countries and revenue).
| Field | Type | Description |
|---|---|---|
| siterequired | string | The site's public id or its domain (with or without www). |
| range | string | today, yesterday, 7d, 30d (default), 90d, 12m, month, last_month, all, or custom with from and to. Days are in the site's time zone. |
| from, to | YYYY-MM-DD | The first and last day of a custom range. |
| dims | string | Comma-separated breakdowns to return (see Dimensions). Up to 20. |
| limit | number | Rows per breakdown, 1 to 200. Default 30. |
| <filter> | string | Any filter key with one value, e.g. source=ChatGPT&country=AU (see Filters). |
Filters
One value per key, exact match. Use (none) to select sessions where the value is unknown. Keys: source, source_type, referrer_host, country, region, city, device, browser, os, utm_source, utm_medium, utm_campaign, utm_content, utm_term, entry_path, exit_path, path, event. path selects sessions that viewed that page and event sessions that fired that event.
Dimensions
dims is a comma-separated list of the breakdowns to return, up to 20: source, source_type, referrer_host, path, entry_path, exit_path, country, region, city, device, browser, os, language, utm_source, utm_medium, utm_campaign, utm_content, utm_term, event, outbound. Without it the dashboard's default set is returned.
curl "https://glai.io/api/v1/stats?site=acme.com&range=30d&dims=source,path&source_type=ai" \
-H "Authorization: Bearer $GLAI_API_KEY"{
"statusCode": 200,
"success": true,
"message": "Stats.",
"data": {
"site": { "id": "k3m9p2x7q4wz", "name": "Acme", "domain": "acme.com", "time_zone": "Australia/Sydney", "currency": "USD" },
"range": { "key": "30d", "from": "2026-09-15T14:00:00.000Z", "to": "2026-10-14T23:12:08.113Z", "bucket": "day" },
"filters": { "source_type": "ai" },
"totals": {
"current": { "visitors": 3317, "sessions": 4021, "pageviews": 9870, "events": 412, "bounce_rate": 38.2, "avg_duration_s": 94,
"revenue_cents": 152000, "payments": 12, "customers": 11, "revenue_per_visitor_cents": 46, "conversion_rate": 0.33 },
"previous": { "visitors": 2480, "…": "…" }
},
"series": { "bucket": "day", "points": [ { "date": "2026-09-15", "visitors": 88, "sessions": 101, "pageviews": 240, "revenue": 4900, "payments": 1 }, "…" ] },
"breakdowns": {
"source": [ { "key": "ChatGPT", "label": "ChatGPT", "visitors": 2210, "sessions": 2704, "pageviews": 6410, "revenue_cents": 98000, "customers": 7, "share": 66.6, "icon": "logos:openai-icon", "type": "ai" }, "…" ],
"path": [ { "key": "/pricing", "label": "/pricing", "visitors": 1402, "pageviews": 1890, "revenue_cents": 0, "customers": 0, "share": 42.3 }, "…" ]
},
"goals": [ { "id": "…", "name": "Signed up", "type": "EVENT", "event_name": "signup", "path_pattern": null, "is_active": true, "value_cents": null,
"visitors": 61, "conversions": 63, "value_cents_total": 0, "conversion_rate": 1.84 } ]
}
}The response
The body is { statusCode, success, message, data }. Inside data:
| Field | Type | Description |
|---|---|---|
| siterequired | object | { id, name, domain, time_zone, currency }. Revenue is in the site's currency, in cents. |
| rangerequired | object | { key, from, to, bucket }: the range as resolved, with ISO instants. |
| filtersrequired | object | The filters that were applied, as sent. |
| totalsrequired | object | { current: Totals, previous: Totals }. |
| seriesrequired | object | { bucket, points: Point[] }. |
| breakdownsrequired | object | { <dim>: BreakdownRow[] } for every dimension asked for. |
| goalsrequired | Goal[] | The site's goals with their conversions in the range. |
Totals
totals.current and totals.previous (the same length of time just before the range) both hold:
| Field | Type | Description |
|---|---|---|
| visitorsrequired | number | Distinct visitors in the range. |
| sessionsrequired | number | Visits. A visit ends after the site's session gap without an event. |
| pageviewsrequired | number | Pageviews. |
| eventsrequired | number | Custom events and outbound clicks. |
| bounce_raterequired | number | Percent of visits with one pageview and no event (0 to 100). |
| avg_duration_srequired | number | Average visit length in seconds. |
| revenue_centsrequired | number | Payments minus refunds, in cents of the site's currency. |
| paymentsrequired | number | Number of payments. |
| customersrequired | number | Distinct paying customers. |
| revenue_per_visitor_centsrequired | number | revenue_cents divided by visitors. |
| conversion_raterequired | number | Customers as a percent of visitors (0 to 100). |
Series
series.bucket is hour for one day, day up to about 13 months, month beyond. series.points has every bucket of the range, empty ones included:
| Field | Type | Description |
|---|---|---|
| daterequired | string | "2026-10-14" for a day, "2026-10-14T09" for an hour, "2026-10" for a month, in the site's time zone. |
| visitors, sessions, pageviewsrequired | number | Counts in that bucket. |
| revenue, paymentsrequired | number | Revenue in cents (minus refunds) and number of payments in that bucket. |
Breakdown rows
Each breakdowns.<dim> is a list of rows sorted by visitors, with an unknown value shown as (none):
| Field | Type | Description |
|---|---|---|
| keyrequired | string | The raw value: "Google", "/pricing", "AU", "desktop", "(none)". |
| labelrequired | string | The value to show ("Unknown" for (none)). |
| visitorsrequired | number | Distinct visitors with that value. |
| sessions, pageviews, events | number | Whichever the dimension counts: sessions for session dimensions, pageviews for path, events for event and outbound. |
| revenue_cents, customersrequired | number | Revenue and paying customers whose first visit had that value (source, source_type, country, device, utm_source, utm_medium, utm_campaign; 0 elsewhere). For the event dimension, the value passed with the event. |
| sharerequired | number | Percent of the range's visitors (0 to 100). |
| icon, type | string | null | For the source dimension: the source's icon name and type (search, social, ai, email, paid, referral). |
Goals
One entry per goal of the site, with its conversions in the range:
| Field | Type | Description |
|---|---|---|
| id, name, typerequired | string | type is EVENT (an event name) or PAGE (a path pattern such as /thanks*). |
| event_name, path_patternrequired | string | null | What the goal matches. |
| is_active, value_centsrequired | boolean, number | null | Whether it counts, and a fixed value per conversion when set. |
| visitors, conversionsrequired | number | Distinct visitors who converted, and the number of conversions. |
| value_cents_total, conversion_raterequired | number | Value of the conversions, and converting visitors as a percent of all visitors. |
Errors and limits
Errors use standard HTTP status codes and a JSON body with a readable message.
| Status | Meaning |
|---|---|
| 400 | A parameter is missing or invalid (an unknown range, a bad date). The body names it. |
| 401 | The API key is missing, wrong, revoked or expired. |
| 402 | The workspace's plan does not include the API. |
| 404 | No site with that id or domain in the key's workspace. |
| 429 | Rate limit reached. Wait a minute and retry. |
Rate limit: 300 requests a minute per workspace. Each request may name up to 20 dimensions and return up to 200 rows per dimension (limit), so one call a minute is usually enough for a dashboard.