API reference
Authentication
Two flavors of auth:
- Browser ingestion — uses your
site_key+Allowed origins. No secret needed (and you can't keep one). - Server-side ingestion + public read API — uses your app's
secret_keyviaAuthorization: Bearer <secret>. Rotate it from the dashboard.
Ingestion — POST /v1/i
Endpoint base: https://api.www.useanalisa.com/v1/i
POST /v1/i
Content-Type: application/json
Authorization: Bearer <secret_key> # required for server-side; browser uses site_key
{
"site_key": "YOUR_SITE_KEY",
"batch": [
{
"event": "page_view",
"ts": 1715346000000,
"url": "https://example.com/pricing",
"path": "/pricing",
"referrer": "https://google.com/",
"anon_id": "anon_abc",
"session_id": "sess_xyz",
"user_id": "user_123", // optional
"utm": { "source": "google", "medium": "cpc", "campaign": "launch" },
"lang": "en-US",
"tz": "America/Sao_Paulo",
"viewport": { "w": 1920, "h": 1080 },
"screen": { "w": 1920, "h": 1080 },
"props": {}
}
]
}Response 200: {"ok":true,"received":1}.
Common error codes: 400 invalid payload, 401 unauthorized, 403 origin not allowed, 402 quota exceeded, 413 payload too large.
Public read API
Base: https://www.useanalisa.com/api/v1/public. All endpoints require from and to (ISO 8601) and accept an optional siteKey (must match the secret) and limit. Auth via Authorization: Bearer <secret_key>.
Windows are capped: up to 366 days for the report endpoints, up to 7 days for errors and snapshot (they read raw events for freshness). Errors always come back as JSON: {"error":"..."} with 400 (bad window), 401 (bad or missing secret), 403 (site paused or siteKey mismatch), 429 (rate limited, see Retry-After) or 500.
GET /api/v1/public/overview
Returns pageviews, unique_visitors, sessions, and a timeseries.
curl "https://www.useanalisa.com/api/v1/public/overview?siteKey=YOUR_KEY&from=2026-05-01&to=2026-05-08" \ -H "Authorization: Bearer YOUR_SECRET"
GET /api/v1/public/top-pages
Top pages by pageviews/uniques.
GET /api/v1/public/referrers
Top referrer sources.
GET /api/v1/public/countries
Top countries.
GET /api/v1/public/errors
JavaScript error groups seen in the window (captured automatically by the SDK), most frequent first. Aggregates only: no IPs, user ids, session ids or full stacks — just the top frame.
curl "https://www.useanalisa.com/api/v1/public/errors?from=2026-09-29T10:00:00Z&to=2026-09-29T11:00:00Z" \
-H "Authorization: Bearer YOUR_SECRET"
{
"from": "2026-09-29T10:00:00.000Z",
"to": "2026-09-29T11:00:00.000Z",
"errors": [
{
"fingerprint": "1x9k2",
"type": "TypeError",
"message": "x is undefined",
"count": 2,
"users_affected": 2,
"first_seen": "2026-09-29T10:10:00Z",
"last_seen": "2026-09-29T10:20:00Z",
"handled": false,
"kind": "onerror",
"sample_path": "/checkout",
"top_frame": "at pay (checkout.js:10:5)"
}
]
}GET /api/v1/public/snapshot
Traffic, conversions (per goal) and Web Vitals p75 for the window, plus the same window one week earlier as baseline — same weekday, so weekly seasonality doesn't look like a drop. deltas are percent changes, null when the baseline is zero. Each vital carries its samples count so you can ignore a p75 computed from too few pageviews.
curl "https://www.useanalisa.com/api/v1/public/snapshot?from=2026-09-29T10:00:00Z&to=2026-09-29T11:00:00Z" \
-H "Authorization: Bearer YOUR_SECRET"
{
"current": { "from": "...", "to": "...", "visitors": 5, "pageviews": 10, "sessions": 5,
"conversions": 2, "goals": [{ "id": "...", "name": "Signup", "conversions": 2 }],
"web_vitals": { "LCP": { "p75": 3250, "samples": 4 }, "INP": { "p75": null, "samples": 0 }, ... } },
"baseline": { ...same shape, 7 days earlier... },
"deltas": { "visitors": -50, "pageviews": -50, "conversions": -50 }
}GDPR endpoints
See GDPR & privacy for POST /api/gdpr/export and POST /api/gdpr/delete.
Rate limits
- Ingestion: 100 KB/request, 1000 events/batch, no fixed RPS cap (we throttle abusive IPs).
- Public read API: 120 requests/minute per site by default (
RATE_LIMIT_PUBLIC_READSwhen self-hosting).429withRetry-Afterif exceeded.