-
Notifications
You must be signed in to change notification settings - Fork 0
Broadcasts
Relay chess events on Lichess. Broadcasts are organized in tournaments, which have several rounds, which have several games.
Namespace: LichessSharp.Api.Contracts
Access: client.Broadcasts
Stream ongoing official broadcasts sorted by tier, followed by finished broadcasts.
IAsyncEnumerable<BroadcastWithRounds> StreamOfficialBroadcastsAsync(
int? nb = null,
bool? html = null,
CancellationToken cancellationToken = default)Parameters:
| Name | Type | Description |
|---|---|---|
| nb | int? | Max broadcasts to fetch (1-100, default 20) |
| html | bool? | Convert description from markdown to HTML |
Example:
using var client = new LichessClient();
await foreach (var broadcast in client.Broadcasts.StreamOfficialBroadcastsAsync(nb: 10))
{
Console.WriteLine($"Tournament: {broadcast.Tour.Name}");
Console.WriteLine($" URL: {broadcast.Tour.Url}");
if (broadcast.Tour.Info != null)
{
Console.WriteLine($" Location: {broadcast.Tour.Info.Location}");
Console.WriteLine($" Time Control: {broadcast.Tour.Info.TimeControl}");
}
Console.WriteLine($" Rounds: {broadcast.Rounds.Count}");
foreach (var round in broadcast.Rounds.Take(3))
{
var status = round.Ongoing == true ? "LIVE" : (round.Finished == true ? "Finished" : "Upcoming");
Console.WriteLine($" - {round.Name} [{status}]");
}
}Get paginated top broadcast previews.
Task<BroadcastTopPage> GetTopBroadcastsAsync(
int? page = null,
CancellationToken cancellationToken = default)Example:
using var client = new LichessClient();
var top = await client.Broadcasts.GetTopBroadcastsAsync(page: 1);
Console.WriteLine("Active Broadcasts:");
foreach (var broadcast in top.Active ?? [])
{
Console.WriteLine($" {broadcast.Tour.Name}");
if (broadcast.Round?.Ongoing == true)
{
Console.WriteLine($" LIVE: {broadcast.Round.Name}");
}
}
Console.WriteLine("\nPast Broadcasts:");
foreach (var broadcast in top.Past?.CurrentPageResults ?? [])
{
Console.WriteLine($" {broadcast.Tour.Name}");
}
if (top.Past?.NextPage != null)
{
Console.WriteLine($"\nMore on page {top.Past.NextPage}");
}Stream broadcasts created by a user.
IAsyncEnumerable<BroadcastByUser> StreamUserBroadcastsAsync(
string username,
int? nb = null,
bool? html = null,
CancellationToken cancellationToken = default)Example:
using var client = new LichessClient();
await foreach (var broadcast in client.Broadcasts.StreamUserBroadcastsAsync("someuser", nb: 20))
{
Console.WriteLine($"{broadcast.Tour.Name} - {broadcast.Tour.Url}");
}Search across recent official broadcasts.
Task<BroadcastSearchPage> SearchBroadcastsAsync(
string query,
int? page = null,
CancellationToken cancellationToken = default)Example:
using var client = new LichessClient();
var results = await client.Broadcasts.SearchBroadcastsAsync("World Championship");
Console.WriteLine($"Found broadcasts (page {results.CurrentPage}):");
foreach (var broadcast in results.CurrentPageResults ?? [])
{
Console.WriteLine($" {broadcast.Tour.Name}");
}Get information about a broadcast tournament.
Task<BroadcastWithRounds> GetTournamentAsync(
string broadcastTournamentId,
bool? html = null,
CancellationToken cancellationToken = default)Example:
using var client = new LichessClient();
var tournament = await client.Broadcasts.GetTournamentAsync("tournamentId");
Console.WriteLine($"Tournament: {tournament.Tour.Name}");
Console.WriteLine($"Description: {tournament.Tour.Description}");
foreach (var round in tournament.Rounds)
{
Console.WriteLine($"Round: {round.Name}");
Console.WriteLine($" URL: {round.Url}");
Console.WriteLine($" Ongoing: {round.Ongoing}");
}Get information about a broadcast round with games.
Task<BroadcastRound> GetRoundAsync(
string broadcastTournamentSlug,
string broadcastRoundSlug,
string broadcastRoundId,
CancellationToken cancellationToken = default)Example:
using var client = new LichessClient();
var round = await client.Broadcasts.GetRoundAsync(
"world-championship-2024",
"round-1",
"roundId123");
Console.WriteLine($"Round: {round.Round.Name}");
Console.WriteLine($"Games:");
foreach (var game in round.Games)
{
var white = game.Players?.FirstOrDefault();
var black = game.Players?.Skip(1).FirstOrDefault();
Console.WriteLine($" {white?.Title} {white?.Name} vs {black?.Title} {black?.Name}");
Console.WriteLine($" Status: {game.Status}");
Console.WriteLine($" FEN: {game.Fen}");
}Stream all broadcast rounds you are a member of.
Required Scope: study:read
IAsyncEnumerable<BroadcastMyRound> StreamMyRoundsAsync(
int? nb = null,
CancellationToken cancellationToken = default)Example:
using var client = new LichessClient(token);
await foreach (var myRound in client.Broadcasts.StreamMyRoundsAsync())
{
Console.WriteLine($"Tournament: {myRound.Tour.Name}");
Console.WriteLine($"Round: {myRound.Round.Name}");
Console.WriteLine($"Can edit: {myRound.Study.Writeable}");
}Create a new broadcast tournament.
Required Scope: study:write
Task<BroadcastWithRounds> CreateTournamentAsync(
BroadcastTournamentOptions options,
CancellationToken cancellationToken = default)Example:
using var client = new LichessClient(token);
var tournament = await client.Broadcasts.CreateTournamentAsync(new BroadcastTournamentOptions
{
Name = "Club Championship 2024",
ShortDescription = "Annual club championship tournament",
FullDescription = "## Club Championship\n\nOur annual event...",
Location = "New York, USA",
TimeControl = "90+30",
FideTimeControl = "standard",
TimeZone = "America/New_York",
AutoLeaderboard = true
});
Console.WriteLine($"Created tournament: {tournament.Tour.Id}");
Console.WriteLine($"URL: {tournament.Tour.Url}");Update an existing broadcast tournament.
Required Scope: study:write
Task<BroadcastWithRounds> UpdateTournamentAsync(
string broadcastTournamentId,
BroadcastTournamentOptions options,
CancellationToken cancellationToken = default)Create a new broadcast round.
Required Scope: study:write
Task<BroadcastRoundNew> CreateRoundAsync(
string broadcastTournamentId,
BroadcastRoundOptions options,
CancellationToken cancellationToken = default)Example:
using var client = new LichessClient(token);
var round = await client.Broadcasts.CreateRoundAsync("tournamentId", new BroadcastRoundOptions
{
Name = "Round 1",
StartsAt = DateTimeOffset.UtcNow.AddHours(1).ToUnixTimeMilliseconds(),
SyncUrl = "https://example.com/games.pgn",
SyncPeriod = 6,
Delay = 60
});
Console.WriteLine($"Created round: {round.Round.Id}");Update an existing broadcast round.
Required Scope: study:write
Task<BroadcastRoundNew> UpdateRoundAsync(
string broadcastRoundId,
BroadcastRoundOptions options,
CancellationToken cancellationToken = default)Reset a broadcast round to its initial state, removing all games.
Required Scope: study:write
Task<bool> ResetRoundAsync(
string broadcastRoundId,
CancellationToken cancellationToken = default)Push PGN to a broadcast round. Only for broadcasts without a source URL.
Required Scope: study:write
Task<BroadcastPgnPushResult> PushPgnAsync(
string broadcastRoundId,
string pgn,
CancellationToken cancellationToken = default)Example:
using var client = new LichessClient(token);
var pgn = @"
[Event ""Club Championship""]
[White ""Smith, John""]
[Black ""Jones, Alice""]
[Result ""*""]
1. e4 e5 2. Nf3 Nc6 *
";
var result = await client.Broadcasts.PushPgnAsync("roundId", pgn);
foreach (var game in result.Games ?? [])
{
if (game.Error != null)
{
Console.WriteLine($"Error: {game.Error}");
}
else
{
Console.WriteLine($"Pushed game with {game.Moves} moves");
}
}Download all games of a broadcast round in PGN format.
Task<string> ExportRoundPgnAsync(
string broadcastRoundId,
bool? clocks = null,
bool? comments = null,
CancellationToken cancellationToken = default)| Parameter | Type | Description |
|---|---|---|
| broadcastRoundId | string | The broadcast round ID |
| clocks | bool? | Include clock comments in PGN moves (default: true) |
| comments | bool? | Include analysis comments in PGN moves (default: true) |
Example:
using var client = new LichessClient();
// Export with all annotations
var pgn = await client.Broadcasts.ExportRoundPgnAsync("roundId");
await File.WriteAllTextAsync("round1.pgn", pgn);
// Export without clocks or comments (moves only)
var cleanPgn = await client.Broadcasts.ExportRoundPgnAsync("roundId", clocks: false, comments: false);Download all games of all rounds of a broadcast tournament in PGN format.
Task<string> ExportAllRoundsPgnAsync(
string broadcastTournamentId,
bool? clocks = null,
bool? comments = null,
CancellationToken cancellationToken = default)| Parameter | Type | Description |
|---|---|---|
| broadcastTournamentId | string | The broadcast tournament ID |
| clocks | bool? | Include clock comments in PGN moves (default: true) |
| comments | bool? | Include analysis comments in PGN moves (default: true) |
Stream an ongoing broadcast round as PGN. Returns a new PGN every time a game is updated.
IAsyncEnumerable<string> StreamRoundPgnAsync(
string broadcastRoundId,
bool? clocks = null,
bool? comments = null,
CancellationToken cancellationToken = default)| Parameter | Type | Description |
|---|---|---|
| broadcastRoundId | string | The broadcast round ID |
| clocks | bool? | Include clock comments in PGN moves (default: true) |
| comments | bool? | Include analysis comments in PGN moves (default: true) |
Example:
using var client = new LichessClient();
using var cts = new CancellationTokenSource();
await foreach (var pgn in client.Broadcasts.StreamRoundPgnAsync("roundId", cancellationToken: cts.Token))
{
Console.WriteLine("Games updated:");
Console.WriteLine(pgn.Substring(0, Math.Min(200, pgn.Length)) + "...");
}Get the list of players in a broadcast tournament.
Task<IReadOnlyList<BroadcastPlayerEntry>> GetPlayersAsync(
string tournamentId,
CancellationToken cancellationToken = default)Example:
using var client = new LichessClient();
var players = await client.Broadcasts.GetPlayersAsync("tournamentId");
Console.WriteLine("Tournament Players:");
foreach (var player in players.OrderByDescending(p => p.Score))
{
Console.WriteLine($" {player.Rank}. {player.Title} {player.Name}");
Console.WriteLine($" Rating: {player.Rating} ({player.Federation})");
Console.WriteLine($" Score: {player.Score}/{player.Played}");
}Get details of a specific player with their games.
Task<BroadcastPlayerWithGames> GetPlayerAsync(
string tournamentId,
string playerId,
CancellationToken cancellationToken = default)Example:
using var client = new LichessClient();
var player = await client.Broadcasts.GetPlayerAsync("tournamentId", "123456");
Console.WriteLine($"Player: {player.Title} {player.Name}");
Console.WriteLine($"FIDE ID: {player.FideId}");
Console.WriteLine($"Rating: {player.Rating}");
if (player.Fide != null)
{
Console.WriteLine($"FIDE Ratings: Standard={player.Fide.Ratings?.Standard}, " +
$"Rapid={player.Fide.Ratings?.Rapid}, Blitz={player.Fide.Ratings?.Blitz}");
}
Console.WriteLine("\nGames:");
foreach (var game in player.Games ?? [])
{
Console.WriteLine($" vs {game.Opponent?.Title} {game.Opponent?.Name} ({game.Color}): {game.Points}");
}Get the team leaderboard of a broadcast tournament, if available.
Task<IReadOnlyList<BroadcastTeamLeaderboardEntry>> GetTeamStandingsAsync(
string broadcastTournamentId,
CancellationToken cancellationToken = default)Example:
using var client = new LichessClient();
var teams = await client.Broadcasts.GetTeamStandingsAsync("tournamentId");
Console.WriteLine("Team Standings:");
foreach (var team in teams)
{
Console.WriteLine($" {team.Name}: MP={team.Mp}, GP={team.Gp}");
Console.WriteLine($" Matches: {team.Matches.Count}, Players: {team.Players.Count}");
}Response Types:
| Property | Type | Description |
|---|---|---|
| Name | string | Team name |
| Mp | double | Total match points scored |
| Gp | double | Total game points scored |
| AverageRating | int? | Average rating of the team's players |
| Matches | IReadOnlyList<BroadcastTeamMatchEntry> | List of matches played |
| Players | IReadOnlyList<BroadcastPlayerEntry> | Players who played for this team |
| Property | Type | Description |
|---|---|---|
| RoundId | string | Round ID of the match |
| Opponent | string | Name of the opposing team |
| Mp | double? | Match points scored |
| Gp | double? | Game points scored |
| Points | string? | Match result ("1", "1/2", or "0") |
| Property | Type | Description |
|---|---|---|
| Name | string | Tournament name (2-80 chars, required) |
| ShortDescription | string? | Short description (max 400 chars) |
| FullDescription | string? | Full markdown description (max 20,000 chars) |
| AutoLeaderboard | bool? | Enable auto leaderboard |
| TeamTable | bool? | Enable team standings table |
| Players | string? | Featured players (comma-separated) |
| Website | string? | External website URL |
| Standings | string? | External standings URL |
| Location | string? | Tournament location |
| Format | string? | Tournament format description |
| TimeControl | string? | Time control description |
| FideTimeControl | string? | FIDE category: "standard", "rapid", "blitz" |
| TimeZone | string? | Timezone identifier |
| Property | Type | Description |
|---|---|---|
| Name | string | Round name (3-80 chars, required) |
| SyncUrl | string? | URL to sync PGN from |
| StartsAt | long? | Start time (Unix ms) |
| StartsAfterPrevious | bool? | Start after previous round |
| Rated | bool? | FIDE rated games |
| Delay | int? | Broadcast delay in seconds (0-1800) |
| SyncPeriod | int? | Sync interval in seconds (2-60) |
- Studies API - Collaborative analysis boards
- Games API - Game export
- Fide API - FIDE player data