L logiover
data · Jul 9, 2026 · 6 min read

How to Scrape Twitch Streams, Games & Channels in 2026

Pull Twitch live streams, top games, channel profiles, VODs and clips via Twitch's own public GraphQL — no API key, no OAuth, no dev app, no browser.

Twitch has an official API — Helix — but using it means registering a developer app, managing OAuth tokens, and living inside official rate limits, all before you pull your first row. For a one-off creator-discovery sweep or a scheduled directory snapshot, that setup cost is out of proportion to the job. Meanwhile, Twitch’s own website reads its data from a public GraphQL endpoint using an anonymous web client ID — the same one your browser uses, no login required. This guide covers how that GraphQL surface works, why guest pagination forces a fan-out strategy for volume, and how to pull thousands of live streams, channel profiles, VODs or clips in one run with no key and no browser.

What’s worth extracting

The actor exposes seven modes through one input form, and every row is tagged with _mode so you can mix modes in a single dataset and filter later. The fields depend on the mode:

  • Streams (topStreams, streamsByGame) — login, displayName, title, gameName, viewersCount, startedAt, freeform tags, isPartner / isAffiliate, thumbnailUrl.
  • Games / categories (topGames) — rank, name, gameId, viewersCount, boxArtUrl and a directory URL.
  • Channel profiles (user) — login, displayName, followers, isPartner, isAffiliate, isLive, liveGame, liveViewers, description, profileImageUrl.
  • VODs (videos) — title, viewCount, durationMinutes, publishedAt, gameName, channelName.
  • Clips (clips) — title, viewCount, durationSeconds, createdAt, curatorName (who clipped it), gameName.
  • Search (search) — channel or game matches for a free-text term.

Universal on every row: _mode, a canonical twitchUrl, and scrapedAt (ISO 8601). The dataset ships with six pre-built views (Overview, Streams, Games, Channels, Videos, Clips) so you can slice without post-processing.

How the source actually works

The engine makes direct HTTP calls to Twitch’s public GraphQL endpoint using the anonymous web Client-ID — no API key, no OAuth, no registered Helix developer app, and no headless browser. It’s the exact data path the twitch.tv front-end uses for guest visitors.

You pick a mode and fill only the fields it needs. The seven modes map to Twitch’s directory and channel surfaces:

ModeWhat it returns
topStreamsSweeps the top games and pulls their live streams — the whole live directory (highest volume)
topGamesTop games / categories ranked by current viewers
streamsByGameLive streams for one or more specific games
userChannel / streamer profile for one or many logins (batch)
videosA channel’s past broadcasts / VODs
clipsA channel’s top clips
searchFree-text search across channels or games

A high-volume directory sweep:

{
  "mode": "topStreams",
  "gameFanout": 30,
  "gameSort": "VIEWER_COUNT",
  "maxResults": 500
}

A batch profile pull for lead-gen — logins accepts a list, and a single login also takes a full URL or @handle:

{
  "mode": "user",
  "logins": ["shroud", "pokimane", "xqc", "ninja"]
}

Live streams for a single category:

{
  "mode": "streamsByGame",
  "game": "VALORANT",
  "maxResults": 200
}

Open the Twitch Scraper on Apify — one run sweeps the live directory into thousands of stream rows, or batches channel profiles for lead-gen. Twitch’s own GraphQL, no key, no OAuth, no browser. Export to JSON, CSV or Excel.

The access reality: why it fans out instead of paging

This is the key operational fact. Twitch caps each GraphQL request at 100 items, and it gates deep cursor pagination for guests — an anonymous client can’t page endlessly through one directory. So the naive “walk the stream list to the end” approach stalls after 100 rows.

The actor’s answer is to fan out rather than page one list. In topStreams mode it sweeps across many games (controlled by gameFanout, 1–100, default 30) and pulls up to 100 live streams from each, then aggregates them into one dataset. Because each game is its own request returning up to 100 streams, sweeping 30 games can yield thousands of live-stream rows in a single run — far past the 100-item guest ceiling. maxResults drives this multi-game sweep for topStreams and streamsByGame.

The mode-specific sort and filter knobs:

  • gameSort — directory ordering for topStreams / topGames: VIEWER_COUNT, RELEVANCE or NUM_FOLLOWERS.
  • videoSortTIME (newest) or VIEWS for VODs.
  • clipPeriodLAST_DAY, LAST_WEEK, LAST_MONTH or ALL_TIME, plus clipSort for ordering.
  • searchIndexCHANNEL (streamers) or GAME (categories) for search mode.

