Skip to content

Live data

Real-time state attached to a milestone — score, clock, period, weather, etc. Pair with milestones to render live UI alongside Kalshi markets.

Public — no auth required.

Quick reference

Method Endpoint
get(milestone_id, *, include_player_stats=None) GET /live_data/{milestone_id}
batch(milestone_ids, *, include_player_stats=None) GET /live_data
game_stats(milestone_id) GET /live_data/{milestone_id}/game_stats
get_typed(live_data_type, milestone_id) GET /live_data/{type}/milestone/{milestone_id} (legacy)

Get one milestone's live data

live = client.live_data.get("ms_abc", include_player_stats=True)
print(live.live_data_type, live.payload)

Batch (up to 100 milestones)

resp = client.live_data.batch(
    milestone_ids=["ms_a", "ms_b", "ms_c"],
    include_player_stats=False,
)
for entry in resp.live_data:
    print(entry.milestone_id, entry.payload)

milestone_ids is required and non-empty — passing [] raises ValueError. Cap: 100 ids per call.

Game stats / play-by-play

pbp = client.live_data.game_stats("ms_abc")
if pbp.pbp is None:
    print("no play-by-play for this milestone type")
else:
    for period in pbp.pbp.periods:
        for play in period.plays:
            print(play.timestamp, play.description)

game_stats works only for sports milestones with play-by-play coverage. Other milestone types return pbp=None.

Legacy get_typed

live = client.live_data.get_typed("sports_game", "ms_abc")

Prefer get() over get_typed(). The latter wraps the legacy /live_data/{type}/milestone/{id} path and is retained only for callers that still depend on it.

Reference

kalshi.resources.live_data.LiveDataResource

LiveDataResource(transport: SyncTransport)

Bases: SyncResource

Sync live-data API — public, no auth required per spec.

get_typed

get_typed(
    milestone_type: str,
    milestone_id: str,
    *,
    include_player_stats: bool | None = None
) -> LiveData

Legacy /live_data/{type}/milestone/{milestone_id} shape.

milestone_type populates the {type} path segment. Named milestone_type (not type) to avoid shadowing the Python built-in.

Prefer :meth:get. The spec marks this endpoint as the legacy form retained for backward compatibility.

batch

batch(
    *,
    milestone_ids: list[str],
    include_player_stats: bool | None = None
) -> builtins.list[LiveData]

Fetch up to 100 milestones in one call.

Spec requires at least one milestone id (max 100). milestone_ids wire format is ?milestone_ids=a&milestone_ids=b (spec style: form, explode: true) — httpx serializes list values that way by default.

game_stats

game_stats(milestone_id: str) -> GetGameStatsResponse

Play-by-play stats. Returns pbp=None for unsupported sports.

kalshi.resources.live_data.AsyncLiveDataResource

AsyncLiveDataResource(transport: AsyncTransport)

Bases: AsyncResource

Async live-data API.

get_typed async

get_typed(
    milestone_type: str,
    milestone_id: str,
    *,
    include_player_stats: bool | None = None
) -> LiveData

Legacy /live_data/{type}/milestone/{milestone_id} shape.

milestone_type populates the {type} path segment. Named milestone_type (not type) to avoid shadowing the Python built-in.

Prefer :meth:get. The spec marks this endpoint as the legacy form retained for backward compatibility.

batch async

batch(
    *,
    milestone_ids: list[str],
    include_player_stats: bool | None = None
) -> builtins.list[LiveData]

Fetch up to 100 milestones in one call.

Spec requires at least one milestone id (max 100). milestone_ids wire format is ?milestone_ids=a&milestone_ids=b (spec style: form, explode: true) — httpx serializes list values that way by default.

game_stats async

game_stats(milestone_id: str) -> GetGameStatsResponse

Play-by-play stats. Returns pbp=None for unsupported sports.