shiftzero

Events API (collector)

The collector's ingest and read surface. Writes take a publishable write key; reads take a private bearer token.

POST /events

Ingest a batch of exposure and/or conversion events. Authenticate with a write key — as ?wk= (browser beacons) or an Authorization: Bearer / x-shiftzero-key header (servers). Rate-limited per client; oversized bodies and batches are rejected.

request
POST /events?wk=szk_live_…
Content-Type: text/plain

[
  { "type": "exposure", "experimentId": "hero-test", "variantKey": "variant_b",
    "uid": "6f2c…", "url": "https://site.com/", "device": "mobile",
    "country": "GB", "timestamp": 1784900000000 },
  { "type": "conversion", "uid": "6f2c…", "metric": "purchase", "value": 89.0,
    "experiments": ["hero-test"], "timestamp": 1784900012345 }
]
response — 202 (or 207 with per-item errors)
{ "accepted": 2, "rejected": 0, "errors": [] }
FieldNotes
type"exposure" | "conversion"
uidThe visitor id — joins exposures to conversions during analysis.
experimentsConversion-only, optional. When present, the conversion is credited ONLY to these experiments (the track bridge stamps it from the edge bootstrap).
valueConversion-only, optional numeric value for revenue/continuous metrics.
device / countryExposure-only, optional — power result segmentation and audience reach.

Reads (bearer token)

EndpointReturns
POST /reportFull multi-metric analysis for one experiment: variants, lifts, CIs, sequential + fixed-horizon verdicts, Bayesian view, SRM. Body: { experiment, control, metrics: MetricSpec[], variantWeights?, targetN?, segment? }
GET /resultsOne metric scored: ?experiment=&metric=&agg=rate|count|value&direction=
GET /exposuresAnonymised recent-exposure sample (url/device/country, no uid) — audience reach estimation. ?limit= up to 5000
GET /diagnosticsPatch-health records: ?experiment=&limit=
GET /healthzLiveness — the only unauthenticated route
The write key is publishable (it can only add events, and ingestion is validated and rate-limited). The read token is private — it exposes your results. Configure them as INGEST_KEYS and READ_TOKEN on the collector.