atrixANALYTICS
REST API

Capture API

The ingest endpoints the SDKs use, for languages without an SDK.

Ingest lives on your region's host, https://eu.i.analytics.atrix.dev for EU projects, and is authenticated by the project's public key in the body. Prefer an SDK where one exists: they handle batching, retries and deduplication for you.

POST /e

{
  "api_key": "atx_pk_eu_production_XXXXXXXXXXXXXXXXXXXXXX",
  "sent_at": "2026-09-25T10:00:05Z",
  "batch": [
    {
      "uuid": "01927f3e-8a7b-7c3d-9e0f-1a2b3c4d5e6f",
      "event": "order_completed",
      "timestamp": "2026-09-25T10:00:00Z",
      "distinct_id": "user_42",
      "properties": { "amount": 1999, "currency": "AED" },
      "lib": { "name": "import", "version": "1.0.0" }
    }
  ]
}

/batch is an alias of /e. Both also accept PostHog payloads, and ingest serves PostHog's /capture, /i/v0/e, /decide and Segment's /v1/* too: see Migrating.

Event fields

FieldRequired
uuidyesA UUIDv7 you generate. The deduplication key end to end: send the same uuid on retry.
eventyesThe event name. Names starting with $ are reserved; unknown ones are rejected.
timestampyesWhen it happened (RFC 3339). Corrected for clock skew using sent_at; future times are clamped.
distinct_idyesYour user id, or an anonymous device id. 1–200 characters. Never an email or phone number.
propertiesyesAn object. Money as integer minor units plus currency.
libyes{ name, version }. Hand-written integrations use "name": "import".
anon_idThe device's anonymous id, on every event before and after identify.
session_id, window_idUUIDv7 session and tab ids.
$set, $set_oncePerson properties to set.
groupsGroup type → key, at most 5 types.
consentgranted, pending or cookieless.

Limits

  • 1 to 1,000 events per request; 20 MB after decompression; 900 KiB per event.
  • 5,000 events per second per project sustained, bursting to 50,000. Beyond that: 429 with Retry-After.
  • Events older than the project's retention are rejected.

Compression

Content-Encoding: gzip or zstd, or ?compression=gzip-js|gzip|zstd|base64 for clients that cannot set headers (the browser SDK sends text/plain with ?compression=gzip-js to avoid a CORS preflight). Gzip and zstd bodies are also detected from their magic bytes. sendBeacon form bodies (data=…) are accepted.

Response

{ "accepted": 1, "rejected": [{ "uuid": "…", "reason": "clock_skew" }], "quota_limited": ["events"] }
  • rejected[].reason is one of invalid, too_large, reserved_name, clock_skew, duplicate.
  • quota_limited lists meters over their allowance. Events past the spend cap are sampled with weights, not cut off; kept events carry $sample_rate so counts stay statistically correct.
  • Errors are { "error": "…" }: 400 for a malformed body, 401 for a missing, unknown or revoked key (or a key from another region), 413 for a batch that is too large, 503 with Retry-After when ingest is briefly unavailable.

What ingest does to each event

  • Looks up the location from the IP address (country, region, city, time zone), then drops the address. $ip is never stored. Set $geoip_disable: true to skip the lookup.
  • Drops self-declared crawlers (not stored, not billed) and marks headless or datacenter browser traffic as suspect.
  • Drops duplicate uuids within a batch; storage deduplicates across batches.

CORS

Every response carries CORS headers without credentials. With no origin allowlist on the key, any origin is accepted; with one, only listed origins are (others get 403).

POST /r

Session-replay chunks: { api_key, sent_at?, chunks: [...] } with 1–50 chunks, each carrying session_id, seq, distinct_id, platform (web, ios, android, react-native, tauri), mode and 1–20,000 rrweb-compatible events. The answer lists sampled_out sessions and any rejected chunks. The SDKs and native recorders speak this for you.

POST /flags and GET /flags/definitions

Remote flag evaluation with the public key, and flag definitions for local evaluation with a flags secret key. See Feature flags.

POST /wh/{provider}/{token}

Revenue webhooks from Stripe, RevenueCat, the App Store and Google Play. See Revenue.

On this page