Partner-facing event contract for tournament lifecycle events.
Events are partner-visible change notifications. They help consumers decide when to refresh state from the Partner API; the API remains the source of truth after an event is received.
The initial v0 series event surface is intentionally smaller than the full series lifecycle state model. It is not a complete state-transition log. It only exposes stable, externally meaningful milestones that are currently part of the public partner event model. Other series changes, including cancellation, postponement, suspension, or resumption, remain discoverable through Partner API reads until they are promoted to explicit public event types in a future contract addition.
Operational delivery uses a single Pub/Sub topic, tds-events, for the
partner event stream. Consumers route messages by event_type. The
ordering group key is aggregate_id; for the current series events this
is the series ID. Ordering is therefore scoped to one series and is not a
global ordering guarantee.
Documented event types:
Event name: series.started
Emitted when a series enters the live state.
Payload model: SeriesStartedEvent
Event name: series.completed
Emitted when a series reaches its completed state.
Payload model: SeriesCompletedEvent
Versioning:
series.started, series.completed) are stable.event_version field that gates
payload schema evolution. Both events are currently at
"2.0" after aligning SeriesSnapshot with the current Partner
API series shape: topology IDs and venue_id replace older
venue, publication, and progression_links fields.
Additive, backward-compatible changes bump the minor component;
breaking payload changes bump the major component.Draft visibility:
series.* events are not emitted while a series is in
the DRAFT lifecycle state. A series only becomes visible to
partners once it transitions out of DRAFT (typically to
SCHEDULED). Subscribers will not receive any partner event
referencing a series whose current state is DRAFT, including
before snapshots captured from a DRAFT predecessor.Sends the partner-visible series lifecycle events.
Accepts one of the following messages:
Emitted when a series starts.
Series transitions from SCHEDULED to LIVE on time
{
"event_type": "series.started",
"event_version": "2.0",
"occurred_at": "2026-04-22T17:05:00Z",
"aggregate_id": "1832145900000000001",
"data": {
"series_id": "1832145900000000001",
"tournament_id": "trn_ewc_2026_cs2",
"game_mode_id": "gm_cs2_standard_5v5",
"node_id": "nde_ewc_2026_cs2_groups_a_r1m1",
"round_id": "rnd_ewc_2026_cs2_groups_a_r1",
"group_id": "grp_ewc_2026_cs2_a",
"phase_id": "phs_ewc_2026_cs2_groups",
"state": "LIVE",
"scheduled_start": "2026-04-22T17:00:00Z",
"actual_start": "2026-04-22T17:05:00Z",
"format": {
"type": "BEST_OF",
"best_of": 3,
"set_count": null
},
"venue_id": "ven_riyadh_arena_main",
"stream": "https://twitch.tv/example/cs2-ewc-2026",
"result_visibility_override": null
},
"before": {
"series_id": "1832145900000000001",
"tournament_id": "trn_ewc_2026_cs2",
"game_mode_id": "gm_cs2_standard_5v5",
"node_id": "nde_ewc_2026_cs2_groups_a_r1m1",
"round_id": "rnd_ewc_2026_cs2_groups_a_r1",
"group_id": "grp_ewc_2026_cs2_a",
"phase_id": "phs_ewc_2026_cs2_groups",
"state": "SCHEDULED",
"scheduled_start": "2026-04-22T17:00:00Z",
"format": {
"type": "BEST_OF",
"best_of": 3,
"set_count": null
},
"venue_id": "ven_riyadh_arena_main",
"stream": "https://twitch.tv/example/cs2-ewc-2026",
"result_visibility_override": null
},
"changed_fields": [
"state",
"actual_start"
]
}
Emitted when a series is completed.
Series transitions from LIVE to COMPLETED with final actual_end
{
"event_type": "series.completed",
"event_version": "2.0",
"occurred_at": "2026-04-22T18:45:00Z",
"aggregate_id": "1832145900000000001",
"data": {
"series_id": "1832145900000000001",
"tournament_id": "trn_ewc_2026_cs2",
"game_mode_id": "gm_cs2_standard_5v5",
"node_id": "nde_ewc_2026_cs2_groups_a_r1m1",
"round_id": "rnd_ewc_2026_cs2_groups_a_r1",
"group_id": "grp_ewc_2026_cs2_a",
"phase_id": "phs_ewc_2026_cs2_groups",
"state": "COMPLETED",
"scheduled_start": "2026-04-22T17:00:00Z",
"actual_start": "2026-04-22T17:05:00Z",
"actual_end": "2026-04-22T18:45:00Z",
"format": {
"type": "BEST_OF",
"best_of": 3,
"set_count": null
},
"venue_id": "ven_riyadh_arena_main",
"stream": "https://twitch.tv/example/cs2-ewc-2026",
"result_visibility_override": null
},
"before": {
"series_id": "1832145900000000001",
"tournament_id": "trn_ewc_2026_cs2",
"game_mode_id": "gm_cs2_standard_5v5",
"node_id": "nde_ewc_2026_cs2_groups_a_r1m1",
"round_id": "rnd_ewc_2026_cs2_groups_a_r1",
"group_id": "grp_ewc_2026_cs2_a",
"phase_id": "phs_ewc_2026_cs2_groups",
"state": "LIVE",
"scheduled_start": "2026-04-22T17:00:00Z",
"actual_start": "2026-04-22T17:05:00Z",
"format": {
"type": "BEST_OF",
"best_of": 3,
"set_count": null
},
"venue_id": "ven_riyadh_arena_main",
"stream": "https://twitch.tv/example/cs2-ewc-2026",
"result_visibility_override": null
},
"changed_fields": [
"state",
"actual_end"
]
}
Emitted when a series starts.
Emitted when a series is completed.
Snapshot of Series state. Carried as the post-event snapshot
(data) and as the prior before snapshot on every partner
series event so consumers can diff state transitions without
additional lookups. Mirrors the partner-facing Series resource shape
used by the current Partner API. archived_at is intentionally not
part of this snapshot.
Canonical snake_case name of a Series field that can appear in the
changed_fields list on partner series events. Enum order matches
the deterministic iteration order used by the publisher when
building the list.
Lifecycle states permitted by the initial partner series event snapshot schema. This is an intentionally limited public event subset, not the full canonical API lifecycle enum.
Competitive format of the series. Mirrors
openapi/v1/common/formats.yaml#/SeriesFormat.
Optional per-series override for result visibility. Null when no
override is set. Mirrors
openapi/v1/common/formats.yaml#/ResultVisibilityOverride.