Viewership API
Access tournament viewership data programmatically — concurrent viewers, daily stats, channel breakdowns.
Overview
Base URL
https://app.escharts.com/api/viewership
All endpoints return JSON. Dates use Y-m-d format. Timestamps are UTC.
Authentication
Pass your API token as a Bearer token in every request:
Authorization: Bearer <your_token>
Rate Limiting
120 requests per minute per token. Exceeding the limit returns 429 Too Many Requests.
What Your Token Reaches
Two things are agreed separately and checked on every request.
| Scope | What it decides |
|---|---|
| Tournaments |
Which tournaments answer at all — by game, organizer, event series and date window. A tournament outside it returns 403, the same scope that decides what you see signed in on the site
|
| Endpoints |
Which of the endpoints below your agreement covers. One not covered returns 403
|
| Fields |
Which fields an endpoint returns for you. A field outside your agreement is absent from the rows — the request still succeeds, and meta is never trimmed
|
Every example below shows the full set of fields. Yours may be narrower; nothing else about the shape changes.
Errors
{
"error": "game_id is not in your allowed games list.",
"status": 403
}
| Code | Meaning |
|---|---|
| 401 | Missing or invalid token |
| 403 | The tournament is outside your partner access scope — the same scope that decides which tournaments you see on the site |
| 403 | The endpoint, or a field inside it, is not part of your API access |
| 404 | Requested tournament does not exist |
| 422 | Validation error — check required parameters |
| 429 | Rate limit exceeded |
Field Glossary
Canonical fields returned across viewership endpoints.
| Field | Description |
|---|---|
| channel_name | Display name of the channel |
| platform | Streaming platform (Twitch, YouTube, etc.) |
| category | "Official" or "Co-stream" |
| language | Human-readable language name (e.g. "English") |
| tournament | Tournament display name |
| day | Broadcast day number, 1-based, as the site's Days table lists them: rest days are not counted, and a broadcast that runs past midnight UTC stays one day. null for data outside a labelled broadcast day |
| phase | Stage / phase name (VERIFIED only) |
| label | Match label, e.g. "Faze Clan vs Falcons" (channel-minute VERIFIED only) |
| team_a, team_b | Names of the two teams playing the match (channel-minute VERIFIED only) |
| timestamp | Slot timestamp (UTC), the start of the slot. Slot width is meta.granularity: 1 minute for RAW, 1 or 5 minutes for VERIFIED |
| start_timestamp | Min start datetime across official channels (UTC) |
| end_timestamp | Max end datetime across official channels (UTC) |
| tournament_id, channel_id, stream_entity_id | Stable join keys. Names can change; ids do not. stream_entity_id is set when channel_id is 0; it is an unsigned 64-bit integer, so read it with a parser that does not turn large numbers into doubles |
| is_official | true for an official broadcast channel; the boolean form of category |
| channel_url | The channel's page on its platform, e.g. https://www.twitch.tv/ow_esports. null for in-game broadcasts with no public page |
| broadcast_date | The UTC date the broadcast day starts on. A broadcast that runs past midnight UTC keeps the date it started on (channel-day only) |
| airtime | Total broadcast hours, to four decimals |
| airtime_minutes | Total broadcast minutes, a whole number. The same value as airtime, without the unit conversion |
| hours_watched | Total hours watched (viewers × time) |
| average_viewers | Average concurrent viewers. On channel-minute, the average within the slot: hours watched in the slot are average_viewers × slot width |
| peak_viewers | Maximum concurrent viewers |
| peak_viewers_at | Start (UTC) of the 5-minute slot in which peak_viewers was reached |
| data_updated_at | UTC. The later of the last moderation edit and the last recalculation of the tournament's numbers. Responses are cached for up to an hour, so overlap incremental syncs by an hour |
| concurrent_viewers | Concurrent viewers in the slot. RAW slots are 1 minute wide; VERIFIED slots are 1 or 5 minutes wide, see meta.granularity |
| views | Total view count |
| unique_viewers | Estimated unique viewers (broadcast-tournament only) |
| media_value_eur | Estimated ad-equivalent media value in EUR (broadcast-tournament only) |
/tournaments
List Tournaments
Paginated list of tournaments with aggregated viewership stats. Results are limited to tournaments in your partner access scope.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| game_id | int | Filter by game ID | |
| organizer_id | int | Filter by organizer ID | |
| event_id | int | Filter by event series ID | |
| date_from | Y-m-d | Tournaments that ended on or after this date | |
| date_to | Y-m-d | Tournaments that started on or before this date | |
| search | string | Partial match on tournament name (max 100 chars) | |
| sort_by | string | name · hours_watched · peak_viewers · avg_viewers · air_time · starts_at · ends_at · prize_pool · matches_count · match_days | |
| sort_order | string | ASC or DESC (default DESC) | |
| page | int | Page number (default 1) | |
| per_page | int | Results per page, max 200 (default 50) |
Response
{
"data": [
{
"tournament_id": 1234,
"name": "Six Invitational 2025",
"slug": "six-invitational-2025",
"game_name": "Rainbow Six Siege",
"game_id": 11,
"event_name": "Six Invitational",
"event_id": 42,
"starts_at": "2025-02-10 00:00:00",
"ends_at": "2025-02-23 00:00:00",
"hours_watched": 2540000.0,
"peak_viewers": 312000,
"avg_viewers": 85000.0,
"air_time_minutes": 5400,
"views": 36199618,
"prize_pool": 3000000,
"is_offline": 1,
"organizer_names": "Ubisoft",
"venue_names": "Montreal",
"matches_count": 42,
"match_days": 12,
"peak_viewers_at": "2025-02-23 23:40:00",
"data_updated_at": "2025-02-24 11:30:00"
}
],
"meta": {
"page": 1,
"per_page": 50,
"total": 1,
"sort_by": "ends_at",
"sort_order": "DESC"
}
}
/tournament-channels
Tournament Channels
Full channel breakdown for a tournament — one row per channel with aggregated stats for the entire event. Use the returned channel_id values with the channel-level endpoints.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| tournament_id | int | ✓ | Tournament ID |
| official_only | bool | Return only official/main broadcast channels (default false) | |
| sort_by | string | hours_watched · peak_viewers · avg_viewers · air_time · channel_name (default hours_watched) | |
| sort_order | string | ASC or DESC (default DESC) |
Response
{
"data": [
{
"tournament_id": 1234,
"channel_id": 5678,
"stream_entity_id": 0,
"channel_name": "Rainbow6",
"channel_slug": "rainbow6",
"platform": "Twitch",
"platform_slug": "twitch.tv",
"channel_url": "https://www.twitch.tv/rainbow6",
"category": "Official",
"is_official": true,
"language": "English",
"other_languages": [],
"hours_watched": 920000.0,
"peak_viewers": 180000,
"peak_viewers_at": "2025-02-23 23:40:00",
"avg_viewers": 95000.0,
"airtime": 54.0,
"airtime_minutes": 3240,
"views": 4200000,
"data_updated_at": "2025-02-24 11:30:00"
}
],
"meta": {
"tournament_id": 1234,
"official_only": false,
"sort_by": "hours_watched",
"sort_order": "DESC",
"count": 18
}
}
/tournament-matches
Tournament Matches
Full match schedule for a tournament with aggregated viewership stats. All parallel matches (Stream A / Stream B) are returned as separate rows. Useful for attributing viewership to specific matches.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| tournament_id | int | ✓ | Tournament ID |
| date | Y-m-d | Filter to matches played on a specific day. Omit to get all matches for the tournament |
Response
{
"data": [
{
"match_id": 101,
"match_name": "Falcons VS EP",
"stage_name": "Group Stage",
"day": 3,
"event_name": "Group Stage, Day 3",
"phase": "Group Stage",
"starts_at": "2025-11-15 14:00:00",
"ends_at": "2025-11-15 15:28:00",
"team_a": "Falcons",
"team_b": "EP",
"hours_watched": 12500.0,
"peak_viewers": 45000,
"avg_viewers": 38200.0,
"air_time_minutes": 88
},
{
"match_id": 102,
"match_name": "Wildcard VS LOS",
"stage_name": "Group Stage",
"day": 3,
"event_name": "Group Stage, Day 3",
"phase": "Group Stage",
"starts_at": "2025-11-15 14:00:00",
"ends_at": "2025-11-15 15:15:00",
"team_a": "Wildcard",
"team_b": "LOS",
"hours_watched": 3200.0,
"peak_viewers": 9800,
"avg_viewers": 7500.0,
"air_time_minutes": 75
}
],
"meta": {
"tournament_id": 1234,
"date": null,
"count": 2,
"days": [
{ "day": 1, "date": "2025-11-13", "event_name": "Group Stage, Day 1", "phase": "Group Stage" },
{ "day": 2, "date": "2025-11-14", "event_name": "Group Stage, Day 2", "phase": "Group Stage" },
{ "day": 3, "date": "2025-11-15", "event_name": "Group Stage, Day 3", "phase": "Group Stage" }
],
"stages": ["Group Stage"]
}
}
Grouping a Tournament the Way the Site Does
The tournament page filters matches by day and by stage. Both option lists travel in meta, and every match names which one it belongs to — so a client can rebuild those groupings without a second call.
| Field | Description |
|---|---|
| day |
The broadcast day the match was played in, 1-based. Rest days are not counted and a broadcast past midnight UTC stays one day, so it matches /broadcast-day and /channel-day
|
| event_name |
The day label the site's day filter lists, e.g. "Week 1, Day 3"
|
| phase |
The stage filter's value — the part of event_name before the comma, e.g. "Week 1". For a league this is the week number
|
| stage_name |
The stage recorded against the match itself. Usually equal to phase, but it comes from the match schedule rather than from the broadcast day
|
| meta.days |
Every broadcast day of the tournament, ascending — the day filter's option list. Returned only when date is omitted: asking for one day and being handed every other one is 5 KB nobody reads
|
| meta.stages | Distinct phases in broadcast order — the stage filter's option list |
A match played on a date with no broadcast carries null for all three — there are no viewership numbers for it either.
/tournaments-teams
Tournaments Teams
Viewership attributed to each team — the same breakdown the team chart shows on the tournament page. Sorted by hours watched, descending.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| tournament_id | int | ✓ | Tournament ID |
Response
{
"data": [
{
"name": "Six Invitational 2025",
"team": [
{
"team_name": "RSG SG",
"team_id": 101,
"hours_watched": 228100,
"pcu": 85200,
"acu": 42100,
"airtime": 6.5,
"views": 36199618
},
{
"team_name": "BURN x FLASH",
"team_id": 108,
"hours_watched": 205800,
"pcu": 76300,
"acu": 33400,
"airtime": 5.5,
"views": 28104433
}
]
}
],
"meta": {
"tournament_id": 1234,
"players_only": false,
"count": 2
}
}
| Field | Description |
|---|---|
| pcu |
Peak concurrent viewers — peak_viewers elsewhere in this API
|
| acu |
Average concurrent viewers — avg_viewers elsewhere in this API
|
| airtime | Broadcast hours attributed to the team |
Hours watched and both viewer counts are whole numbers, and airtime is hours to four decimals, so it stays whole minutes. A players-only tournament is broken down by player instead; the rows keep the team_id / team_name keys and meta.players_only is true. An unknown tournament_id returns 404.
/tournaments-language
Tournaments Language
Viewership split by broadcast language — the same breakdown the language chart shows on the tournament page, so the shares match. Sorted by hours watched, descending.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| tournament_id | int | ✓ | Tournament ID |
Response
{
"data": [
{
"name": "M7 World Championship",
"viewership_language": [
{
"tournament_id": 1234,
"language": "English",
"hours_watched": 228100,
"peak_viewers": 85200,
"peak_viewers_at": "2025-11-23 13:15:00",
"avg_viewers": 42100,
"airtime": 6.5,
"airtime_minutes": 390,
"views": 36199618,
"data_updated_at": "2025-11-24 06:00:00"
},
{
"tournament_id": 1234,
"language": "Indonesian",
"hours_watched": 205800,
"peak_viewers": 76300,
"peak_viewers_at": "2025-11-23 12:50:00",
"avg_viewers": 33400,
"airtime": 5.5,
"airtime_minutes": 330,
"views": 28104433,
"data_updated_at": "2025-11-24 06:00:00"
}
]
}
],
"meta": {
"tournament_id": 1234,
"count": 2
}
}
Hours watched and average viewers are whole numbers, and airtime is hours to four decimals, so it stays whole minutes. Peak viewers are the language's own peak — summed across its channels slot by slot — so they cannot be rebuilt by adding up the channels' peaks from /tournament-channels. data is a one-element list so the tournament name travels with its breakdown. A language the dictionary does not know is reported as "Others". An unknown tournament_id returns 404. China platforms are excluded, as everywhere else.
/channel-minute
Channel Minute
Concurrent viewers per minute for a given day. Pass channel_id or stream_entity_id for a single channel, channel_ids[]/stream_entity_ids[] for a subset, or omit all to get every channel.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| tournament_id | int | ✓ | Tournament ID |
| status | string | ✓ | RAW or VERIFIED |
| date | Y-m-d | ✓* | Date to query. Required unless match_id is provided (date is derived from the match automatically) |
| match_id | int | Filter to a single match window. Shorthand for match_ids[]=X. When provided, date can be omitted | |
| match_ids[] | int[] | Filter to one or more matches — e.g. match_ids[]=101&match_ids[]=102. Minutes within any of the match windows are returned. date can be omitted. Works with both RAW and VERIFIED | |
| channel_id | int | Single channel ID (when channel_id != 0 in /tournament-channels). Mutually exclusive with channel_ids[] | |
| stream_entity_id | int | Single stream entity ID, unsigned 64-bit (when channel_id == 0 in /tournament-channels). Mutually exclusive with stream_entity_ids[] | |
| channel_ids[] | int[] | Filter multiple channels by ID — e.g. channel_ids[]=1&channel_ids[]=2. Only applied when channel_id/stream_entity_id are omitted | |
| stream_entity_ids[] | int[] | Filter multiple stream entities by ID, unsigned 64-bit. Only applied when channel_id/stream_entity_id are omitted. Can be combined with channel_ids[] | |
| page | int | Page number (default: 1) | |
| per_page | int | Rows per page (default: 10000, max: 50000) | |
| granularity | int | VERIFIED only: 5 for 5-minute slots, the ones the dashboard is built from. 1 (default) returns 1-minute slots where available, for the last 30 days only |
Response — status=RAW, with channel_id
{
"data": [
{
"channel_name": "Rainbow6",
"platform": "Twitch",
"category": "Official",
"language": "English",
"tournament": "SLC Major 2026",
"timestamp": "2026-05-15 15:33:00",
"concurrent_viewers": 12345,
"average_viewers": 11873
}
],
"status": "RAW",
"meta": {
"tournament_id": 1234,
"tournament_name": "SLC Major 2026",
"channel_id": 5678,
"date": "2026-05-15",
"day": 6,
"scope": "channel",
"granularity": 1
}
}
Response — status=VERIFIED, with channel_id
{
"data": [
{
"channel_name": "Rainbow6",
"platform": "Twitch",
"category": "Official",
"language": "English",
"tournament": "SLC Major 2026",
"day": 6,
"phase": "Playoffs",
"label": "Faze Clan vs Falcons",
"team_a": "Faze Clan",
"team_b": "Falcons",
"timestamp": "2026-05-15 15:33:00",
"concurrent_viewers": 12345,
"average_viewers": 11873
}
],
"status": "VERIFIED",
"meta": {
"tournament_id": 1234,
"tournament_name": "Six Invitational 2025",
"channel_id": 5678,
"date": "2025-02-10",
"day": 1,
"scope": "channel",
"granularity": 1
}
}
day, phase, label, team_a, team_b are only present in VERIFIED responses. Values are null for slots outside any match window.
Response — status=RAW, without channel_id
One row per channel per minute, ordered by timestamp ASC, concurrent_viewers DESC.
{
"data": [
{
"channel_name": "Rainbow6",
"platform": "Twitch",
"category": "Official",
"language": "English",
"tournament": "SLC Major 2026",
"timestamp": "2026-05-15 15:33:00",
"concurrent_viewers": 12345,
"average_viewers": 11873
}
],
"status": "RAW",
"meta": {
"tournament_id": 1234,
"tournament_name": "SLC Major 2026",
"channel_id": null,
"date": "2026-05-15",
"day": 6,
"scope": "all_channels",
"granularity": 1,
"page": 1,
"per_page": 10000,
"count": 10000,
"total": 40519,
"pages": 5,
"has_more": true
}
}
Pagination — check this before charting a full day
Without channel_id you get one row per channel per slot, so a busy day exceeds the default per_page=10000 — the first page can end hours before the broadcast did. Watch meta.has_more / meta.total: a whole day of every channel on a big tournament is around 80 000 rows, more than one page even at the maximum per_page=50000, so page through with page until meta.has_more is false. Pages are cut by row count, not by slot, so the last slot of a truncated page is partial — don’t plot it. Requests with per_page above 15 000 bypass the response cache, so a full-day pull is always fresh.
Response — status=VERIFIED, without channel_id
One row per channel per slot of meta.granularity minutes, with match context attached.
{
"data": [
{
"channel_name": "Rainbow6",
"platform": "Twitch",
"category": "Official",
"language": "English",
"tournament": "SLC Major 2026",
"day": 6,
"phase": "Playoffs",
"label": "Faze Clan vs Falcons",
"team_a": "Faze Clan",
"team_b": "Falcons",
"timestamp": "2026-05-15 15:33:00",
"concurrent_viewers": 12345,
"average_viewers": 11873
}
],
"status": "VERIFIED",
"meta": {
"tournament_id": 1234,
"tournament_name": "SLC Major 2026",
"channel_id": null,
"date": "2026-05-15",
"day": 6,
"scope": "all_channels",
"granularity": 5,
"page": 1,
"per_page": 10000,
"count": 10000,
"total": 11556,
"pages": 2,
"has_more": true
}
}
/channel-day
Channel Day
Aggregated stats for a calendar date or a broadcast day, one row per broadcast day. With channel_id — that channel only. Without — one row per channel, ordered by hours watched within each broadcast day.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| tournament_id | int | ✓ | Tournament ID |
| date | Y-m-d | ✓* | Calendar date (UTC). Rows are split by broadcast day, so a date holding the tail of the previous evening returns it as its own row. Required unless day is given |
| day | int | ✓* | Broadcast day number, as in meta.days of /tournament-matches. Returns the whole broadcast day, also when it runs past midnight UTC. Use instead of date |
| status | string | ✓ | RAW or VERIFIED |
| channel_id | int | Channel ID (channel_id != 0 in /tournament-channels). Omit for one row per channel | |
| stream_entity_id | int | Stream entity ID, unsigned 64-bit (channel_id == 0 in /tournament-channels). Mutually exclusive with channel_id |
Response — status=RAW
{
"data": [
{
"tournament_id": 1234,
"channel_id": 5678,
"stream_entity_id": 0,
"channel_name": "Rainbow6",
"platform": "Twitch",
"category": "Official",
"is_official": true,
"language": "English",
"tournament": "SLC Major 2026",
"day": 6,
"broadcast_date": "2026-05-15",
"start_timestamp": "2026-05-15 12:00:00",
"end_timestamp": "2026-05-15 20:30:00",
"airtime": 8.5,
"airtime_minutes": 510,
"hours_watched": 104933,
"average_viewers": 12345,
"peak_viewers": 12345,
"views": 4321,
"peak_viewers_at": "2026-05-15 18:40:00",
"data_updated_at": "2026-05-16 06:00:00"
}
],
"status": "RAW",
"meta": {
"tournament_id": 1234,
"tournament_name": "SLC Major 2026",
"channel_id": null,
"date": "2026-05-15",
"day": 6,
"scope": "all_channels"
}
}
Response — status=VERIFIED (adds phase)
{
"data": [
{
"tournament_id": 1234,
"channel_id": 5678,
"stream_entity_id": 0,
"channel_name": "Rainbow6",
"platform": "Twitch",
"category": "Official",
"is_official": true,
"language": "English",
"tournament": "SLC Major 2026",
"day": 6,
"broadcast_date": "2026-05-15",
"phase": "Playoffs",
"start_timestamp": "2026-05-15 12:00:00",
"end_timestamp": "2026-05-15 20:30:00",
"airtime": 8.5,
"airtime_minutes": 510,
"hours_watched": 104933,
"average_viewers": 12345,
"peak_viewers": 12345,
"views": 4321,
"peak_viewers_at": "2026-05-15 18:40:00",
"data_updated_at": "2026-05-16 06:00:00"
}
],
"status": "VERIFIED",
"meta": {
"tournament_id": 1234,
"tournament_name": "SLC Major 2026",
"channel_id": null,
"date": "2026-05-15",
"day": 6,
"scope": "all_channels"
}
}
Reconciliation. Rows are cut from the same 5-minute slots as /tournament-channels, so summed over every date of the tournament a channel's hours_watched and airtime_minutes equal its /tournament-channels totals, up to the rounding of each row to whole hours. peak_viewers is a maximum: take the largest day, never the sum. A language's peak cannot be rebuilt from these rows either — use /tournaments-language.
/broadcast-day
Broadcast Day
Totals across all channels that broadcast the tournament for a calendar date or a broadcast day, one row per broadcast day. Concurrent viewers are summed per 5-minute slot before aggregation. Use official_only=true to limit it to official channels.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| tournament_id | int | ✓ | Tournament ID |
| date | Y-m-d | ✓* | Calendar date (UTC). Rows are split by broadcast day, so a date holding the tail of the previous evening returns it as its own row. Required unless day is given |
| day | int | ✓* | Broadcast day number, as in meta.days of /tournament-matches. Returns the whole broadcast day, also when it runs past midnight UTC. Use instead of date |
| status | string | ✓ | RAW or VERIFIED |
| official_only | bool | true to aggregate only official/main channels (default false) |
Response
{
"data": [
{
"tournament": "SLC Major 2026",
"day": 6,
"start_timestamp": "2026-05-15 12:00:00",
"end_timestamp": "2026-05-15 20:30:00",
"airtime": 8.5,
"hours_watched": 104933,
"average_viewers": 12345,
"peak_viewers": 12345,
"views": 4321
}
],
"status": "RAW",
"meta": {
"tournament_id": 1234,
"tournament_name": "SLC Major 2026",
"date": "2026-05-15",
"day": 6,
"official_only": false
}
}
Response — status=VERIFIED (adds phase)
{
"data": [
{
"tournament": "SLC Major 2026",
"day": 6,
"phase": "Playoffs",
"start_timestamp": "2026-05-15 12:00:00",
"end_timestamp": "2026-05-15 20:30:00",
"airtime": 8.5,
"hours_watched": 104933,
"average_viewers": 12345,
"peak_viewers": 12345,
"views": 4321
}
],
"status": "VERIFIED",
"meta": {
"tournament_id": 1234,
"tournament_name": "SLC Major 2026",
"date": "2026-05-15",
"day": 6,
"official_only": false
}
}
day counts only days with a broadcast — rest days are skipped, so it matches the tournament’s Days table on the site.
/broadcast-tournament
Broadcast Tournament
Single-row tournament-level totals across all channels that broadcast the tournament. Same shape for RAW and VERIFIED — RAW has shorter cache.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| tournament_id | int | ✓ | Tournament ID |
| status | string | ✓ | RAW or VERIFIED |
Response
start_timestamp / end_timestamp are min/max across all official channels.
{
"data": {
"tournament": "SLC Major 2026",
"start_timestamp": "2026-05-08 10:05:00",
"end_timestamp": "2026-05-17 18:45:00",
"airtime": 120.75,
"hours_watched": 1490660,
"average_viewers": 12345,
"peak_viewers": 12345,
"views": 36199618,
"unique_viewers": 543210,
"media_value_eur": 1454581
},
"status": "VERIFIED",
"meta": {
"tournament_id": 1234
}
}
unique_viewers may be null if post-verification has not yet completed. media_value_eur is estimated using CPM rates by language and game area.
Typical Workflow
- 1
/tournamentsDiscover available tournaments and their IDs. Filter by game, date range, or event series.
- 2
/tournament-channelsGet all channels for a tournament. Each entry has a channel_id for the next steps.
- 3
/channel-minuteor/channel-dayFetch channel-level viewership. Pass channel_id for one channel, or omit it for aggregated totals.
- 4
/broadcast-dayor/broadcast-tournamentGet broadcast totals — peak concurrent and hours watched across all channels, or official ones with official_only=true. Pass day to get a whole broadcast day.
Changelog
Every user-visible change to the Viewership API, newest first. Endpoints stay backward compatible unless an entry says otherwise.
-
- Added
data_updated_aton/tournaments,/tournament-channels,/tournaments-languageand/channel-day: when the tournament's data last changed, by moderation or by a recalculation. Re-sync tournaments whose value is newer than your last sync. - Added
airtime_minuteson/tournament-channels,/tournaments-languageand/channel-day.airtimestays in hours. - Added
viewson/tournaments. - Added
channel_urlon/tournament-channels: the channel's page on its platform, the link the site's channels table uses.nullfor in-game broadcasts with no public page. - Added
peak_viewers_aton/tournaments,/tournament-channels,/tournaments-languageand/channel-day. - Added
/tournament-channels,/tournaments-languageand/channel-dayrows carrytournament_id;/tournament-channelsand/channel-dayalso carryis_official, and/channel-daycarrieschannel_id,stream_entity_idandbroadcast_date.
- Added
-
- Added New
dayparameter on/broadcast-dayand/channel-day: pass a broadcast day number, as listed inmeta.daysof/tournament-matches, instead ofdateto get the whole broadcast day, including the part after midnight UTC. - Added
/channel-minute:granularityparameter (VERIFIED only;5returns the 5-minute slots the dashboard is built from) andmeta.granularity, the slot width actually returned. - Added
/channel-minute:average_viewers, the average audience within the slot, next toconcurrent_viewers. - Changed
dayis the broadcast day as the site's Days table lists it: a broadcast that runs past midnight UTC stays one day, so day numbers after such a broadcast are lower than before. Applies to/broadcast-day,/channel-day,/channel-minuteand/tournament-matches. - Changed Breaking:
/channel-minuteacceptsper_pageup to 50000 (was 100000). A whole day of every channel can take two pages — page through untilmeta.has_moreis false. - Changed
/channel-minute: 1-minute data has one row per channel for every minute of the broadcast in every scope, not only withchannel_idorchannel_ids[];concurrent_viewersis a number rather than a string. - Fixed
/channel-minuteVERIFIED: 1-minute data no longer ends five minutes before the broadcast does.
- Added New
-
- Fixed
/tournament-matches:hours_watchedandair_time_minuteswere doubled for matches with two teams; they now match the matches table on the site.
- Fixed
-
- Added
/tournament-matches: each match now carriesday,event_nameandphase, andmeta.stageslists the tournament page's stage filter options.meta.dayslists its day filter options, and is returned only whendateis omitted. - Added New endpoint
/tournaments-teams— viewership attributed to each team, matching the team chart on the tournament page. - Added New endpoint
/tournaments-language— viewership by broadcast language, matching the language chart on the tournament page.
- Added
-
- Fixed
daynow counts broadcast days only — rest days are skipped, matching the Days table on the site.
- Fixed
-
- Changed
/broadcast-dayand/broadcast-tournamentaggregate all channels that broadcast the tournament, not only official ones. - Added
official_onlyparameter on both endpoints (defaultfalse) restores the previous official-only totals.
- Changed
-
- Added New endpoint
/tournament-matches— full match schedule with per-match viewership.
- Added New endpoint
-
- Added Initial release:
/tournaments,/tournament-channels,/channel-minute,/channel-day,/broadcast-day,/broadcast-tournament.
- Added Initial release: