# Twitch Scraper: Streamers, Followers, Live Viewers & Clips (`vant47/twitch-streamer-scraper`) Actor

Find Twitch streamers by game, language or name with followers, live viewers, public social links, recent videos, clips and follower growth for creator research. About $0.0038 per channel: 100 cost $0.38; streams, clips and videos $0.0018 each. No login.

- **URL**: https://apify.com/vant47/twitch-streamer-scraper.md
- **Developed by:** [fortbrand](https://apify.com/vant47) (community)
- **Categories:** Social media, Videos
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.04 / 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?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Twitch Scraper: Streamers, Followers, Live Viewers & Clips

For gaming marketers, esports agencies and game publishers finding public Twitch creators and monitoring them over time. A channel profile costs about **$0.0038**, so 100 profiles cost about **$0.38**. Each live stream, video or clip costs **$0.0018**. A first run with 20 live streams costs about **$0.04**. No Twitch login or API key is needed.

Find creators by game, language or name. Collect public profiles, followers, viewers, social links and media. Compare followers in a private watch history. Independent tool; no affiliation with or endorsement from Twitch.

### What you get

| Row | Fields you can use |
| --- | --- |
| Channel | Stable channel ID, login, display name, followers, partner and affiliate flags, description, broadcast language, live status, current game and viewers, last broadcast start, available archive frequency, public social links and profile URL |
| Stream | Stable stream ID, channel ID and login, title, game name and ID, current viewers, channel followers, start time, public tags, language and channel URL |
| Video | Stable video ID, source channel, title, views, duration in seconds, creation and publication timestamps, category, thumbnail and source URL |
| Clip | Stable clip ID and slug, source channel, title, views, duration, creation timestamp, category, language, thumbnail and source URL |
| Summary | Useful row counts by type, source queries, exclusions, unchanged rows, source notes and whether the spending limit stopped delivery |

Every row starts with `verdict` and includes `type` and `scrapedAt`. Missing source values are `null`, never invented zeros.

### Start in three steps

1. Keep the prefilled Minecraft game and 20 live-stream rows, or enter channels, exact game names or channel-search words.
2. Choose the row types in `include`. Set a language or minimum live-viewer count if useful.
3. Start the Actor and open the dataset. Export JSON, CSV or Excel, or read the summary for coverage notes.

The cloud prefill returned 20 streams in **6.4 seconds** on 29 October 2026 at 512 MB. Network conditions vary; profile enrichment can take longer.

### Typical jobs

Studios can shortlist creators; agencies can track followers; analysts can build time series; content teams can compare clips.

Viewer counts are per channel; collaboration headers can show a larger shared total.

### Inputs

| Input | Meaning and example |
| --- | --- |
| `channels` | Array of channel names, @handles or channel URLs, such as `["twitch", "warframe"]` |
| `games` | Array of exact category names, such as `["Minecraft", "Just Chatting"]`, or Twitch category URLs |
| `searchTerms` | Array of channel-name search words, such as `["esport"]`; Twitch ranks these by relevance |
| `languages` | Optional array of broadcast language codes, such as `["en", "de"]` |
| `minViewers` | Minimum current live viewers; default `0` keeps offline channels, while any positive value excludes them |
| `maxItems` | Total useful rows across all selected types, from 1 to 1,000; default 20 |
| `include` | Any combination of `channel`, `liveStream`, `recentVideos`, `clips` |
| `onlyChangedSinceLastRun` | Suppress identical observations using a stable `watchId`; default false |
| `watchId` | Your private comparison-history name, using letters, digits, underscores or hyphens |
| `proxyConfiguration` | Optional Apify Proxy or custom proxy configuration; datacenter is the default |

If there is no source input, the Actor uses Minecraft. When `include` is omitted, game-only jobs return live-stream rows; channel and search jobs return channel profiles. The prefilled editor explicitly selects `liveStream`, so change that selection when switching to a profile job.

Sources are combined and deduplicated. `maxItems` is shared across types; profiles and streams come before media. Search samples up to `maxItems` candidate channels per term, then applies filters. Game discovery uses the first 100 public source slots per category; restricted game cursors are not used. Fewer matches can mean fewer rows. Discovery is bounded to three times `maxItems`, at most 2,000 candidate channels, to keep memory predictable. Narrow source lists for coverage.

#### Find live streams by game

```json
{
  "games": ["VALORANT"],
  "languages": ["en"],
  "minViewers": 100,
  "maxItems": 20,
  "include": ["liveStream"]
}
```

#### Inspect creator profiles

```json
{
  "channels": ["twitch", "riotgames", "warframe"],
  "maxItems": 3,
  "include": ["channel"]
}
```

#### Collect clips or archived broadcasts

```json
{
  "channels": ["warframe"],
  "maxItems": 40,
  "include": ["clips"]
}
```

Use `recentVideos` instead for recent archived broadcasts. Clips are ranked over **all time**; there is no date-range input in this version. Videos are past broadcasts, excluding uploads and highlights. Media uses the first 100 public source slots per type per channel; unavailable slots can reduce the count. Restricted media cursors are not used. Videos and clips are interleaved when both are selected.

### Channel fields and honest interpretation

| Field | Interpretation |
| --- | --- |
| `followers` | Source-provided total at the observation time; browser pages often show a rounded number |
| `currentViewers` | Individual channel viewers, or null when offline |
| `lastStreamedAt` | Source-reported last broadcast start, with an ISO timestamp |
| `streamsPerWeek` | Available archived broadcasts started in the last seven days, sampled from at most 20 recent archives |
| `streamsPerWeekMethod` | Explains that archive counts can undercount actual streams |
| `archiveSampleTruncated` | True when the 20-item sample ends inside the seven-day observation window |
| `avgViewersRecent` | Null: public video view totals do not establish average live viewers |
| `socialLinks` | Structured public links shown in the channel's About area, when available |
| `descriptionLinks` | URLs explicitly written in the public description, kept separately from structured social links |
| `upcomingSchedule` | Public schedule segments when Twitch supplies them; otherwise null |
| `previousFollowers` | Prior delivered follower total for this channel under the same watch |
| `followersChange` | Current followers minus the prior total, including negative changes |
| `previousObservedAt` | Observation time associated with the prior follower total |

Missing or deleted archives can undercount streaming frequency. Empty archives leave `streamsPerWeek` null. Public schedule segments are separate.

### Monitor followers every day

Create an Apify task with your channel list and a distinct `watchId`, such as `publisher-watch`. Run it once with `include: ["channel"]` to establish a baseline. Then use the same ID and set `onlyChangedSinceLastRun: true` on sequential runs.

```json
{
  "channels": ["twitch", "warframe"],
  "include": ["channel"],
  "maxItems": 2,
  "watchId": "publisher-watch",
  "onlyChangedSinceLastRun": true
}
```

The first run delivers a baseline. Later changes to followers, live status, viewers, game, description, public links or media views can trigger delivery. Timestamps and comparison fields alone do not trigger changes.

History belongs to the running user and this Actor. Different watch IDs keep independent histories. Only delivered results update it. The most recent 10,000 unique row fingerprints and 10,000 channel follower records are retained; older evicted results can appear again. An unfinished run blocks the same watch ID so its recovery cannot overwrite another run's baseline. Resume that original run or choose a new ID. Runs sharing an ID must be sequential; simultaneous starts are not supported.

Set a task schedule in Apify after verifying its first result. Retain datasets for long-term charts.

### Example output

A shortened channel observation from the real cloud tests on 29 October 2026:

```json
{
  "verdict": "twitch: offline, 2,484,858 followers.",
  "type": "channel",
  "channelId": "12826",
  "login": "twitch",
  "followers": 2484858,
  "isPartner": true,
  "isAffiliate": false,
  "language": "en",
  "isLive": false,
  "currentViewers": null,
  "lastStreamedAt": "2026-10-23T17:51:13.310Z",
  "streamsPerWeek": 1,
  "avgViewersRecent": null,
  "previousFollowers": null,
  "url": "https://www.twitch.tv/twitch"
}
```

The overview, channel, stream and media views share one dataset; filter `type` downstream. Every run also writes a free `SUMMARY` dataset row and a `SUMMARY` key-value record. Summary and input-note rows are additional to `maxItems` and have no data-row charge.

### Pricing and spending limits

| Unit | List price | Bronze | Silver | Gold and higher |
| --- | --- | --- | --- | --- |
| Channel | $0.0038 | $0.00361 | $0.00342 | $0.00304 |
| Stream | $0.0018 | $0.00171 | $0.00162 | $0.00144 |
| Video | $0.0018 | $0.00171 | $0.00162 | $0.00144 |
| Clip | $0.0018 | $0.00171 | $0.00162 | $0.00144 |

The platform start fee is $0.00005 per GB, with a minimum of one start unit. Platform usage is included in the Actor price. Failed requests, invalid inputs, unchanged suppressed rows, duplicates, empty results and summaries have no data charge. The start fee still applies when no data is delivered.

At list prices, 100 profiles cost about $0.38; 100 clips cost about $0.18; 100 profiles plus 500 clips cost about $1.28, plus the small start fee. Choosing more row types can increase your total, because each delivered type is a separate useful row. Check `maxItems` and Apify's maximum charge before starting a larger job.

The Actor checks available budget before delivery and stops cleanly when the next row does not fit. A result is saved before its charge. Durable row IDs, charge receipts and per-row billing keys protect recovery after a migration or reboot. An ambiguous recovery state stops further billing rather than guessing.

### API use

Use an Apify token in the authorization header. No Twitch token is required.

```bash
curl -X POST 'https://api.apify.com/v2/acts/vant47~twitch-streamer-scraper/run-sync-get-dataset-items' \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"games":["Minecraft"],"include":["liveStream"],"maxItems":20}'
```

For larger jobs, use asynchronous runs and read the dataset after completion. Keep tokens in secret configuration.

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("vant47/twitch-streamer-scraper").call(
    run_input={"channels": ["warframe"], "include": ["clips"], "maxItems": 20}
)
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
    if row.get("type") == "clip":
        print(row["url"], row["views"])
```

### Use with AI agents (MCP)

Connect an MCP-capable client to `https://mcp.apify.com` and allow this Actor. Ask the assistant to find Twitch streamers for a named game and language, choose a row cap, run the Actor and inspect the summary before interpreting the data. For example: “Collect 20 English-speaking VALORANT streams with at least 100 viewers, then group them by current viewers.”

Agents should retain timestamps and links, distinguish video views from live viewers, and mention missing fields. Sponsorship suitability and private demographics are not inferred.

### Limits and troubleshooting

The source is Twitch's signed-out GraphQL endpoint. Requests are serial and paced, transient errors receive fresh-session retries, and Retry-After is honored. Datacenter proxy is used first. Refused social fields and other failed requests can receive an ordinary residential retry. No account cookies, login, challenge solving or integrity-token generation is used. With proxy disabled, the Actor uses the run's address and does not add a residential fallback.

Twitch can change or restrict fields. Partial results are retained, missing values stay null and the summary explains problems. Search is relevance-ranked, not exhaustive. Live feeds move between pages; deduplication cannot make them a simultaneous census.

Only public channel and content metadata is collected. Chat participants, messages, subscriber lists, private contacts, video files and historical live averages are excluded. Twitch's terms restrict automated access; review them for your use case.

### FAQ

**Why fewer rows than `maxItems`?** Check the summary for finite feeds, filters, offline channels, unchanged observations or the spending limit.

**Why different website numbers?** Twitch rounds interface counts and live values change. Compare channel metrics and times; collaboration headers can show a shared audience. [Twitch explains Shared Viewership](https://blog.twitch.tv/en/2024/12/05/shared-viewership/).

**Can I search stream titles?** No. `searchTerms` searches channels. Use games, languages and minimum viewers for live discovery.

**Do deleted or unavailable channels cost a channel charge?** No. They produce a source note without a useful channel row. Incorrect input that reaches the Actor also becomes a free note; the input editor can reject invalid types before a run starts.

**Can free-plan users run larger jobs?** Yes. There is no artificial free-plan result cap. All users share the same 1,000-row input maximum and the limits of their own Apify budget.

**Where is follower growth?** Include `channel` for comparison fields; stream-only jobs return live observations.

**What if a run is interrupted?** Resume it to reconcile saved rows and continue. Keep the same watch ID sequential.

# Actor input Schema

## `channels` (type: `array`):

Twitch channel names, @handles or public channel URLs. For example twitch, riotgames or https://www.twitch.tv/warframe.

## `games` (type: `array`):

Exact Twitch category names, such as Minecraft or Just Chatting, or a Twitch category page URL. Discovers live channels. Multiple sources are combined and deduplicated. Each category uses its first 100 public source entries; unavailable entries and filters can reduce the result count.

## `searchTerms` (type: `array`):

Search for channel names using Twitch relevance ranking. These are channel searches, not searches inside broadcast titles.

## `languages` (type: `array`):

Optional language codes such as en, es, de, fr or ko. Filters the current broadcast language, or the channel broadcast setting when offline.

## `minViewers` (type: `integer`):

Minimum individual channel viewers, excluding shared collaboration totals. Zero keeps offline channels; a positive value keeps only live channels meeting this count.

## `maxItems` (type: `integer`):

Total useful rows across channels, streams, videos and clips. Free summary and note rows are additional. Channels and live streams are delivered before media.

## `include` (type: `array`):

Select any of channel, liveStream, recentVideos, clips. If omitted, games default to liveStream and channel/search inputs default to channel. maxItems is shared across types. Videos and clips use up to 100 public source entries per channel and type; unavailable entries can reduce the count.

## `onlyChangedSinceLastRun` (type: `boolean`):

With a stable watchId, suppress identical observations from the previous successful delivery history. Follower growth is included on channel rows. First run creates the baseline. Runs sharing a watchId must be sequential.

## `watchId` (type: `string`):

A private history name containing letters, digits, underscores or hyphens. Set the same ID on sequential runs to compare followers. Use a different ID for an independent campaign.

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

Datacenter by default, with an ordinary residential retry for refused requests and structured social links. Disable Apify Proxy to use the run address; then no automatic residential retry is used.

## Actor input object example

```json
{
  "channels": [],
  "games": [
    "Minecraft"
  ],
  "searchTerms": [],
  "languages": [],
  "minViewers": 0,
  "maxItems": 20,
  "include": [
    "liveStream"
  ],
  "onlyChangedSinceLastRun": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": []
  }
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

## `channels` (type: `string`):

No description

## `streams` (type: `string`):

No description

## `media` (type: `string`):

No description

## `summary` (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 = {
    "channels": [],
    "games": [
        "Minecraft"
    ],
    "searchTerms": [],
    "languages": [],
    "maxItems": 20,
    "include": [
        "liveStream"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("vant47/twitch-streamer-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 = {
    "channels": [],
    "games": ["Minecraft"],
    "searchTerms": [],
    "languages": [],
    "maxItems": 20,
    "include": ["liveStream"],
}

# Run the Actor and wait for it to finish
run = client.actor("vant47/twitch-streamer-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 '{
  "channels": [],
  "games": [
    "Minecraft"
  ],
  "searchTerms": [],
  "languages": [],
  "maxItems": 20,
  "include": [
    "liveStream"
  ]
}' |
apify call vant47/twitch-streamer-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,vant47/twitch-streamer-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/DXhjcE7b0D1ubrLgp/builds/AWnDSLIa8GWeQH2Q7/openapi.json
