Skip to main content

Reference

Endpoint reference

Base URL: https://truestat.io/api/v1/

Not available yet. These routes are designed and the queries behind them are built; the routes themselves are not. This page describes the planned surface. When it ships, this reference is generated from the same schemas the API validates against, so it cannot drift from the implementation.

Base URL: https://truestat.io/api/v1/

All endpoints are GET. All are read-only. All need an API key on the Pro tier.

The endpoints

MethodPathReturns
GET/sitesThe sites this key can read — start here for the ids
GET/sites/{id}/overviewThe headline totals. One small answer.
GET/sites/{id}/timeseriesBucketed views and visitors over time
GET/sites/{id}/breakdowns/{dimension}A ranked breakdown
GET/sites/{id}/summaryEverything the dashboard renders, in one call
GET/sites/{id}/ai/crawlersCrawler views by operator, with verification
GET/sites/{id}/ai/pagesWhich of your pages crawlers read
GET/usageYour event limit and consumption this period

Which one to call

/overview for a single number on a status page. It is one query.

/summary for a full dashboard rebuild. It fans out across every breakdown, so it is a much heavier call — do not poll it every 30 seconds for one figure.

/timeseries and /breakdowns/{dimension} for anything in between.

Breakdown dimensions

pages · referrers · channels · campaigns · keywords · countries · regions · cities · browsers · os · devices

channels and keywords have no equivalent in comparable products.

One-site keys

If a key is scoped to exactly one site, the {id} segment can be omitted — /api/v1/summary resolves to that site. It is a convenience only; the same authorisation runs either way.

Shared parameters

Apply to /overview, /timeseries, /breakdowns/*, /summary and both /ai/* endpoints.

ParameterContract
from, toISO 8601. Must be given together — one alone is a 400.
periodInstead of from/to: today, yesterday, last24h, last7d, last30d, last12m, month, year, all. Resolved in the site's timezone. Combining it with from/to is a 400.
tzIANA timezone name. Defaults to the site's own.
unitTimeseries only: minute, hour, day, week, month.
limit, offsetBreakdowns only. limit defaults to 100, maximum 1000. offset defaults to 0.
botsexcluded (default) or included. Ignored by the /ai/* endpoints, which always include crawlers.
filter_*See below.

Filters

Flat query parameters, one per dimension:

filter_path          filter_path_pattern   filter_browser
filter_os            filter_device         filter_country
filter_region        filter_city           filter_referrer
filter_channel       filter_utm_source     filter_utm_medium
filter_utm_campaign  filter_utm_term       filter_bot_kind

Equality only. There is no is_not, no contains and no numeric comparison. The one exception is filter_path_pattern, which accepts * as a wildcard:

?filter_path_pattern=/blog/*

filter_bot_kind applies to the /ai/* endpoints and takes ai_assistant, ai_training, search or other.

Retention clamping

If your range reaches further back than your tier's retention window, you get the data that exists and the response says so — not an error, and not a silent truncation:

"meta": { "range": { "clamped": true, "from": "2023-08-24T00:00:00Z" } }

Retention is 3 years on Starter and 5 on Pro, and the API reads the same window the dashboard does. See Data retention.

The response envelope

One shape, on every endpoint, with no exceptions:

{
  "data": { },
  "meta": {
    "site_id": "…",
    "range": { "from": "…", "to": "…", "tz": "UTC", "clamped": false },
    "unit": "day",
    "bots": "excluded",
    "pagination": { "limit": 100, "offset": 0 }
  }
}

Errors use one shape too, with a symbolic code rather than a repeated HTTP status:

{ "error": { "code": "insufficient_scope", "message": "…" } }

error.message never contains anything from your request. See Errors.

Adding a field to data is not a breaking change. Read the fields you need and ignore the rest.

Pagination

limit and offset on breakdowns. There is no cursor.

meta.pagination carries limit and offset and not a total, because the underlying queries do not compute one. Rather than fabricate a number, it is absent. To tell whether more rows exist, ask for one more than you need.

What is not here, and will not be

Why
/visitors, /visitors/{id}Needs cross-day person identity TrueStat is built without. Not deferred — not this product.
Anything writing eventsUse the tracking script.
Revenue, payments, goal analytics, funnelsThose features do not exist.
Site, key, team and settings managementDashboard only. Every write endpoint is authorisation surface with no demand behind it.
fields projectionRows are two or three columns. A projection layer would buy nothing.

What is deferred, not refused

Note
/realtimeA live visitor count. Cheap and genuinely wanted; first candidate after the initial set.
Bounce rate, session durationNot on the dashboard either. Those come first.
Filter operators (is_not, contains)Would mean rewriting the predicate every dashboard number flows through. Deliberate, or not at all.
Hostname breakdownFor multi-domain sites.
An MCP serverDesigned to be a thin adapter over these routes once they exist.
Was this page helpful?

Last updated August 28, 2026