Example output

A stream row and a channel-profile row, both carrying _mode:

{
  "_mode": "topStreams",
  "login": "shroud",
  "displayName": "shroud",
  "title": "ranked grind",
  "gameName": "VALORANT",
  "viewersCount": 28450,
  "startedAt": "2026-07-06T09:12:00Z",
  "tags": ["English", "FPS"],
  "isPartner": true,
  "twitchUrl": "https://www.twitch.tv/shroud",
  "scrapedAt": "2026-07-06T12:00:00Z"
}
{
  "_mode": "user",
  "login": "pokimane",
  "displayName": "pokimane",
  "followers": 9420000,
  "isPartner": true,
  "isAffiliate": false,
  "isLive": false,
  "liveGame": null,
  "description": "hi i'm poki",
  "twitchUrl": "https://www.twitch.tv/pokimane",
  "scrapedAt": "2026-07-06T12:00:00Z"
}

Typical use cases

  • Creator and influencer discovery — find streamers by game or keyword, rank channels by followers and live viewers, and build outreach lists for sponsorships and brand deals.
  • Gaming and esports analytics — track which games top the directory over time, measure category viewership, and benchmark titles by concurrent viewers.
  • Live stream monitoring — snapshot who is live in a category right now, with viewer counts, titles and tags, on a schedule.
  • Streamer lead-gen — export channel profiles (followers, partner status, current game, bio) as clean CSV for sales and talent scouting.
  • Recommendation engines and ML — bulk-ingest streams, games, clips and channels to train content or collaborative recommenders.
  • AI agents and RAG — wrap the actor as a tool so an LLM can answer “who are the top VALORANT streamers live now?” or embed clip and VOD metadata.

Build-it-yourself vs. managed actor

You could reverse-engineer the GraphQL calls yourself — the anonymous Client-ID is discoverable. What’s actually involved is more than the first query: constructing the GraphQL payloads for seven different endpoints, the fan-out logic that works around the 100-item cap and guest cursor-gating, normalizing wildly different response shapes (streams, games, channels, VODs, clips) into flat rows with a shared _mode tag, and keeping all of it green when Twitch adjusts its persisted queries.

On cost, the actor is pay-per-result — you pay for the rows you extract, with no separate platform-fee math and no Helix rate-limit ceiling to negotiate. A topStreams sweep of the directory easily returns thousands of live-stream rows for a few cents to low single dollars. Because it’s pay-per-result and keyless, an AI agent can also call it through Apify’s MCP server on demand.

Common pitfalls

  • Don’t expect endless pagination. The 100-item-per-request cap and guest cursor-gating are Twitch’s, not the actor’s. Use topStreams with a higher gameFanout for volume rather than expecting a single list to page forever.
  • Fill only the fields your mode uses. Each mode reads a different subset of the input. Setting game in user mode does nothing; check the mode table before configuring.
  • Live data is a snapshot. viewersCount, isLive and startedAt reflect the instant of scraping. For trends, run on a schedule and store scrapedAt — a single run is one moment in time.
  • login normalization is forgiving. A full URL or @handle works where a login is expected, but batch pulls use logins (array) — don’t cram multiple handles into the single login field.
  • Clip windows matter. clips respects clipPeriod; a channel with few recent clips will return little on LAST_DAY. Widen to ALL_TIME if you want the channel’s best-ever clips.
  • Filter mixed datasets by _mode. If you run multiple modes into one dataset, always pivot on _mode — stream rows and channel rows have different fields, and merging them blindly will produce sparse columns.

Wrapping up

Twitch’s public GraphQL gives you the whole live directory, channel profiles, VODs and clips without Helix’s app-registration and OAuth overhead — the catch is the 100-item cap and guest cursor-gating that force a fan-out strategy. This actor solves the fan-out, normalizes seven response shapes into flat rows, and tags each with _mode, so you can go from a mode selection to thousands of structured Twitch rows in one run.

Run the Twitch Scraper on Apify — thousands of live streams, plus top games, channel profiles, VODs and clips, from Twitch’s own public GraphQL. No key, no OAuth, no browser. Export to JSON, CSV or Excel, and start on Apify’s free monthly credit.

Related guides