Skip to navigation

Live revisions and prediction history

The same canonical mat_, ply_, trn_, edt_, drw_ and pnt_ identities are used across live states, predictions and historical publication. A live match can exist before inclusion in a named historical release. An older release is not changed to include it; hydrate its operational state with the live endpoints until historical publication is available.

Identity and correction rules

Identity/versionGrain and join
Match id / match_idBoth denote the same canonical match identity. The envelope uses match_id for routing.
player_idsFixed side order, shared by score, points and probabilities. Names are display data.
score_revisionChanges when normalized sets, game points, server, status or interruption reason changes. A repeated observation does not restart the enrichment deadline.
prediction_input_revision / prediction state_revisionFull model input version. These must match for a composed current prediction, even when the displayed score did not change.
Point id, sequence, revisionStable logical point identity, match-local ordinal and corrected payload version. Sequence is not a stream cursor or score revision.
prediction_idImmutable accepted model result. Recalculation creates another ID.
event_id and cursorCommitted stream event identity and global order. Lifecycle transition IDs are shared with their live events.

Source match identifiers, alternate player-name spellings and provider routing fields stay private. Conflicting identities and duplicate primary cards are rejected before public admission. Additional source observations must reconcile into the authoritative identity; name similarity alone does not create a second public match.

A score-only fallback has point_id: null. It remains associated with its exact score_revision. A later confirmed point is not retroactively attached to that immutable result.

Read current data and retained history

RequestResult
GET /v2/live/matchesPaginated tracked states; optional current status, tour, gender and category filters.
GET /v2/live/matches/{matchId}Current operational match projection.
GET /v2/live/matches/{matchId}/pointsLatest observed versions of the match’s unretracted points.
GET /v2/live/matches/{matchId}/status-historyObserved lifecycle transitions, including the preceding status and reason.
GET /v2/live/matches/{matchId}/predictionCurrent prediction state and freshness.
GET /v2/live/matches/{matchId}/predictionsImmutable accepted prediction history, ordered by history_sequence.
GET /v2/live/predictions/{predictionId}One immutable accepted result.

Filter prediction history with point_id and/or score_revision. Cursors are signed and bound to the account, route, match and filters; do not reuse them with different filters. History retention is 180 days for superseded results; the latest result can remain beyond that window. A removed or expired history record can return 404.

Polling should use a new ordinary GET request. Reusing an idempotency key is a retry of the original operation, not a request for a new polling sample. Pagination of operational live states is dynamic; use a named release for an immutable historical dataset.

For example, GET /v2/live/matches?status=cancelled selects currently cancelled tracked matches. Status history preserves an earlier interruption even if a match later resumed, including explicit terminal corrections. Statuses include scheduled, warmup, live, suspended, finished, retired, walkover, cancelled and unknown. A rain delay or play abandoned for the day is an interruption, not automatically a permanent cancellation.

Commentary is stored privately and deduplicated by content with snapshot links. Only normalized lifecycle state and an allowed interruption reason are public. Commentary text and general card insights are not stream or REST fields.

Time semantics and measured delay

ClockWhat it records
score_observed_atFirst time the collector observed this normalized score revision.
source_last_observed_atLatest source observation/heartbeat, including repeated score states.
score_received_atDatabase acceptance of the score revision.
Point source_observed_at, received_atFirst observation and acceptance of this point payload revision. A full prefix may reveal earlier points together.
enrichment_received_atAcceptance of the coherent enrichment used at inference admission.
prediction_requested_atAcceptance clock of the stored model input event. It can equal score_received_at; it is not the time an inference HTTP request started.
computed_atAcceptance/storage of the computed model result.
Event published_atOutbox event timestamp; delivery becomes visible after transaction commit.
Client receive timeRecord in your own process when the frame arrives. It is not a server-produced timestamp.

Clocks use UTC and preserve available microsecond evidence precision. Clock precision is not proof of physical event-time accuracy. score_observed_at is an observed pipeline boundary, not the time the ball was struck or the point ended on court.

Useful measurements are score_received_at - score_observed_at, prediction_requested_at - score_received_at, computed_at - prediction_requested_at, and your live receive time minus computed_at. The last two include queueing and transport, not only CPU inference time. Exclude replay frames from live-latency samples and synchronize participating clocks.

For first-prediction latency, group by match_id plus score_revision and choose the earliest computed_at from immutable prediction history. Report later input/enrichment revisions separately. Include eligible score revisions with no accepted result in the availability denominator; a histogram of successful calculations alone does not measure availability. Superseded scores, startup boundaries and source-stale intervals need explicit categories.

Pending, unavailable, stale or terminal current states carry null probabilities and no calculation identity or clocks from an earlier score. Use immutable history to inspect previous results. A missing result can reflect missing required inputs or a dependency failure; a public unavailable state does not imply that missing inputs were filled.

Coverage and units

Live statistics use the canonical metric code, side, period, numerator, denominator, value and unit. Ratios use [0,1]; a zero denominator yields null. Missing outcome classifications do not imply zero aces or errors. Point result_code is a canonical outcome or null.

rally_count_by_side contains observed per-side source counts and rally_length_missing records their missingness. These values are not promoted to exact rally lengths or stroke trajectories. serve_speed_raw has an unverified unit and must not be assumed to be km/h. The public schema does not label uncertain point-duration fields as timestamps.

features_used measures finite model inputs for a particular result; features_total is 77. Coverage varies by point, denominators, available profiles/rankings, matched historical baselines and live enrichment. Recorded source capability has reached 70 inputs, but neither 70 on every point nor model accuracy/calibration is guaranteed by that count.

Bounded live pages

A page contains at most the requested limit and may contain fewer rows to fit the authenticated response byte budget. Follow page.next_cursor until it is null; a short page is not a completion signal. The cursor refers to the last returned row and remains bound to the principal, operation and filters. An individual row that cannot fit still returns 413 RESPONSE_LIMIT; the byte cap is never disabled. Live pages describe a changing observed set, not a frozen historical release.