Skip to main content

Account

List sites

The sites this credential can read.

GET/sites
List sites
curl --request GET \
  --url 'https://truestat.io/api/v1/sites' \
  --header 'Authorization: Bearer <token>'
{
  "data": [
    {
      "id": "6fed8980-a119-4a9c-a4d4-53e448ef9f9e",
      "name": "codivupload.com",
      "active": true,
      "domain": "codivupload.com",
      "timezone": "UTC",
      "created_at": "2026-09-03T18:02:11.000Z",
      "first_event_at": "2026-09-03T18:40:02.000Z"
    }
  ],
  "meta": {
    "page": {
      "limit": 100,
      "offset": 0,
      "has_more": false
    }
  }
}

The first call most integrations make, because every other endpoint needs a site id.

What a credential can see

An API key

The sites of the organisation that owns the key — narrowed further when the key was issued for specific sites.

A personal login

The sites of every organisation you have an accepted membership in, honouring any per-site scope on that membership.

Two details on the personal path that are easy to get wrong if you build something similar yourself: a pending invitation is not access, and a member scoped to a subset of an organisation's sites sees only those. Both are applied here.

The site key is not in the response

Deliberately. The site key is a write credential — it belongs in your tracking snippet and the dashboard shows it once when you add a site.

An endpoint that handed it back would turn any read-only API key into one that can forge traffic into your account.

first_event_at tells you what kind of quiet

null means no event has ever arrived: the site was created and the script was never installed, or was installed wrongly.

A date means measurement started then. A site with a date and no traffic today is simply quiet, which is a different problem from one that was never wired up — and the two look identical from a visitor count alone.

Paging

Ordered newest first. limit and offset work as everywhere else, and meta.page.has_more is measured rather than inferred.

This endpoint needs the sites:read scope. A key with only analytics:read can query a site it already knows the id of, but cannot list them — 403 insufficient_scope.

Past the quota, this closes too

If the account has outgrown its plan, this endpoint answers 402 quota_exhausted rather than listing sites.

That mirrors the dashboard, which shows a customer past the ceiling the billing screen and nothing else — not their analytics and not the list of which sites they have. Usage and account keep answering, so an integration can still find out what is wrong and say so.

Authorizations

Authorizationstringheaderrequired

An API key from Settings → API keys. Scopes available: analytics:read, sites:read, sites:write, settings:read, settings:write, goals:read, goals:write, funnels:read, funnels:write, notes:read, notes:write, alerts:read, alerts:write, team:read, team:write, revenue:read, revenue:write.

Bearer authentication header of the form Bearer <token>, where <token> is your auth token.

Query parameters

limitintegerquerydefault: 100
Rows per page, 1 to 1000.
offsetintegerquerydefault: 0
Rows to skip.

Response

application/json

The answer.

dataunknown
See the example.
metaobject