Overview
Base URL, conventions, shared parameters and errors.
Every route lives under /v2, for example https://api.analytics.remcostoeten.nl/v2/health. The live OpenAPI document is served at /v2/openapi/json, with interactive docs at /v2/openapi; the API reference on this site is generated from the same document.
Conventions
- Lists answer
{ data, nextCursor }; single resources answer{ data }. - Timestamps are ISO 8601 in UTC.
- Every response carries
x-request-id. - Aggregate reads of a public project are cached for 60 seconds (
Cache-Control: public, s-maxage=60); everything else isprivate, no-store. - Every list and breakdown also answers
format=csv|json|sql(orAccept: text/csv) with the whole list as one download, up to 1 million rows.
Shared query parameters
| Parameter | Values | Default |
|---|---|---|
from, to | ISO 8601 timestamps | last 30 days |
period | 24h, 7d, 30d, 90d, 12mo, all; ignored when from and to are set | 30d |
traffic | human (bot score under 50, no internal or localhost), bots (bot score 50 or more), internal (visitors marked internal), all | human |
environment | production (no preview deployments), preview (preview deployments only), all; applies on top of traffic | production |
filter[<dimension>] | a value, or !value to exclude; repeatable across dimensions | none |
limit, cursor | up to 100; opaque cursor from the previous page | 20 |
An unknown dimension answers 400 VALIDATION_FAILED, in breakdown/:dimension and in filter[<dimension>] alike.
Events the server client sends without a visitor or session share the id server. They count in pageviews, events and every breakdown of events, but never as a visitor or a session: visitors, sessions, bounce rate, session duration, pages per session, conversion rate, paths, retention, lifecycle, stickiness, the map's visitors, and the visitor, session and people lists leave them out.
Errors
Every error uses one envelope:
{
"error": {
"code": "VALIDATION_FAILED",
"message": "The request does not match the schema",
"details": { "fields": [{ "path": "/period", "message": "Expected union value" }] },
"requestId": "req_01J8Z3",
"docs": "https://api.analytics.remcostoeten.nl/v2/openapi#errors/VALIDATION_FAILED"
}
}| Status | Code | When |
|---|---|---|
| 400 | VALIDATION_FAILED | Body, query or path fails the schema; details lists each field |
| 401 | UNAUTHORIZED | No or invalid session, token or key |
| 401 | AUTH_REQUIRED | The dev widget bootstrap was called without a session cookie |
| 403 | FORBIDDEN_ORIGIN | Public key used from an origin not in the project's list |
| 403 | ORIGIN_NOT_ALLOWED | The dev widget bootstrap's origin is in no project's allowed origins |
| 403 | FORBIDDEN | The caller's role or token scope does not allow the action |
| 403 | WIDGET_REPORTS_DISABLED | Client reports sent to a project with widgetReports off |
| 404 | NOT_FOUND | Unknown route or resource, or a private project without access |
| 409 | CONFLICT | Creating something that exists |
| 413 | PAYLOAD_TOO_LARGE | Ingest body over 60 KB or more than 50 events, or a client report body over 16 KB |
| 429 | RATE_LIMITED | A rate limit was hit; Retry-After says when to try again |
| 500 | INTERNAL | Unexpected failure; the message never includes internals |
| 503 | UNAVAILABLE | The database or a configured service is unreachable, or a job is not configured |