Skip to main content

Getting started

Authentication

Every request carries a bearer token.

Every request carries a bearer token.

Authorization: Bearer ts_live_a1b2c3d4e5f6...
curl "https://truestat.io/api/v1/sites" \
  -H "Authorization: Bearer $TRUESTAT_API_KEY"

That is the whole of it. No signing, no timestamps, no nonces.

Get a key

Getting an API key.

HTTPS is required

Requests over plain HTTP are refused. A key sent unencrypted is a key that has been disclosed.

What a key can reach

A key is bound to your organisation and, optionally, to specific sites.

  • Organisation is the outer boundary. A key cannot read another organisation's data under any circumstances, including a site id belonging to one.

  • Sites narrow it further. A key with no sites named reads every site in your organisation, including ones added later.

Every request resolves what the caller may read before any query runs. Passing a site id you do not have access to returns the same response as passing one that does not exist — see Errors.

Scopes

A key carries exactly the permissions you tick when you create it, one resource at a time, read and write separately:

ResourceReadWrite
Analyticsanalytics:read—
Websitessites:readsites:write
Settingssettings:readsettings:write
Goalsgoals:readgoals:write
Funnelsfunnels:readfunnels:write
Notesnotes:readnotes:write
Alertsalerts:readalerts:write
Teamteam:readteam:write
Revenuerevenue:readrevenue:write

Analytics has no write column, and the dash is a real answer rather than a box left unticked: traffic is measured, not set. There is nothing to write.

A key defaults to analytics:read alone. Every other permission is granted deliberately — a key that can change what your site measures is not a reasonable default for "give me my numbers".

Granting a write ticks its read as well. A key that could change an alert it cannot see would be nobody's intent.

What no key can do, whatever you tick

Mint another key

There is no api_keys scope. A credential that issues credentials turns one leak into permanent access, so keys are created in the dashboard by an organisation admin and nowhere else.

Delete a site

Irreversible, and dashboard-only. The same applies to reading any secret back: integration credentials and key plaintexts are never returned by any endpoint.

revenue:write is narrower than it sounds. It connects, disconnects and re-syncs a payment provider — it cannot post a payment. Revenue arrives from the provider and is reconciled against it; a figure you could POST would be a figure your Stripe account has never seen.

If a key leaks

What it reaches is exactly what you ticked. A read-only key exposes your numbers; one with writes can change the things those writes name.

Revoke it — the effect is immediate, and anything written before the revocation stays written. Then create a replacement with the narrowest set of permissions that still does the job.

Expiry and revocation

A key stops working the moment it is revoked, and on its expiry date if it has one. Both produce 401 with invalid_credential — the same response as a garbage token, deliberately, so a caller learns "this credential does not work" rather than "this credential existed and was revoked at 14:02".

Last used

Every successful authentication updates the key's last-used timestamp, visible in the key list. It is what tells you whether a key is still part of something before you revoke it.

Recording it never blocks or slows your request.

Two other ways in — not for the API

The API takes an API key. For completeness, two other credentials exist in the product and neither is for /api/v1/:

Your dashboard session. The app's own requests use your signed-in session. That is not something to script against.

A share link. A read-only, anonymous view of one dashboard. See Public dashboards. It is a web page, not an API surface.

Keeping the key out of the wrong places

  • Server-side only. A key in browser JavaScript is public.

  • Environment variables, not source. A key in a repository is in every clone and in your git history permanently.

  • The ts_live_ prefix is designed to be greppable, so secret scanners can catch a key before it is pushed.

Testing your key

curl -i "https://truestat.io/api/v1/sites" \
  -H "Authorization: Bearer $TRUESTAT_API_KEY"

200 with a list of sites means the key works and tells you the site ids every other endpoint needs.

401 means the key is wrong, revoked or expired. 403 means the key is valid but does not cover what you asked for — a site it is not scoped to, or a scope it does not carry. It is not a tier problem: API access is on every plan.

See Errors.

Was this page helpful?

Last updated September 16, 2026