Account
Read API
Query your numbers from scripts and tools with read-only API keys.
The read API gives scripts, spreadsheets, notebooks and internal tools read-only access to a project's numbers: the same overview and insights you see in the dashboard. JSON in, JSON out.
Max plan
Read API keys are part of Max. See Plans and usage or the pricing.
API keys
Owners and admins create keys in the project's Keys & API page, under API keys (read-only). Give each key a name that says what uses it.
- Keys start with
vxr_. - A key reads one project only, and can't change anything.
- A key is shown once, right after you create it. Copy it then: it can't be shown again. The list only shows its first characters, who created it and when it was last used.
- You can revoke a key at any time. Requests with a revoked key get a 401.
Heads up
Unlike write keys, API keys read your data. Keep them secret: don't put them in a website or a game build.
Making requests
Send the key as a bearer token. Your project id is in the dashboard's address bar, right after /projects/.
curl -H "Authorization: Bearer vxr_YOUR_API_KEY" \
"https://api.anyanalytics.org/api/v1/projects/<projectId>/overview?range=30d"Endpoints
All paths are relative to /api/v1/projects/:projectId.
| Request | Returns |
|---|---|
GET / | The project: id, name, kind, timezone and domain. |
GET /overview | The project overview, with the query in the URL. |
POST /overview | The same, with the query as a JSON body. |
POST /query | Runs any trends, funnel, retention or paths query. |
GET /insights | Saved insights: id, name, description, query and when it was last updated. |
GET /insights/:insightId | A saved insight and its current result, as { insight, result }. |
Overview
The overview takes these parameters, in the query string or the JSON body:
| Parameter | Values |
|---|---|
range | today, 24h, 7d (default), 30d, 90d, 12m or custom |
from, to | With custom: the first and last day, inclusive, as YYYY-MM-DD, up to two years apart |
interval | hour, day, week or month. Defaults to the range's natural one. |
compare | true adds the previous period's series |
filters | A JSON array like [{"dim":"country","value":"FR"}]. A dimension is any breakdown (page, channel, referrer, country, browser, platform, event…) or goal with a goal id. Up to 10. |
curl -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d '{"range":"custom","from":"2026-09-01","to":"2026-09-30","filters":[{"dim":"channel","value":"Organic Search"}]}' \
"https://api.anyanalytics.org/api/v1/projects/<projectId>/overview"The response has the headline totals and the previous period's, the chart series and their buckets, the breakdowns for every dimension, your goals and the revenue currency. Times are wall-clock in the project's timezone. The numbers are defined in The dashboard.
Insight queries
POST /query takes { "query": { ... } } with the same query a saved insight holds. The easiest way to write one is to build it in the dashboard, save it, and read its query from GET /insights. A query without a kind is a trend; funnels, retention and paths set "kind" to "funnel", "retention" or "paths".
curl -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d '{"query":{"series":[{"event":"$pageview","metric":"unique_users"}],"dateRange":{"from":"-30d"},"interval":"day"}}' \
"https://api.anyanalytics.org/api/v1/projects/<projectId>/query"curl -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d '{"query":{"kind":"funnel","steps":[{"kind":"page","value":"/pricing"},{"value":"signup_completed"}],"dateRange":{"from":"-30d"}}}' \
"https://api.anyanalytics.org/api/v1/projects/<projectId>/query"Date ranges are relative ("-24h", "-30d") or a YYYY-MM-DD day, read in the project's timezone, and can cover up to two years.
Limits and caching
- Each key can make 300 requests per minute.
- Each key can have 8 requests in flight at once.
- Results are cached for a minute, so asking more often than that returns the same numbers.
- Browsers can call the API directly (CORS is open), since the key travels in a header.
Errors
Errors come back as JSON with an error field. When a response has a Retry-After header, wait that many seconds before trying again.
| Status | error | Meaning |
|---|---|---|
| 400 | validation_failed | The query is invalid; details says why. |
| 400 | invalid_range | The range is too long, or too many buckets for the interval. |
| 401 | invalid_api_key | The key is missing, unknown or revoked. |
| 402 | plan_required or a message | The organization's plan doesn't include the read API, or its trial has ended. |
| 404 | Project not found | The key belongs to another project. Unknown insights also answer 404. |
| 429 | rate_limited | Over 300 requests in a minute. |
| 429 / 503 | too_many_concurrent_queries | Too many queries running at once. Retry shortly. |