POST /v1/track
POST /v1/track — emit a single event.
Emit a single analytics event. The most common write endpoint.
Auth
Required scope
ingest
Key kinds
pk_* (browser, origin-checked) · sk_* (server, no origin check)
Request
POST /v1/track
Authorization: Bearer {key}
Origin: {your-origin} ← only for pk_* keys
Content-Type: application/json{
"event": "signup",
"event_id": "evt_abc123",
"timestamp": "2026-05-16T19:00:00.000Z",
"anonymous_id": "u_abc",
"user_id": "user_42",
"session_id": "sess_xyz",
"url": "https://yoursite.com/?utm_source=facebook&utm_medium=cpc&fbclid=abc",
"path": "/",
"referrer": "https://l.facebook.com/",
"properties": { "plan": "free", "team_size": 4 }
}Field reference
event
yes
Event name. 1–128 chars. By convention, system events start with $ ($pageview, $identify).
event_id
no
Idempotency key, 1–128 chars.
timestamp
no
ISO 8601. Defaults to server time when the request lands.
anonymous_id
no
Caller-supplied UUID. If omitted, the Worker generates one — but you usually want to control this from the browser SDK.
user_id
no
If you've called /v1/identify, set this on subsequent events to link them to a person.
session_id
no
If omitted, derived as ${anonymous_id}-${30min_bucket}. Override for custom session boundaries.
url
no
Landing URL — including any utm_*, fbclid, gclid query params. The classifier reads this.
path
no
URL path. The browser SDK sets this automatically.
referrer
no
document.referrer value (or Referer header server-side). The classifier reads this.
properties
no
Free-form JSON, capped at 8 KB after JSON.stringify.
Response
The 202 means the event has been written to ClickHouse synchronously. Materialised views (daily_rollup, sessions) update within seconds.
What the server adds
The Worker enriches every event before insert:
Source classification —
source,medium,campaign,source_confidence,source_rule_id(see Attribution).Geo & device —
country(geo-IP, country code only),device_type,browser,os(parsed from User-Agent).Hashed IP —
ip_hash = HMAC(ip, IP_SALT || UTC_date). Raw IPs are never persisted.
You don't need to send any of these; if you do, they're ignored.
Errors
See overview. Common ones for track:
400 invalid_payload—eventmissing orpropertiesexceeds 8 KB.403 origin_not_allowed—pk_*key, butOriginisn't in the project's allowlist.429 rate_limited— burst over 200 requests; back off and retry.
Examples
curl (server-side)
Browser SDK
Node SDK
MCP
Last updated
Was this helpful?