Wire schema v1
The schema is the load-bearing artifact — anything that speaks POST /v1/events is a valid backend. It is versioned separately from the package, and v1 will not break.
{
"batchId": "8f14e45f-ea31-4f7c-9c2a-1b0a6f0d2c11",
"sentAt": "2026-08-18T14:03:11.482Z",
"context": {
"appId": "com.example.MyApp",
"appVersion": "2.4.1",
"osVersion": "19.1",
"deviceModel": "iPhone17,2",
"locale": "en_US"
},
"events": [
{ "name": "paywall_shown", "at": "2026-08-18T14:03:10.201Z",
"seq": 4821, "installId": "…", "sessionId": "1755526990-04812733",
"props": { "variant": "b" } }
]
}Batching and delivery
Batches of at most 100 events and 256 KiB, byte limit applied first, never mixing two install ids or projects. One request in flight, exponential backoff from 1s with full jitter capped at 5 minutes, the same batch id across retries so dedupe works, and a 24-hour ceiling on delivery attempts.
Retention
Raw event rows for 90 days — the default window and the shortest we will run — and daily rollups kept indefinitely. Per-day history survives; the individual events behind it do not.
Deliberately never collected
IP storage, IDFA, IDFV, Keychain, device serial, location, free text, session replay. The list is normative — §13 of the schema, not a marketing promise.