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

POST /v1/batch

POST /v1/batch — emit up to 1000 events in one call.

Send up to 1000 events in a single request. Used by the browser SDK for buffered flushes (every 20 events or every 2 seconds, whichever comes first).

Auth

Required scope

ingest

Key kinds

pk_* · sk_*

Request

POST /v1/batch
Authorization: Bearer {key}
Origin: {your-origin}              ← only for pk_* keys
Content-Type: application/json
{
  "events": [
    { "event": "$pageview", "anonymous_id": "u_abc",
      "url": "https://yoursite.com/?fbclid=abc" },
    { "event": "click",     "anonymous_id": "u_abc",
      "properties": { "button": "cta" } }
  ]
}

Each element in events follows the same schema as POST /v1/track.

Response

Limits

  • Max events per batch: 1000. Over the limit returns 400 invalid_payload.

  • Total payload size: bounded by the 8 KB-per-event properties cap × event count.

  • Rate limit: 5 batch requests/sec, burst of 20 per project (separately from /v1/track).

Atomicity

A batch is all-or-nothing at the request level — the Worker either inserts every event or returns an error. ClickHouse itself batches the insert as a single JSONEachRow payload. If validation fails on event #4 of 50, no events are written.

Why batch

  • Browser SDK uses it to coalesce navigations + interactions, reducing request volume by ~20×.

  • Server backfills of historical data — pipe N events from a CSV, batch into chunks of 1000.

  • Idempotent replays — if you set event_id on each event, you can safely re-run a batch (no server-side dedup yet — that's still your job).

Example: server backfill

Last updated

Was this helpful?