Ingest contract
Watcher wire

The JSON the Watcher accepts.

Every event the Roundhall agent graph reasons over starts with a single JSON line POSTed at `/telemetry`. The shape below is the wire contract your SDK or game server must speak — the same shape the Watcher's first turn reads on the console.

docsTelemetry.shapeTable.title

Every inbound event is the same five keys at the root. The Watcher reads the top-level fields on its first turn; the `properties` map is event-shaped and validated per the worked example it matches.

FieldRequiredTypeDescription
eventrequiredstringEvent name — `session_start`, `level_up`, `purchase`, `churn_signal`, …
player_idrequiredstringStable per-player id; matches the same value that the Reporter reads back on the console.
session_idrequiredstringPer-session UUID. Replay the same id for every event in a session; rotate on cold start.
timestamprequiredISO 8601 UTCInstant the event was produced, formatted as `YYYY-MM-DDTHH:mm:ss.sssZ`. MUST carry the `Z` UTC suffix.
propertiesoptionalobjectEvent-shaped payload — see the worked examples below.

Worked examples

Each example is the exact JSON the Watcher expects for one of the four canonical events.

Each example is the exact JSON the Watcher expects for one of the four canonical events.

Emitted once on cold start. `properties.platform` is the store the player launched from.

{
  "event": "session_start",
  "player_id": "pl_8c2a91",
  "session_id": "5e9b3c40-7e6b-4f10-9b0c-1e8a3a4d5f60",
  "timestamp": "2026-04-12T09:14:22.018Z",
  "properties": {
    "platform": "ios",
    "app_version": "3.7.2"
  }
}

POST to <host>/telemetry

Send a single event to Roundhall's ingest endpoint at `<host>/telemetry`. Swap `<host>` for the API base your account was provisioned on, then run as-is.

docsTelemetry.curl.snippet

Pair with the wider surface

Console

Read the five KPIs every decision against.

LiveOps agents

Meet the four agents that act on this telemetry.