Install & operate
API reference
Ingest
No authentication; the site id is the authorisation.
The tracker posts to /api/d; /api/collect
is the same endpoint under its original name, kept for existing integrations.
POST /api/d
Content-Type: application/json
{
"site": "SITE_ID",
"type": "pageview", // or "event"
"url": "/pricing?utm_source=x",
"referrer": "https://chatgpt.com/",
"name": "cta_click", // required when type=event
"props": { "plan": "pro" },
"identity": "user-id", // optional
"tag": "v2"
}
| Response | Meaning |
|---|---|
204 | Recorded. |
202 | Accepted but not stored — Do Not Track in strict mode. |
400 | Invalid body — the reason is in the JSON. |
404 | Unknown site id. |
429 | Monthly quota exceeded. |
Reading your data with an API key
Create a key in the dashboard under Workspace → API keys (workspace admins only). A key reads every site in its workspace and can change nothing — it is accepted only by the read endpoints, so there is no write it could reach. It is shown once; we store a hash of it.
Send it in the Authorization header. A key in the URL is refused with
401 rather than accepted, because URLs end up in logs.
# Which sites can this key read? curl https://app.vitrus.dev/api/sites -H "Authorization: Bearer vk_…" # Last 30 days — every number with the query that produced it curl "https://app.vitrus.dev/api/stats?site=SITE_ID&days=30" -H "Authorization: Bearer vk_…"
| Response | Meaning |
|---|---|
401 | Missing, unknown or revoked key — the same answer for all three. |
404 | The site is not in this key's workspace (or does not exist). |
429 | More than 600 requests a minute with this key. |
Live data and session replays are not available to keys: live is for the dashboard, and a recording is the one thing we would rather a leaked key could never fetch.
Query endpoints
Each takes an API key or a signed-in session, and passes through site access control — another
workspace's site id returns 404, not 403, so
existence is not leaked. days is the window (1–365), or use
from and to in epoch milliseconds.
| Endpoint | Returns |
|---|---|
GET /api/sites | The sites an API key can read (key only). |
GET /api/stats?site=&days= | Evidence bundle: query, parameters and result per metric. |
GET /api/digest?site=&days= | Digest plus evidence. &format=text for plain text. |
GET /api/funnel?site=&steps= | Funnel result. steps is a JSON array. |
GET /api/retention?site= | Cohort matrix, or why it cannot be computed. |
GET /api/sessions?site= | Sessions, newest first; /api/sessions/:id for one timeline. |
GET /api/users?site= | Identified users and their traits. |
GET /api/journeys?site= | The most common page paths. |
GET /api/performance?site= | Core Web Vitals at p50–p99. |
GET /api/gsc?site=&days= | Google Search Console clicks, impressions, CTR and position, with Google's request and answer — see Search Console. |
GET /api/revenue?site=¤cy=&by= | Revenue per currency, by dimension and over time — see Revenue. |
GET /api/geo?site= | Countries, regions, cities and coordinates. |
GET /api/export?site= | Raw events as CSV (up to 100,000 rows). |
GET /api/orgs/:id/usage | Quota status (session only). |
POST /mcp | MCP (JSON-RPC 2.0) — see MCP server. |