Errors & limits
REST API
Section titled “REST API”Errors are JSON with a single error key. There is no error code enum and no
request id.
| Status | Body | Cause |
|---|---|---|
200 |
the payload | |
400 |
{"error":"unknown dimension","allowed":[…]} |
Breakdown only; the allowed list is included |
401 |
{"error":"Missing or invalid API key"} |
Missing, malformed or revoked key. Sent with WWW-Authenticate: Bearer |
404 |
{"error":"site not found"} |
The site does not exist, is deleted, or belongs to another account |
A site belonging to someone else is a 404, never a 403 — the API does not
confirm that it exists.
Things that are not errors
Section titled “Things that are not errors”| Input | Behaviour |
|---|---|
An unrecognised range |
Falls back to 30d |
| An unrecognised filter parameter | Ignored |
limit out of bounds |
Clamped to 1–500 |
| A filter that matches nothing | 200 with zeros or [] |
| An event name that does not exist | 200 with a zero-valued shape |
Build clients that check the values, not just the status.
Limits
Section titled “Limits”| Limit | Value |
|---|---|
| Breakdown rows | limit, 1–500, default 20 |
| Event list | 100 events |
| Property keys | 50 |
| Property values | 25 |
| Histogram bins | 12 |
| Realtime feed | 30 events |
| CSV breakdown sections | 500 rows each |
| CSV visits | 5000 rows |
| Session timeline | 500 hits |
Collector
Section titled “Collector”Different service, different rules. The collector at
https://ingest.tracing.tools answers the tracker.
| Status | Body | Cause |
|---|---|---|
202 |
{"m":"hash"} |
Accepted and written |
202 |
(empty) | Accepted and dropped: excluded IP, bot user agent, or excluded path |
304 |
— | /t.js with a matching If-None-Match |
400 |
bad payload |
Unparseable JSON, or missing s / u |
400 |
bad url |
The page URL would not parse, or has no hostname |
404 |
{"error":"unknown site"} |
The public key is not a live site |
413 |
payload too large |
Body over 32 KiB |
The collector answers before the database write completes, so a 202 means the
payload was accepted, not that it is queryable yet. In practice the lag is
milliseconds.
Collector limits
Section titled “Collector limits”| Limit | Value |
|---|---|
| Request body | 32 KiB |
| URL parsed | first 2000 characters |
| Event name, title | 500 characters |
| Referrer | 2000 characters |
| Language | 35 characters |
| Property / trait key | 200 characters |
| String property / trait value | 500 characters |
| Properties or traits per hit | 50 |
| Flushed duration | clamped to 0–30 minutes |
Values over a limit are truncated, not rejected. Properties past the 50th are dropped silently.