# Twitch Scraper (`parsebird/twitch-scraper`) Actor

Scrape Twitch channels, live streams, clips, games, and VODs from the public Twitch API. No login or API key. Get followers, partner status, viewer counts, stream titles, and games. Export as JSON, CSV, or Excel.

- **URL**: https://apify.com/parsebird/twitch-scraper.md
- **Developed by:** [ParseBird](https://apify.com/parsebird) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.49 / 1,000 channels

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

### Twitch Scraper

**Twitch Scraper** extracts structured data from [Twitch](https://www.twitch.tv) using the platform's **public GraphQL API** — no login, no API key, no browser. Scrape **channel profiles**, **live streams**, **clips**, **games and categories**, and **VODs** in one run. Get follower counts, partner and affiliate status, live viewer counts, stream titles, the games being played, recent past broadcasts, and top clips.

<table><tr>
<td style="border-left:4px solid #9146FF;padding:12px 16px;font-weight:600">
Six modes in one Twitch scraper — channel profiles (up to 1,000), channel search, top live streams, streams for a game, top games, and clips by time period. Usernames or full twitch.tv URLs both work.
</td>
</tr></table>

##### Copy to your AI assistant

Copy this block into ChatGPT, Claude, Cursor, or any LLM to start using this actor.

```
Actor: parsebird/twitch-scraper (Twitch Scraper on Apify)
Purpose: scrape Twitch channels, streams, clips, games, and VODs from the public Twitch GraphQL API (no auth).
Call it with ApifyClient. Example (Python):
  from apify_client import ApifyClient
  client = ApifyClient("<APIFY_TOKEN>")
  run = client.actor("parsebird/twitch-scraper").call(run_input={
      "mode": "channels",                 # channels | searchChannels | topStreams | gameStreams | topGames | clips
      "channelUsernames": ["shroud", "pokimane", "xqc"],  # channels + clips modes; usernames or twitch.tv URLs
      "searchQuery": "valorant",           # searchChannels mode
      "gameName": "League of Legends",     # gameStreams mode (exact Twitch category name)
      "maxResults": 30,                    # channels: up to 1000; gameStreams/topGames/clips: up to 100; topStreams: 30
      "clipPeriod": "LAST_WEEK",           # LAST_DAY | LAST_WEEK | LAST_MONTH | ALL_TIME
      "includeVideos": True,               # channels mode: attach 5 recent VODs
      "includeClips": False                # channels mode: attach top 5 clips
  })
  for item in client.dataset(run["defaultDatasetId"]).iterate_items():
      print(item)
Output depends on mode: channel profiles (login, displayName, followersCount, isPartner, isLive, currentViewers,
  lastBroadcastTitle, recentVideos[], topClips[]), stream rows (broadcasterLogin, title, viewersCount, game,
  startedAt), game rows (name, viewersCount, broadcastersCount, boxArtUrl), or clip rows (title, url, viewCount,
  durationSeconds, game, channelLogin, curatorLogin).
API docs: https://docs.apify.com/api/v2  |  Token: https://console.apify.com/account/integrations
```

### What can Twitch Scraper do?

The Twitch Scraper reads the same public data any visitor sees on twitch.tv, through Twitch's own GraphQL endpoint. Pick one of six modes per run:

- 👤 **Channel profiles** — pass a list of usernames (or channel URLs) and get full profiles for up to **1,000 channels**: follower count, partner/affiliate status, whether they are live now, current viewers and game, last broadcast, and account creation date. Optionally attach the **5 most recent VODs** and **top 5 clips**.
- 🔎 **Search channels** — find channels matching a keyword, name, or game.
- 📡 **Top live streams** — the current top streams across all of Twitch, ranked by viewers.
- 🎮 **Streams for a game** — every live stream in a specific category (e.g. `Just Chatting`, `League of Legends`), ranked by viewers.
- 🏆 **Top games / categories** — trending games with total viewers, live-channel counts, and box art.
- 🎬 **Clips from channels** — top clips for one or more channels over the **last day, week, month, or all time**.

Platform features: [schedule](https://docs.apify.com/platform/schedules) runs to track follower growth or live status over time, call the actor from the [Apify API](https://docs.apify.com/api/v2), chain it into [integrations](https://docs.apify.com/platform/integrations) (Zapier, Make, n8n, Slack, GitHub), and export to **JSON, CSV, or Excel**.

### Why scrape Twitch?

- **Influencer and sponsorship research** — shortlist streamers by follower count, partner status, and the games they play.
- **Live monitoring** — poll `topStreams` or `gameStreams` on a schedule to see who is live and how big their audience is right now.
- **Games and category trends** — track which games are gaining or losing viewers with `topGames`.
- **Content and highlights** — pull the best clips for a channel or a time window for editing, reels, or archives.
- **Competitive analysis** — compare a set of channels' growth, broadcast cadence, and game mix.

### Input parameters

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `mode` | string | **Yes** | `channels` | `channels`, `searchChannels`, `topStreams`, `gameStreams`, `topGames`, or `clips` |
| `channelUsernames` | array | For `channels`, `clips` | `[]` | Twitch usernames or `twitch.tv/...` URLs. Up to 1,000 |
| `searchQuery` | string | For `searchChannels` | — | Search term for finding channels |
| `gameName` | string | For `gameStreams` | — | Exact Twitch category name, e.g. `League of Legends` |
| `maxResults` | integer | No | 30 | Channel profiles: up to 1,000. Game streams / top games / clips: up to 100. Top live streams: 30 |
| `clipPeriod` | string | No | `LAST_WEEK` | `LAST_DAY`, `LAST_WEEK`, `LAST_MONTH`, or `ALL_TIME` |
| `includeVideos` | boolean | No | `true` | `channels` mode: attach the 5 most recent VODs |
| `includeClips` | boolean | No | `false` | `channels` mode: attach the top 5 clips for `clipPeriod` |
| `proxyConfiguration` | object | No | Apify Proxy | Optional — Twitch works without a proxy |

### What data can you extract from Twitch?

**Channel profiles**

| Field | Description |
|-------|-------------|
| `login` / `displayName` | Channel username and display name |
| `description` | Channel bio |
| `profileImageUrl` / `bannerImageUrl` | Avatar and banner image URLs |
| `url` | Channel page URL |
| `followersCount` | Total follower count |
| `isPartner` / `isAffiliate` | Twitch Partner / Affiliate status |
| `isLive` | Whether the channel is streaming now |
| `currentViewers` / `streamTitle` / `currentGame` | Live stream stats (when live) |
| `lastBroadcastTitle` / `lastBroadcastGame` / `lastBroadcastDate` | Most recent broadcast |
| `createdAt` | Account creation date |
| `recentVideos` | Up to 5 recent VODs: title, view count, duration, game |
| `topClips` | Up to 5 top clips: title, URL, view count, curator |

**Live streams, game streams, search results**

| Field | Description |
|-------|-------------|
| `broadcasterLogin` / `broadcasterDisplayName` | Channel username and display name |
| `broadcasterFollowers` | Follower count |
| `title` | Stream title |
| `viewersCount` | Current viewer count |
| `game` | Game / category name |
| `startedAt` | Stream start time |
| `url` | Channel URL |

**Top games / categories**

| Field | Description |
|-------|-------------|
| `name` | Game / category name |
| `viewersCount` | Total viewers across all streams |
| `broadcastersCount` | Number of live channels |
| `boxArtUrl` | Game cover image |

**Clips**

| Field | Description |
|-------|-------------|
| `title` / `url` | Clip title and URL |
| `viewCount` / `durationSeconds` | View count and length |
| `game` | Game name |
| `channelLogin` / `curatorLogin` | Source channel and who created the clip |
| `thumbnailUrl` | Clip thumbnail |

### Output example

Channel profile (`channels` mode):

```json
{
  "id": "37402112",
  "login": "shroud",
  "displayName": "shroud",
  "description": "I'm back baby",
  "profileImageUrl": "https://static-cdn.jtvnw.net/jtv_user_pictures/...",
  "url": "https://www.twitch.tv/shroud",
  "followersCount": 11313275,
  "isPartner": true,
  "isAffiliate": false,
  "isLive": false,
  "currentViewers": null,
  "lastBroadcastTitle": "Ready or Not with friends",
  "lastBroadcastGame": "Ready or Not",
  "createdAt": "2012-11-03T15:50:32Z",
  "recentVideos": [
    { "id": "2724725765", "title": "Marathon stream", "viewCount": 260226, "durationSeconds": 27466, "game": "Marathon" }
  ]
}
```

Stream row (`topStreams` / `gameStreams` modes):

```json
{
  "broadcasterLogin": "caedrel",
  "broadcasterDisplayName": "Caedrel",
  "broadcasterFollowers": 1667911,
  "title": "🔴 LEC WAITING ROOM 🔴",
  "viewersCount": 23259,
  "game": "League of Legends",
  "startedAt": "2026-08-28T07:27:44Z",
  "url": "https://www.twitch.tv/caedrel"
}
```

### How to scrape Twitch

1. Open the Actor and go to the **Input** tab.
2. Choose a **Mode**.
3. Fill the field that mode needs:
   - `channels` or `clips` → **Channel usernames** (usernames or full `twitch.tv/...` URLs).
   - `searchChannels` → **Search query**.
   - `gameStreams` → **Game name** (the exact Twitch category name).
   - `topStreams` and `topGames` need no extra input.
4. Set **Max results**. Keep it low for the first run.
5. For `channels` mode, toggle **Include recent VODs** and **Include top clips**, and pick a **Clip period**.
6. Click **Start**. When the run finishes, open the **Dataset** tab and export as JSON, CSV, or Excel.

#### Run from the Apify API — Python

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")

run = client.actor("parsebird/twitch-scraper").call(run_input={
    "mode": "gameStreams",
    "gameName": "Just Chatting",
    "maxResults": 50,
})

for stream in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(stream["broadcasterLogin"], stream["viewersCount"], stream["title"])
```

#### Run from the Apify API — JavaScript

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });

const run = await client.actor('parsebird/twitch-scraper').call({
    mode: 'channels',
    channelUsernames: ['shroud', 'pokimane', 'xqc'],
    includeVideos: true,
    includeClips: true,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

The actor also works over plain [HTTP](https://docs.apify.com/api/v2/act-runs-post) and as an [MCP](https://mcp.apify.com) tool for AI assistants.

### How it works

1. **Validate input** — the actor checks the mode and the field it requires (usernames, query, or game name).
2. **Query the Twitch GraphQL API** — `https://gql.twitch.tv/gql` with Twitch's public web client ID. No authentication is sent.
3. **Batch and paginate** — channel profiles are fetched in batches of 30 usernames per request; browse modes fetch a single ranked page.
4. **Normalize** — nested GraphQL responses are flattened into clean, consistent records; streams are sorted by viewer count.
5. **Push and charge** — each record is written to the dataset and charged once (see Pricing). Transient API errors are retried; unknown usernames and games are logged and skipped.

### How much does it cost to scrape Twitch?

Pricing is **pay-per-event** with four events, one per record type:

| Event | Fires for | Free | Bronze | Silver | Gold |
|-------|-----------|------|--------|--------|------|
| `channel` | `channels` + `searchChannels` records | $2.99 / 1k | $2.49 / 1k | $1.99 / 1k | $1.49 / 1k |
| `stream` | `topStreams` + `gameStreams` records | $1.99 / 1k | $1.49 / 1k | $1.29 / 1k | $0.99 / 1k |
| `game` | `topGames` records | $1.99 / 1k | $1.49 / 1k | $1.29 / 1k | $0.99 / 1k |
| `clip` | `clips` records | $1.99 / 1k | $1.49 / 1k | $1.29 / 1k | $0.99 / 1k |

Scraping 100 channel profiles costs about **$0.30** on the Free plan. Getting the top 30 live streams costs about **$0.06**. Apify's monthly platform credits on the Free plan cover thousands of records. See [Apify pricing](https://apify.com/pricing).

### Is it legal to scrape Twitch?

Scraping publicly available data is generally legal. This Actor accesses only public data through Twitch's own public API endpoints — the same data any visitor sees on twitch.tv — and never logs in or bypasses access controls. You are responsible for how you use the data: comply with Twitch's Terms of Service, and with data-protection laws such as GDPR and CCPA when the data includes personal information. For background, read the Apify blog on [the legality of web scraping](https://blog.apify.com/is-web-scraping-legal/).

### Related actors

- [YouTube Channel Search Scraper](https://apify.com/parsebird/youtube-channel-search-scraper) — find and profile YouTube channels.
- [YouTube Live Chat Scraper](https://apify.com/parsebird/youtube-live-chat-scraper) — capture live chat messages from YouTube streams.
- [Kick Video Downloader](https://apify.com/parsebird/kick-video-downloader) — download videos from Kick.
- [Threads Scraper](https://apify.com/parsebird/threads-scraper) — scrape profiles and posts from Threads.
- [Bluesky Scraper](https://apify.com/parsebird/bluesky-scraper) — scrape posts and profiles from Bluesky.

Browse all [ParseBird actors](https://apify.com/parsebird).

### FAQ

**Do I need a Twitch account or API key?**
No. The Actor uses Twitch's public GraphQL endpoint with the same client ID the website ships to every visitor. Nothing is logged in.

**How many results can I get per mode?**
Channel profiles: up to 1,000 per run. Streams for a game, top games, and clips: up to 100. Top live streams: Twitch caps the global directory at 30. Search returns roughly the top 10–20 matches.

**Why do top-streams and clips modes stop at a certain number?**
Twitch applies an integrity check to deep pagination of its directory. The Actor fetches everything the API returns in one ranked page and stops cleanly when Twitch limits further pages — you still get the top results.

**Can I pass channel URLs instead of usernames?**
Yes. `https://www.twitch.tv/shroud`, `twitch.tv/shroud`, `@shroud`, and `shroud` all work.

**What happens if a username or game doesn't exist?**
It is logged as a warning and skipped; the run continues with the rest.

**How do I get a channel's recent VODs and clips?**
Use `channels` mode with `includeVideos` and/or `includeClips` enabled. VODs are the 5 most recent past broadcasts; clips are the top 5 for the selected `clipPeriod`.

**Can I schedule this to track a channel over time?**
Yes. Use Apify [Schedules](https://docs.apify.com/platform/schedules) to run `channels` mode daily and record follower counts, live status, and broadcast history.

**Something's not working — how do I report it?**
Open an issue on the Actor's **Issues** tab with your input and what you expected. Feedback is welcome.

# Actor input Schema

## `mode` (type: `string`):

What to scrape.

## `channelUsernames` (type: `array`):

Twitch usernames or channel URLs. Used by the 'Channel profiles' and 'Clips from channels' modes. Up to 1,000.

## `searchQuery` (type: `string`):

Search term for the 'Search channels' mode (e.g. a name, game, or keyword).

## `gameName` (type: `string`):

Exact Twitch category name for the 'Streams for a game' mode (e.g. "League of Legends", "Just Chatting").

## `maxResults` (type: `integer`):

Maximum records to return. Channel profiles: up to 1,000. Streams for a game / top games / clips: up to 100. Top live streams: Twitch caps this at 30.

## `clipPeriod` (type: `string`):

Time range for clips (used by 'Clips from channels' and by 'Include top clips').

## `includeVideos` (type: `boolean`):

In 'Channel profiles' mode, attach the channel's 5 most recent past broadcasts (VODs).

## `includeClips` (type: `boolean`):

In 'Channel profiles' mode, attach the channel's top 5 clips for the selected clip period.

## `proxyConfiguration` (type: `object`):

Twitch works without a proxy. Enable one to spread large runs across IPs.

## Actor input object example

```json
{
  "mode": "channels",
  "channelUsernames": [
    "shroud",
    "pokimane",
    "xqc"
  ],
  "searchQuery": "valorant",
  "gameName": "League of Legends",
  "maxResults": 30,
  "clipPeriod": "LAST_WEEK",
  "includeVideos": true,
  "includeClips": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "mode": "channels",
    "channelUsernames": [
        "shroud",
        "pokimane",
        "xqc"
    ],
    "searchQuery": "valorant",
    "gameName": "League of Legends",
    "maxResults": 30,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("parsebird/twitch-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "mode": "channels",
    "channelUsernames": [
        "shroud",
        "pokimane",
        "xqc",
    ],
    "searchQuery": "valorant",
    "gameName": "League of Legends",
    "maxResults": 30,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("parsebird/twitch-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "mode": "channels",
  "channelUsernames": [
    "shroud",
    "pokimane",
    "xqc"
  ],
  "searchQuery": "valorant",
  "gameName": "League of Legends",
  "maxResults": 30,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call parsebird/twitch-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,parsebird/twitch-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/Slov5B2cyYQK50eBB/builds/kVSmwf5xCQ7r5hi8d/openapi.json
