Skip to main content

KHL — KHL site REST (www.khl.ru/rest)

sportsdataverse.hockey.khl — 14 endpoints.

Note: Owner flag (sdv-internal-refs/khl/README.md): the KHL and its webcaster platform are run by Russian operators, some clubs by sanctioned state companies. Fetching on your own machine is fine; any published data release, hosted mirror or redistribution needs owner (sanctions / legal) sign-off first.

khl_schedule​

Season schedule and results of a tournament, one row per game (All-Star games dropped).

Endpoint URL: POST https://www.khl.ru/rest/calendar/list/

Valid URL: https://www.khl.ru/rest/calendar/list/?season=2026&stage=regular

API ParameterPythonPatternRequiredNullableDescription
seasonseasonYSeason by its END year (2026 = 2025-26), mapped to the KHL tournament id (tnId) through the webcaster season table (khl_webcaster_stages). None = the site's current season.
stagestageYWhich stage of the season: regular or playoff.
values[tournament]tournament_idYkhl.ru tournament id (tnId), sent as is instead of season / stage (1369 = 2025-26 regular season, 1370 its playoff; the schedule's tournament_id column). The All-Star games have their own.

Returns​

return_parsed=True (default) — a tidy polars.DataFrame with the columns below; pass return_as_pandas=True for a pandas.DataFrame.

col_nametypedescription
game_idintegerkhl.ru game id; equals webcaster event khl_id / match_id
tournament_idintegerkhl.ru tournament (stage) id, tnId: 1369 = 2025-26 regular season, 1370 its playoff; equals webcaster stage khl_id
datecharacterGame date YYYY-MM-DD (Moscow time)
timecharacterStart time hh:mm (Moscow time); not a game clock
home_club_idintegerHome CLUB id (stable across seasons; joins webcaster team khl_id)
home_namecharacterHome team name (Russian on www.khl.ru)
away_club_idintegerVisitor CLUB id (stable across seasons; joins webcaster team khl_id)
away_namecharacterVisitor team name (Russian on www.khl.ru)
home_scoreintegerHome goals (final, shootout winner counted)
away_scoreintegerVisitor goals (final, shootout winner counted)
decisioncharacterOT or SO when decided in overtime / a shootout; null in regulation
period_scorescharacterPer-period home:away scores, comma-joined
winner_club_idintegerClub id of the winner
approvedinteger1 = result confirmed by the league
arena_idintegerkhl.ru arena id
arena_namecharacterArena (city) name, from data.ARENAS

return_parsed=False — the raw khl.ru envelope Dict ({status, data, errors}).

Example​

khl_schedule(season=2026)

Last validated n/a.

khl_roster​

Club roster (current season only): one row per player.

Endpoint URL: POST https://www.khl.ru/rest/clubs/team/

Valid URL: https://www.khl.ru/rest/clubs/team/?page=team&values%5Bclub_id%5D=7

API ParameterPythonPatternRequiredNullableDescription
values[club_id]club_idYRequired. khl.ru CLUB id (7 = Spartak; schedule home_club_id), not a team-season id.

Returns​

return_parsed=True (default) — a tidy polars.DataFrame with the columns below; pass return_as_pandas=True for a pandas.DataFrame.

col_nametypedescription
groupcharacterList the row comes from (position group / roster section)
player_idintegerkhl.ru player id; equals webcaster player khl_id
photocharacterPlayer photo URL on khl.ru (protocol-relative)
countrycharacterCitizenship (Russian)
lastnamecharacterLast name in Russian
firstnamecharacterFirst name in Russian
jnintegerJersey number (not an id; 0 on a team event)
ageintegerPlayer age in years
favoritelogicalFront-end favourite flag of the signed-in user (always False here)
linkcharacterRelative khl.ru page path

return_parsed=False — the raw khl.ru envelope Dict ({status, data, errors}).

Example​

khl_roster(club_id=7)

Last validated n/a.

khl_stat_filters​

Stats filter options: seasons, tournaments, position groups and clubs (one row per option).

Endpoint URL: POST https://www.khl.ru/rest/filters/statplayers/

Valid URL: https://www.khl.ru/rest/filters/statplayers/?season=2026&stage=regular

API ParameterPythonPatternRequiredNullableDescription
seasonseasonYSeason by its END year (2026 = 2025-26), mapped to the KHL tournament id (tnId) through the webcaster season table (khl_webcaster_stages). None = the site's current season.
stagestageYWhich stage of the season: regular or playoff.
values[tournament]tournament_idYkhl.ru tournament id (tnId), sent as is instead of season / stage (1369 = 2025-26 regular season, 1370 its playoff; the schedule's tournament_id column). The All-Star games have their own.

Returns​

return_parsed=True (default) — a tidy polars.DataFrame with the columns below; pass return_as_pandas=True for a pandas.DataFrame.

col_nametypedescription
filtercharacterFilter code: season, tournament, amplua_full or clubs_full
filter_namecharacterFilter label as the site prints it
valuecharacterOption code to send for the filter (a tournament id, a season code such as s19, a club slug)
namecharacterOption label (Russian)
defintegerDefault tournament id (tnId) of a season option
activeinteger1 when the option is selectable

return_parsed=False — the raw khl.ru envelope Dict ({status, data, errors}).

Example​

khl_stat_filters(season=2026)

Last validated n/a.

khl_game_header​

Game header: status, teams, score, arena (one row).

Endpoint URL: POST https://www.khl.ru/rest/game/header/

Valid URL: https://www.khl.ru/rest/game/header/?page=resume&values%5Bgameid%5D=898236&season=2026&stage=regular

API ParameterPythonPatternRequiredNullableDescription
values[gameid]game_idYRequired. khl.ru game id (the schedule's game_id; equals webcaster event khl_id).
seasonseasonYSeason by its END year (2026 = 2025-26), mapped to the KHL tournament id (tnId) through the webcaster season table (khl_webcaster_stages). The game's season; required unless tournament_id is given.
stagestageYWhich stage of the season: regular or playoff.
values[tournament]tournament_idYkhl.ru tournament id (tnId), sent as is instead of season / stage (1369 = 2025-26 regular season, 1370 its playoff; the schedule's tournament_id column). The All-Star games have their own.

Returns​

return_parsed=True (default) — a tidy polars.DataFrame with the columns below; pass return_as_pandas=True for a pandas.DataFrame.

col_nametypedescription
game_idintegerkhl.ru game id; equals webcaster event khl_id / match_id
tournament_idintegerkhl.ru tournament (stage) id, tnId: 1369 = 2025-26 regular season, 1370 its playoff; equals webcaster stage khl_id
home_club_idintegerHome CLUB id (stable across seasons; joins webcaster team khl_id)
home_team_season_idintegerHome team-season id (one per tournament; joins nothing in the webcaster API)
away_club_idintegerVisitor CLUB id (stable across seasons; joins webcaster team khl_id)
away_team_season_idintegerVisitor team-season id (one per tournament; joins nothing in the webcaster API)
arena_idintegerkhl.ru arena id
home_scoreintegerHome goals (final, shootout winner counted)
away_scoreintegerVisitor goals (final, shootout winner counted)
roundintegerPlayoff round number
roundnamecharacterRound label in Russian ('Неделя 29' = Week 29)
roundname_encharacterRound label in English
datecharacterGame date YYYY-MM-DD (Moscow time)
dayofweekintegerDay of week, 1 = Sunday (6 = Friday 2026-03-20)
timecharacterStart time hh:mm:ss (Moscow time); not a game clock
changesintegerCount of changes to the game record (0 in the captured bodies; unverified)
numberintegerGame number within the tournament
home_name_l3characterHome club 3-letter code in Russian
home_name_encharacterHome club name in English
home_name_l3_encharacterHome club 3-letter code in English
home_city_encharacterHome club city in English
visitor_name_l3characterVisiting club 3-letter code in Russian
visitor_name_encharacterVisiting club name in English
visitor_name_l3_encharacterVisiting club 3-letter code in English
visitor_city_encharacterVisiting club city in English
arenacharacterArena name in Russian
arena_encharacterArena name in English
arena_citycharacterArena city in Russian
arena_city_encharacterArena city in English
msktime_sftintegerOffset of local time from Moscow time, hours (unverified)
gmttime_sftintegerOffset of Moscow time from GMT, hours (unverified)
tempcharacter
scorecharacterFinal score 'home:visitor'
otscharacterHow the game ended: empty = regulation, OT = overtime, SO = shootout
attendanceintegerAttendance (numeric string)
approvedinteger1 = result confirmed by the league
format_date_daycharacterGame date YYYY-MM-DD (Moscow time), as the site formats it
time_formatcharacterStart time hh:mm (Moscow time)
full_dateintegerStart time, unix seconds (UTC)
date_typecharacterFront-end date bucket of the game relative to today ('last' = already played; other values unverified)
typecharacterGame state/type code (sogame = finished in a shootout)
winnercharacterWinning side: A = home, B = visitor
visible_datecharacterShort display date in Russian ('20 мар' = 20 March)
visible_date_fullcharacterDisplay date in Russian without the year ('20 марта')
visible_date_full2characterDisplay date in Russian with the year ('20 марта 2026')
visible_date_daycharacterAbbreviated weekday in Russian ('пт' = Friday)
winintegerTrue when this club won

return_parsed=False — the raw khl.ru envelope Dict ({status, data, errors}).

Example​

khl_game_header(game_id=898236, season=2026)

Last validated n/a.

khl_game_protocol​

Game protocol: one row per goal with scorer, assistants, strength and the jerseys on the ice.

Endpoint URL: POST https://www.khl.ru/rest/game/protocol/

Valid URL: https://www.khl.ru/rest/game/protocol/?values%5Bgameid%5D=898236&season=2026&stage=regular

API ParameterPythonPatternRequiredNullableDescription
values[gameid]game_idYRequired. khl.ru game id (the schedule's game_id; equals webcaster event khl_id).
seasonseasonYSeason by its END year (2026 = 2025-26), mapped to the KHL tournament id (tnId) through the webcaster season table (khl_webcaster_stages). The game's season; required unless tournament_id is given.
stagestageYWhich stage of the season: regular or playoff.
values[tournament]tournament_idYkhl.ru tournament id (tnId), sent as is instead of season / stage (1369 = 2025-26 regular season, 1370 its playoff; the schedule's tournament_id column). The All-Star games have their own.

Returns​

return_parsed=True (default) — a tidy polars.DataFrame with the columns below; pass return_as_pandas=True for a pandas.DataFrame.

col_nametypedescription
game_idintegerkhl.ru game id; equals webcaster event khl_id / match_id
tournament_idintegerkhl.ru tournament (stage) id, tnId: 1369 = 2025-26 regular season, 1370 its playoff; equals webcaster stage khl_id
periodintegerPeriod number (box score: 0 = the whole game; 4+ = overtime)
goal_numberintegerGoal number in the game
timecharacterGame clock mm:ss (game-elapsed); period marker rows keep their wall-clock HH:MM
team_sidecharacterA = home, B = visitor
score_aintegerHome goals after the goal
score_bintegerVisitor goals after the goal
strengthcharacterStrength code as the site prints it (Russian: РАВ even, БОЛ power play, МЕН short-handed)
strength_textcharacterStrength label as the site prints it
scorer_player_idintegerScorer's khl.ru player id
scorer_namecharacterScorer's name with the season count in brackets
scorer_jnintegerScorer's jersey
assist_1_player_idintegerFirst assistant's khl.ru player id
assist_1_namecharacterFirst assistant's name with the season count in brackets
assist_1_jnintegerFirst assistant's jersey
assist_2_player_idintegerSecond assistant's khl.ru player id
assist_2_namecharacterSecond assistant's name with the season count in brackets
assist_2_jnintegerSecond assistant's jersey
on_ice_acharacterHome jerseys on the ice, comma-separated
on_ice_bcharacterVisitor jerseys on the ice, comma-separated

return_parsed=False — the raw khl.ru envelope Dict ({status, data, errors}).

Example​

khl_game_protocol(game_id=898236, season=2026)

Last validated n/a.

khl_game_info​

Game info: teams, score, arena, officials, starting goalies (one row).

Endpoint URL: POST https://www.khl.ru/rest/game/text/

Valid URL: https://www.khl.ru/rest/game/text/?values%5Bgameid%5D=898236&season=2026&stage=regular

API ParameterPythonPatternRequiredNullableDescription
values[gameid]game_idYRequired. khl.ru game id (the schedule's game_id; equals webcaster event khl_id).
seasonseasonYSeason by its END year (2026 = 2025-26), mapped to the KHL tournament id (tnId) through the webcaster season table (khl_webcaster_stages). The game's season; required unless tournament_id is given.
stagestageYWhich stage of the season: regular or playoff.
values[tournament]tournament_idYkhl.ru tournament id (tnId), sent as is instead of season / stage (1369 = 2025-26 regular season, 1370 its playoff; the schedule's tournament_id column). The All-Star games have their own.

Returns​

return_parsed=True (default) — a tidy polars.DataFrame with the columns below; pass return_as_pandas=True for a pandas.DataFrame.

col_nametypedescription
game_idintegerkhl.ru game id; equals webcaster event khl_id / match_id
tournament_idintegerkhl.ru tournament (stage) id, tnId: 1369 = 2025-26 regular season, 1370 its playoff; equals webcaster stage khl_id
home_club_idintegerHome CLUB id (stable across seasons; joins webcaster team khl_id)
home_team_season_idintegerHome team-season id (one per tournament; joins nothing in the webcaster API)
away_club_idintegerVisitor CLUB id (stable across seasons; joins webcaster team khl_id)
away_team_season_idintegerVisitor team-season id (one per tournament; joins nothing in the webcaster API)
arena_idintegerkhl.ru arena id
home_scoreintegerHome goals (final, shootout winner counted)
away_scoreintegerVisitor goals (final, shootout winner counted)
roundintegerPlayoff round number
roundnamecharacterRound label in Russian ('Неделя 29' = Week 29)
roundname_encharacterRound label in English
datecharacterGame date YYYY-MM-DD (Moscow time)
dayofweekintegerDay of week, 1 = Sunday (6 = Friday 2026-03-20)
timecharacterStart time hh:mm:ss (Moscow time); not a game clock
changesintegerCount of changes to the game record (0 in the captured bodies; unverified)
numberintegerGame number within the tournament
home_name_l3characterHome club 3-letter code in Russian
home_name_encharacterHome club name in English
home_name_l3_encharacterHome club 3-letter code in English
home_city_encharacterHome club city in English
visitor_name_l3characterVisiting club 3-letter code in Russian
visitor_name_encharacterVisiting club name in English
visitor_name_l3_encharacterVisiting club 3-letter code in English
visitor_city_encharacterVisiting club city in English
arenacharacterArena name in Russian
arena_encharacterArena name in English
arena_citycharacterArena city in Russian
arena_city_encharacterArena city in English
msktime_sftintegerOffset of local time from Moscow time, hours (unverified)
gmttime_sftintegerOffset of Moscow time from GMT, hours (unverified)
tempcharacter
scorecharacterFinal score 'home:visitor'
otscharacterHow the game ended: empty = regulation, OT = overtime, SO = shootout
sc_p1character1st-period score 'home:visitor'
sc_p2character2nd-period score 'home:visitor'
sc_p3character3rd-period score 'home:visitor'
sc_p4characterOvertime or shootout score 'home:visitor'
attendanceintegerAttendance (numeric string)
approvedinteger1 = result confirmed by the league
format_date_daycharacterGame date YYYY-MM-DD (Moscow time), as the site formats it
time_formatcharacterStart time hh:mm (Moscow time)
full_dateintegerStart time, unix seconds (UTC)
date_typecharacterFront-end date bucket of the game relative to today ('last' = already played; other values unverified)
typecharacterGame state/type code (sogame = finished in a shootout)
winnercharacterWinning side: A = home, B = visitor
visible_datecharacterShort display date in Russian ('20 мар' = 20 March)
visible_date_fullcharacterDisplay date in Russian without the year ('20 марта')
visible_date_full2characterDisplay date in Russian with the year ('20 марта 2026')
visible_date_daycharacterAbbreviated weekday in Russian ('пт' = Friday)
statusvaluecharacterGame status in Russian (матч завершен = match finished)
pernumintegerNumber of regulation periods played
numlinesintegerNumber of lines on the line-up card
gk_a_jnintegerHome starting goalie's JERSEY number (gameItem.gkA), not an id
gk_b_jnintegerVisitor starting goalie's JERSEY number (gameItem.gkB), not an id
is_events_have_multi_ovtlogicalTrue when the game has more than one overtime period (playoff)
idmainref1integerReferee 1: khl.ru referee id
idmainref2integerReferee 2: khl.ru referee id
idlineref1integerLinesman 1: khl.ru referee id
idlineref2integerLinesman 2: khl.ru referee id
jnmainref1characterReferee 1 sweater number
jnmainref2characterReferee 2 sweater number
jnlineref1characterLinesman 1 sweater number
jnlineref2characterLinesman 2 sweater number
refm1characterReferee 1, name in Russian
refm2characterReferee 2, name in Russian
refl1characterLinesman 1, name in Russian
refl2characterLinesman 2, name in Russian
statusintegerGame status code (90 = finished; other codes UNVERIFIED)
gk_a_player_idintegerkhl.ru player id of the home starting goalie (gk_a_jn resolved through players)
gk_b_player_idintegerkhl.ru player id of the visitor starting goalie (gk_b_jn resolved through players)

return_parsed=False — the raw khl.ru envelope Dict ({status, data, errors}).

Example​

khl_game_info(game_id=898236, season=2026)

Last validated n/a.

khl_player_box​

Skater box score by period: one row per period, side and jersey, with the player id.

Endpoint URL: POST https://www.khl.ru/rest/game/text/

Valid URL: https://www.khl.ru/rest/game/text/?values%5Bgameid%5D=898236&season=2026&stage=regular

API ParameterPythonPatternRequiredNullableDescription
values[gameid]game_idYRequired. khl.ru game id (the schedule's game_id; equals webcaster event khl_id).
seasonseasonYSeason by its END year (2026 = 2025-26), mapped to the KHL tournament id (tnId) through the webcaster season table (khl_webcaster_stages). The game's season; required unless tournament_id is given.
stagestageYWhich stage of the season: regular or playoff.
values[tournament]tournament_idYkhl.ru tournament id (tnId), sent as is instead of season / stage (1369 = 2025-26 regular season, 1370 its playoff; the schedule's tournament_id column). The All-Star games have their own.

Returns​

return_parsed=True (default) — a tidy polars.DataFrame with the columns below; pass return_as_pandas=True for a pandas.DataFrame.

col_nametypedescription
game_idintegerkhl.ru game id; equals webcaster event khl_id / match_id
tournament_idintegerkhl.ru tournament (stage) id, tnId: 1369 = 2025-26 regular season, 1370 its playoff; equals webcaster stage khl_id
periodintegerPeriod number (box score: 0 = the whole game; 4+ = overtime)
team_sidecharacterA = home, B = visitor
jnintegerJersey number (not an id; 0 on a team event)
player_idintegerkhl.ru player id; equals webcaster player khl_id
player_namecharacterPlayer name as the site prints it (Russian on www.khl.ru)
positioncharacterPosition code (Russian letter on www.khl.ru)
gintegerGoals scored in the period block
aintegerHome roster keyed by jersey number
pcharacterPoints (empty string when none)
shotsintegerShots on goal in the period block
pimintegerPenalty minutes
fointegerFaceoffs taken in the period block
fowintegerFaceoffs won in the period block
fow_pctnumericStat code the bar is computed from
blsintegerShots blocked in the period block
hitsintegerHits (body checks)
faintegerTakeaways (the site labels this column 'Отборы', takeaways)
p_intcintegerPass interceptions
sftcharacterTime on ice 'mm:ss(shifts)'
sftecharacterEven-strength time on ice 'mm:ss(shifts)'
sftppcharacterPower-play time on ice 'mm:ss(shifts)'
sftshcharacterShort-handed time on ice 'mm:ss(shifts)'
sftencharacterEmpty-net time on ice 'mm:ss(shifts)'
tiamscharacterTime in the attacking zone (mm:ss)
tsnumericTop speed, km/h (tracking; present by 2019/20)
dtnumericDistance skated, km (tracking)
asnumericAverage speed, km/h (tracking)
pcdnumericPuck-control duration (tracking; unit unverified)

return_parsed=False — the raw khl.ru envelope Dict ({status, data, errors}).

Example​

khl_player_box(game_id=898236, season=2026)

Last validated n/a.

khl_pbp​

Play-by-play: shots, faceoffs, hits, blocks, giveaways, takeaways, penalties and goals (2008-09 on).

Endpoint URL: POST https://www.khl.ru/rest/game/text/

Valid URL: https://www.khl.ru/rest/game/text/?values%5Bgameid%5D=898236&season=2026&stage=regular

API ParameterPythonPatternRequiredNullableDescription
values[gameid]game_idYRequired. khl.ru game id (the schedule's game_id; equals webcaster event khl_id).
seasonseasonYSeason by its END year (2026 = 2025-26), mapped to the KHL tournament id (tnId) through the webcaster season table (khl_webcaster_stages). The game's season; required unless tournament_id is given.
stagestageYWhich stage of the season: regular or playoff.
values[tournament]tournament_idYkhl.ru tournament id (tnId), sent as is instead of season / stage (1369 = 2025-26 regular season, 1370 its playoff; the schedule's tournament_id column). The All-Star games have their own.

Returns​

return_parsed=True (default) — a tidy polars.DataFrame with the columns below; pass return_as_pandas=True for a pandas.DataFrame.

col_nametypedescription
game_idintegerkhl.ru game id; equals webcaster event khl_id / match_id
tournament_idintegerkhl.ru tournament (stage) id, tnId: 1369 = 2025-26 regular season, 1370 its playoff; equals webcaster stage khl_id
periodintegerPeriod number (box score: 0 = the whole game; 4+ = overtime)
event_indexinteger0-based order of the event in the game, oldest first
event_typecharacterperiod (start / end marker), faceoff, shot, block, action, penalty or goal
timecharacterGame clock mm:ss (game-elapsed); period marker rows keep their wall-clock HH:MM
time_secondsintegerGame-elapsed seconds (null on period marker rows)
team_sidecharacterA = home, B = visitor
jnintegerJersey number (not an id; 0 on a team event)
player_idintegerkhl.ru player id; equals webcaster player khl_id
resultcharacterEvent result code (shots: goal / saved / miss; actions: hit, gva = giveaway, tka = takeaway, intc = interception)
result_textcharacterEvent result label
penalty_minutesintegerPenalty minutes (penalty events)
score_aintegerHome goals after the goal
score_bintegerVisitor goals after the goal
won_sidecharacterFaceoff winner's side (A / B)
won_jnintegerFaceoff winner's jersey
won_player_idintegerFaceoff winner's khl.ru player id
lost_sidecharacterFaceoff loser's side (A / B)
lost_jnintegerFaceoff loser's jersey
lost_player_idintegerFaceoff loser's khl.ru player id
won_zonecharacterZone of the faceoff from the winner's view: offensive, neutral or defensive
shooter_sidecharacterBlocked shooter's side (A / B)
shooter_jnintegerBlocked shooter's jersey
shooter_player_idintegerBlocked shooter's khl.ru player id
period_actioncharacterPeriod marker: 0 = start, 1 = end (inferred)

return_parsed=False — the raw khl.ru envelope Dict ({status, data, errors}).

Example​

khl_pbp(game_id=898236, season=2026)

Last validated n/a.

khl_shots​

Shot map: one row per shot with its x / y on the 1000 x 500 rink grid (2024-25 on).

Endpoint URL: POST https://www.khl.ru/rest/game/text/

Valid URL: https://www.khl.ru/rest/game/text/?values%5Bgameid%5D=898236&season=2026&stage=regular

API ParameterPythonPatternRequiredNullableDescription
values[gameid]game_idYRequired. khl.ru game id (the schedule's game_id; equals webcaster event khl_id).
seasonseasonYSeason by its END year (2026 = 2025-26), mapped to the KHL tournament id (tnId) through the webcaster season table (khl_webcaster_stages). The game's season; required unless tournament_id is given.
stagestageYWhich stage of the season: regular or playoff.
values[tournament]tournament_idYkhl.ru tournament id (tnId), sent as is instead of season / stage (1369 = 2025-26 regular season, 1370 its playoff; the schedule's tournament_id column). The All-Star games have their own.

Returns​

return_parsed=True (default) — a tidy polars.DataFrame with the columns below; pass return_as_pandas=True for a pandas.DataFrame.

col_nametypedescription
game_idintegerkhl.ru game id; equals webcaster event khl_id / match_id
tournament_idintegerkhl.ru tournament (stage) id, tnId: 1369 = 2025-26 regular season, 1370 its playoff; equals webcaster stage khl_id
periodintegerPeriod number (box score: 0 = the whole game; 4+ = overtime)
timecharacterGame clock mm:ss (game-elapsed); period marker rows keep their wall-clock HH:MM
time_secondsintegerGame-elapsed seconds (null on period marker rows)
team_sidecharacterA = home, B = visitor
jnintegerJersey number (not an id; 0 on a team event)
player_idintegerkhl.ru player id; equals webcaster player khl_id
shot_typeinteger1 = goal, 2 = saved (inferred upstream; unverified)
xintegerShot x on the site's 1000-wide rink grid (indent_left = x/10 %); whether shots are normalised to one attacking direction is UNVERIFIED
yintegerShot y on the site's 500-high rink grid (indent_top = y/5 %); orientation UNVERIFIED
indent_leftnumericShot position as percent from the left edge
indent_topnumericShot position as percent from the top edge
indent_rightnumericShot position as percent from the right edge
indent_bottomnumericShot position as percent from the bottom edge

return_parsed=False — the raw khl.ru envelope Dict ({status, data, errors}).

Example​

khl_shots(game_id=898236, season=2026)

Last validated n/a.

khl_player_profile​

Player profile: bio, contract, club (one row).

Endpoint URL: POST https://www.khl.ru/rest/players/profile/

Valid URL: https://www.khl.ru/rest/players/profile/?values%5Bid%5D=41928

API ParameterPythonPatternRequiredNullableDescription
values[id]player_idYRequired. khl.ru player id (the box score / roster player_id).

Returns​

return_parsed=True (default) — a tidy polars.DataFrame with the columns below; pass return_as_pandas=True for a pandas.DataFrame.

col_nametypedescription
player_idintegerkhl.ru player id; equals webcaster player khl_id
firstnamecharacterFirst name in Russian
lastnamecharacterLast name in Russian
photocharacterPlayer photo URL on khl.ru (protocol-relative)
positioncharacterPosition code (Russian letter on www.khl.ru)
position_codecharacterPosition key in English (goaltender, defender, forward)
biographycharacterBiography text in Russian (HTML)
is_herologicalSite 'hero' flag (unverified meaning)
is_riplogicalTrue for a deceased player
links_statscharacterRelative khl.ru page path
pagelinkcharacterRelative khl.ru page path
summary_stats_gpintegerCareer KHL games played (profile summary)
summary_stats_aintegerCareer KHL assists (profile summary)
summary_stats_pmintegerCareer KHL plus-minus (profile summary)
summary_stats_gintegerCareer KHL goals (profile summary)
summary_stats_ptsintegerCareer KHL points (profile summary)
jnintegerJersey number (not an id; 0 on a team event)
club_namecharacterName in Russian (Cyrillic); the *_en / *en sibling holds the English transliteration
club_logocharacterCurrent club logo URL on khl.ru (protocol-relative)
club_codecharacterClub slug (/clubs//)
heightcharacterHeight with its Russian unit ('183 см' = 183 cm)
weightcharacterWeight with its Russian unit ('85 кг' = 85 kg)
birthdatecharacterBirth date (Russian display format)
agecharacterAge with its Russian unit ('27 лет' = 27 years)
contract_namecharacterContract label in Russian
contract_datecharacterContract end date
country_namecharacterName in Russian (Cyrillic); the *_en / *en sibling holds the English transliteration
country_flagcharacterFlag image path of the player's country (citizenship)
sport_country_namecharacterName in Russian (Cyrillic); the *_en / *en sibling holds the English transliteration
sport_country_flagcharacterFlag image path of the country the player represents in sport
stickcharacterShooting hand: l = left, r = right

return_parsed=False — the raw khl.ru envelope Dict ({status, data, errors}).

Example​

khl_player_profile(player_id=41928)

Last validated n/a.

khl_player_career​

Player career: one row per season tournament.

Endpoint URL: POST https://www.khl.ru/rest/players/stats/

Valid URL: https://www.khl.ru/rest/players/stats/?values%5Bid%5D=41928

API ParameterPythonPatternRequiredNullableDescription
values[id]player_idYRequired. khl.ru player id (the box score / roster player_id).

Returns​

return_parsed=True (default) — a tidy polars.DataFrame with the columns below; pass return_as_pandas=True for a pandas.DataFrame.

col_nametypedescription
player_idintegerkhl.ru player id; equals webcaster player khl_id
season_labelcharacterSeason label as sent (26/27, 2025/2026)
tournament_idintegerkhl.ru tournament (stage) id, tnId: 1369 = 2025-26 regular season, 1370 its playoff; equals webcaster stage khl_id
team_season_idintegerTeam-season id (tid; one per tournament; joins nothing in the webcaster API)
club_idintegerkhl.ru CLUB id (stable across seasons; joins webcaster team khl_id)
team_namecharacterTeam name as the site prints it
jnintegerJersey number (not an id; 0 on a team event)
gpintegerGames played by the player
gintegerGoals scored by the player
aintegerAssists credited to the player
ptsintegerPoints (goals plus assists)
pmintegerPlus-minus rating of the player
plusintegerPlus (on ice for a goal for)
minusintegerMinus (on ice for a goal against)
pimintegerPenalty minutes
eqgintegerEven-strength goals
ppgintegerPower-play goals
shgintegerShort-handed goals
otgintegerOvertime goals scored by the player
gwgintegerGame-winning goals
sdsintegerShootout-deciding goals
sogintegerShots on goal by the player
sog_pctnumericShooting percentage
sog_avgnumericShots on goal per game
fointegerFaceoffs taken by the player
fowintegerFaceoffs won by the player
fo_pctnumericFaceoff win percentage
toi_avgcharacterAverage time on ice per game (mm:ss)
sft_avgnumericAverage shifts per game
tie_avgcharacterAverage even-strength time on ice per game
sfte_avgnumericAverage even-strength shifts per game
tipp_avgcharacterAverage power-play time on ice per game
sftpp_avgnumericAverage power-play shifts per game
tish_avgcharacterAverage short-handed time on ice per game
sftsh_avgnumericAverage short-handed shifts per game
hitsintegerHits (body checks)
blsintegerShots blocked by the player
foaintegerFaceoffs lost by the player
tkaintegerTakeaways by the player
p_intcintegerPass interceptions

return_parsed=False — the raw khl.ru envelope Dict ({status, data, errors}).

Example​

khl_player_career(player_id=41928)

Last validated n/a.

khl_playoff_bracket​

Playoff bracket: one row per team per series.

Endpoint URL: POST https://www.khl.ru/rest/standings/playoff/

Valid URL: https://www.khl.ru/rest/standings/playoff/?stage=playoff&values%5Btype%5D=playoff&season=2026

API ParameterPythonPatternRequiredNullableDescription
seasonseasonYSeason by its END year (2026 = 2025-26), mapped to the KHL tournament id (tnId) through the webcaster season table (khl_webcaster_stages). Required unless tournament_id is given.
values[tournament]tournament_idYkhl.ru tournament id (tnId), sent as is instead of season / stage (1369 = 2025-26 regular season, 1370 its playoff; the schedule's tournament_id column). The All-Star games have their own.

Returns​

return_parsed=True (default) — a tidy polars.DataFrame with the columns below; pass return_as_pandas=True for a pandas.DataFrame.

col_nametypedescription
roundintegerPlayoff round number
wins_to_advanceintegerWins needed to win a series of the round
pairintegerSeries number within the round
conferencecharacterConference (west / east)
seedintegerConference seed
club_idintegerkhl.ru CLUB id (stable across seasons; joins webcaster team khl_id)
namecharacterName in Russian (Cyrillic); the *_en / *en sibling holds the English transliteration
series_winsintegerWins in the series so far
game_idscharacterkhl.ru game ids of the series, comma-joined

return_parsed=False — the raw khl.ru envelope Dict ({status, data, errors}).

Example​

khl_playoff_bracket(season=2026)

Last validated n/a.

khl_standings​

Regular-season standings: one row per team per table (league, conferences, divisions).

Endpoint URL: POST https://www.khl.ru/rest/standings/regular/

Valid URL: https://www.khl.ru/rest/standings/regular/?values%5Btype%5D=regular&season=2026

API ParameterPythonPatternRequiredNullableDescription
seasonseasonYSeason by its END year (2026 = 2025-26), mapped to the KHL tournament id (tnId) through the webcaster season table (khl_webcaster_stages). None = the site's current season.
values[tournament]tournament_idYkhl.ru tournament id (tnId), sent as is instead of season / stage (1369 = 2025-26 regular season, 1370 its playoff; the schedule's tournament_id column). The All-Star games have their own.

Returns​

return_parsed=True (default) — a tidy polars.DataFrame with the columns below; pass return_as_pandas=True for a pandas.DataFrame.

col_nametypedescription
tablecharacterStandings table: league, a conference (west / east) or a division key
rankinteger1-based position in its table / list
club_idintegerkhl.ru CLUB id (stable across seasons; joins webcaster team khl_id)
namecharacterName in Russian (Cyrillic); the *_en / *en sibling holds the English transliteration
gpintegerGames played (gp = w + otw + sow + sol + otl + l)
wintegerRegulation wins only: overtime (otw) and shootout (sow) wins are separate columns
otwintegerOvertime wins (not counted in w)
sowintegerShootout wins (not counted in w)
solintegerShootout losses
otlintegerOvertime losses
otl_enintegerOvertime losses with the net empty
lintegerRegulation losses only: overtime (otl) and shootout (sol) losses are separate columns
ptsintegerPoints: 2 per win of any kind, 1 per overtime or shootout loss (3-2-1 in early seasons such as 2013-14)
goals_forintegerGoals scored by the team
goals_againstintegerGoals allowed by the team
is_out_playofflogicalEliminated from playoff contention
linkcharacterRelative khl.ru page path

return_parsed=False — the raw khl.ru envelope Dict ({status, data, errors}).

Example​

khl_standings(season=2026)

Last validated n/a.

khl_player_stats​

League player stats of a tournament, one page (one row per player).

Endpoint URL: POST https://www.khl.ru/rest/stat/players/

Valid URL: https://www.khl.ru/rest/stat/players/?season=2026&stage=regular&values%5Bamplua_full%5D=forwards&nav%5Bpage%5D=1&nav%5Bcount%5D=20

API ParameterPythonPatternRequiredNullableDescription
seasonseasonYSeason by its END year (2026 = 2025-26), mapped to the KHL tournament id (tnId) through the webcaster season table (khl_webcaster_stages). None = the site's current season.
stagestageYWhich stage of the season: regular or playoff.
values[tournament]tournament_idYkhl.ru tournament id (tnId), sent as is instead of season / stage (1369 = 2025-26 regular season, 1370 its playoff; the schedule's tournament_id column). The All-Star games have their own.
values[amplua_full]positionYPosition group: goalies, defenses, forwards, skaters or all. None = the site's default.
values[clubs_full]clubYClub slug (khl_stat_filters, filter clubs_full) or all. None = every club.
nav[page]pageY1-based page. Loop until a page comes back shorter than per_page.
nav[count]per_pageYRows per page: 12, 20, 24 or 36. Keep 20: the site computes page counts and ranks for 20.

Returns​

return_parsed=True (default) — a tidy polars.DataFrame with the columns below; pass return_as_pandas=True for a pandas.DataFrame.

col_nametypedescription
groupcharacterList the row comes from (position group / roster section)
rankinteger1-based position in its table / list
player_idintegerkhl.ru player id; equals webcaster player khl_id
player_namecharacterPlayer name as the site prints it (Russian on www.khl.ru)
imagecharacterPlayer photo URL on khl.ru (team-season specific)
jnintegerJersey number (not an id; 0 on a team event)
gpintegerGames played by the player
gintegerGoals scored by the player
aintegerAssists credited to the player
ptsintegerPoints (goals plus assists)
pmintegerPlus-minus rating of the player
plusintegerPlus (on ice for a goal for)
minusintegerMinus (on ice for a goal against)
pimintegerPenalty minutes
eqgintegerEven-strength goals
ppgintegerPower-play goals
shgintegerShort-handed goals
otgintegerOvertime goals scored by the player
gwgintegerGame-winning goals
sdsintegerShootout-deciding goals
sogintegerShots on goal by the player
sog_pctnumericShooting percentage
sog_avgnumericShots on goal per game
fointegerFaceoffs taken by the player
fowintegerFaceoffs won by the player
fo_pctnumericFaceoff win percentage
toi_avgcharacterAverage time on ice per game (mm:ss)
sft_avgnumericAverage shifts per game
tie_avgcharacterAverage even-strength time on ice per game
sfte_avgnumericAverage even-strength shifts per game
tipp_avgcharacterAverage power-play time on ice per game
sftpp_avgnumericAverage power-play shifts per game
tish_avgcharacterAverage short-handed time on ice per game
sftsh_avgnumericAverage short-handed shifts per game
hitsintegerHits (body checks)
blsintegerShots blocked by the player

return_parsed=False — the raw khl.ru envelope Dict ({status, data, errors}).

Example​

khl_player_stats(position='forwards', season=2026)

Last validated n/a.