Partner API

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.

Errors

{
  "error": "game_id is not in your allowed games list.",
  "status": 403
}
Code Meaning
401 Missing or invalid token
403 Requested data is outside your partner access scope
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 Tournament day number (1-based, from tournament start date)
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 5-minute slot timestamp (UTC) for channel-minute
start_timestamp Min start datetime across official channels (UTC)
end_timestamp Max end datetime across official channels (UTC)
airtime Total broadcast hours
hours_watched Total hours watched (viewers × time)
average_viewers Average concurrent viewers
peak_viewers Maximum concurrent viewers
concurrent_viewers Live viewers in a single 5-minute slot
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)
GET /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,
      "prize_pool": 3000000,
      "is_offline": 1,
      "organizer_names": "Ubisoft",
      "venue_names": "Montreal",
      "matches_count": 42,
      "match_days": 12
    }
  ],
  "meta": {
    "page": 1,
    "per_page": 50,
    "total": 1,
    "sort_by": "ends_at",
    "sort_order": "DESC"
  }
}
GET /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": [
    {
      "channel_id": 5678,
      "stream_entity_id": 0,
      "channel_name": "Rainbow6",
      "channel_slug": "rainbow6",
      "platform": "Twitch",
      "platform_slug": "twitch.tv",
      "category": "Official",
      "language": "English",
      "other_languages": [],
      "hours_watched": 920000.0,
      "peak_viewers": 180000,
      "avg_viewers": 95000.0,
      "airtime": 54.0,
      "views": 4200000
    }
  ],
  "meta": {
    "tournament_id": 1234,
    "official_only": false,
    "sort_by": "hours_watched",
    "sort_order": "DESC",
    "count": 18
  }
}
GET /channel-minute

Channel Minute

Concurrent viewers in 5-minute intervals for a given day. Omit channel_id to get totals summed across all channels.

RAW — near real-time, ≤5 min delay VERIFIED — post-processed with match context, available 24–120 h after stream end

Query Parameters

Parameter Type Required Description
tournament_id int Tournament ID
date Y-m-d Date to query
status string RAW or VERIFIED
channel_id int Channel ID from /tournament-channels (when channel_id != 0). Omit for cross-channel totals
stream_entity_id int Stream entity ID from /tournament-channels (when channel_id == 0). Mutually exclusive with channel_id

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
    }
  ],
  "status": "RAW",
  "meta": {
    "tournament_id": 1234,
    "tournament_name": "SLC Major 2026",
    "channel_id": 5678,
    "date": "2026-05-15",
    "day": 6,
    "scope": "channel"
  }
}

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
    }
  ],
  "status": "VERIFIED",
  "meta": {
    "tournament_id": 1234,
    "tournament_name": "Six Invitational 2025",
    "channel_id": 5678,
    "date": "2025-02-10",
    "day": 1,
    "scope": "channel"
  }
}

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 5-minute slot, 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
    }
  ],
  "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, without channel_id

One row per channel per 5-minute slot, 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
    }
  ],
  "status": "VERIFIED",
  "meta": {
    "tournament_id": 1234,
    "tournament_name": "SLC Major 2026",
    "channel_id": null,
    "date": "2026-05-15",
    "day": 6,
    "scope": "all_channels"
  }
}
GET /channel-day

Channel Day

Aggregated daily stats. With channel_id — one summary row for that channel. Without — one row per channel ordered by hours watched.

RAW — near real-time, ≤5 min delay VERIFIED — post-processed, available 24–120 h after stream end

Query Parameters

Parameter Type Required Description
tournament_id int Tournament ID
date Y-m-d Date to query
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 (channel_id == 0 in /tournament-channels). Mutually exclusive with channel_id

Response — status=RAW

{
  "data": [
    {
      "channel_name": "Rainbow6",
      "platform": "Twitch",
      "category": "Official",
      "language": "English",
      "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": 104932.5,
      "average_viewers": 12345,
      "peak_viewers": 12345,
      "views": 4321
    }
  ],
  "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": [
    {
      "channel_name": "Rainbow6",
      "platform": "Twitch",
      "category": "Official",
      "language": "English",
      "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": 104932.5,
      "average_viewers": 12345,
      "peak_viewers": 12345,
      "views": 4321
    }
  ],
  "status": "VERIFIED",
  "meta": {
    "tournament_id": 1234,
    "tournament_name": "SLC Major 2026",
    "channel_id": null,
    "date": "2026-05-15",
    "day": 6,
    "scope": "all_channels"
  }
}
GET /broadcast-day

Broadcast Day

Daily totals across all official channels. Concurrent viewers are summed per 5-minute slot before aggregation.

RAW — ≤30 min delay VERIFIED — post-processed, available 24–120 h after stream end

Query Parameters

Parameter Type Required Description
tournament_id int Tournament ID
date Y-m-d Date to query
status string RAW or VERIFIED

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": 104932.5,
      "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
  }
}

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": 104932.5,
      "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
  }
}
GET /broadcast-tournament

Broadcast Tournament

Single-row tournament-level totals across all official channels. Same shape for RAW and VERIFIED — RAW has shorter cache.

RAW — ≤30 min cache VERIFIED — post-processed totals

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": 1490659.75,
    "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. 1
    /tournaments

    Discover available tournaments and their IDs. Filter by game, date range, or event series.

  2. 2
    /tournament-channels

    Get all channels for a tournament. Each entry has a channel_id for the next steps.

  3. 3
    /channel-minute or /channel-day

    Fetch channel-level viewership. Pass channel_id for one channel, or omit it for aggregated totals.

  4. 4
    /broadcast-day or /broadcast-tournament

    Get official broadcast totals — peak concurrent and hours watched across main streams.