For the complete documentation index, see llms.txt. This page is also available as Markdown.

Event schema

Full Zod schemas, ClickHouse columns, and what's required vs optional.

The single source of truth is packages/schema/src/index.ts — the Zod schemas the API validates against and the SDKs export. This page is a human-readable mirror.

TrackEventInput — POST /v1/track body

{
  event: string,                     // required, 1–128 chars
  event_id?: string,                 // 1–128 chars
  timestamp?: string,                // ISO 8601
  anonymous_id?: string,             // 1–128 chars
  user_id?: string,                  // 1–256 chars
  session_id?: string,               // 1–128 chars

  url?: string,                      // valid URL, ≤ 2048 chars
  path?: string,                     // ≤ 2048 chars
  referrer?: string,                 // ≤ 2048 chars

  properties?: Record<string, unknown>   // JSON-stringified ≤ 8 KB
}
Field
Required
Validation
Notes

event

yes

1–128 chars

Use snake_case. $-prefix reserved for system events.

event_id

no

1–128 chars

Idempotency / join key. No server-side dedup yet.

timestamp

no

ISO 8601

Server clock if omitted.

anonymous_id

no

1–128 chars

Caller-supplied UUID. Server fabricates if omitted.

user_id

no

1–256 chars

Set after /v1/identify.

session_id

no

1–128 chars

Auto-derived if omitted. See Sessions.

url

no

URL, ≤ 2048

Classifier reads this.

path

no

≤ 2048

Browser SDK fills this.

referrer

no

≤ 2048

Classifier reads this.

properties

no

≤ 8 KB stringified

Free-form JSON.

BatchInput — POST /v1/batch body

IdentifyInput — POST /v1/identify body

ForgetInput — POST /v1/forget body

ClassifiedSource — what the classifier returns

The full rule cascade is in Attribution.

EventRow — what gets inserted into ClickHouse

Partitioned by toYYYYMM(timestamp), ordered by (project_id, timestamp, event_id).

Materialised views

daily_rollup

Aggregates by (project_id, day, event_name, source, medium, country, device_type). Powers /v1/stats.

Column
Type

events

SimpleAggregateFunction(sum, UInt64)

uniques

AggregateFunction(uniq, String) (HLL over anonymous_id)

sessions

One row per (project_id, session_id, anonymous_id). Powers /v1/sources and revenue attribution. Schema in Sessions.

What's not in the schema

  • Email, name, address. Don't send PII.

  • Raw IP. Sent in the request, never persisted — we store HMAC(ip, IP_SALT || UTC_date) only.

  • City-level geo. Country only. We use Cloudflare's cf-ipcountry.

  • Cookies. None set by us.

Validation errors

A failed Zod parse returns 400 invalid_payload with the flattened error tree. Example:

See also

Last updated

Was this helpful?