Authentication
The REST API lives on the dashboard host, not the collector.
https://tracing.tools/api/v1Pro API access is a paid-plan feature. See Plans & limits.
Creating a key
Section titled “Creating a key”Settings → API keys → Create key. Give it a name you will recognise
(Metabase, weekly report, staging).
The plaintext is shown once:
tk_live_9f3c1a7b2d5e8460b1c4a9f7e2d3506aOnly a SHA-256 digest of the key is stored, so a leaked database gives nobody a working key — and nobody, including support, can recover a key you did not copy. Lose it and you create a new one.
The list shows each key’s name, its last four characters, when it was created and when it was last used. Revoking takes effect immediately.
Sending it
Section titled “Sending it”curl -s \ -H "Authorization: Bearer tk_live_9f3c1a7b2d5e8460b1c4a9f7e2d3506a" \ "https://tracing.tools/api/v1/sites"const response = await fetch("https://tracing.tools/api/v1/sites", { headers: { authorization: `Bearer ${process.env.TRACING_API_KEY}` },});const { data } = await response.json();import os, requests
r = requests.get( "https://tracing.tools/api/v1/sites", headers={"Authorization": f"Bearer {os.environ['TRACING_API_KEY']}"}, timeout=30,)r.raise_for_status()sites = r.json()["data"]The scheme is matched case-insensitively and the token is trimmed, so
bearer tk_live_… works too.
Every request resolves the caller’s account from the key, then looks the site
up inside that account. A site id belonging to someone else is a 404, not
a 403 — the API does not confirm that it exists.
Identifying a site
Section titled “Identifying a site”Every site endpoint accepts either form in the path:
| Form | Example |
|---|---|
| Site id (UUID) | /api/v1/sites/6f2b1e7c-9a54-4f21-8c3a-1d0b7e5f4a92/stats |
| Public key | /api/v1/sites/pk_live_a91c3f04/stats |
Anything matching 36 characters of hex and hyphens is treated as an id; everything else is treated as a public key. The public key is usually more convenient — it is the value already in your HTML.
Last used
Section titled “Last used”Every authenticated request stamps the key’s lastUsedAt, fire-and-forget: a
failed stamp never fails the request. Use it in Settings to find keys nothing
is calling any more.
What is not here
Section titled “What is not here”- No rate limit is published or enforced. Be considerate: these endpoints
run real aggregate queries against Postgres. Cache on your side, and prefer
one wide
rangeover a loop of narrow ones. - No write endpoints. The API reads. Data gets in through the tracker, revenue included.
- No pagination cursors. Endpoints that limit results take a
limit. - No OAuth, no scopes, no key expiry.
Endpoints
Section titled “Endpoints”| Endpoint | Returns |
|---|---|
GET /sites |
Every site the key can read |
GET /sites/:id/stats |
Headline metrics, previous period and deltas |
GET /sites/:id/series |
Zero-filled time series |
GET /sites/:id/breakdown |
Top rows for one dimension |
GET /sites/:id/events |
Events, properties, values, histograms |
GET /sites/:id/realtime |
The live snapshot |
Every one of them accepts range and the
filter parameters.