# Twitch Live Stream Intelligence (`tuhin/twitch-live-stream-intelligence`) Actor

Monitor Twitch streams, detect viewer growth, track live channels, discover rising categories, and collect structured Twitch intelligence automatically — from public data only.

- **URL**: https://apify.com/tuhin/twitch-live-stream-intelligence.md
- **Developed by:** [Tuhin](https://apify.com/tuhin) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 66.7% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.01 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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 Live Stream Intelligence

**Monitor Twitch streams, detect viewer growth, track live channels, discover rising categories, and collect structured Twitch intelligence automatically — from public data only.**

This is not a generic scraper. It turns publicly available Twitch information into structured intelligence: it tells you *who is live now*, *how their audience is moving*, *which categories are heating up*, and *what brands are being mentioned* — and it detects meaningful changes over time when you run it on a schedule.

> **Responsible use:** This Actor only reads publicly available Twitch data. It does **not** create viewers, inflate counts, automate accounts, generate fake engagement, or bypass any authentication, CAPTCHA, or anti-bot protection. It is a monitoring and analytics tool.

***

### Who it's for

- **Creators & managers** — track your own and competitors' live performance and growth.
- **Agencies & talent scouts** — discover rising streamers and trending categories.
- **Brands & marketers** — surface brand/sponsorship mentions across live streams.
- **Researchers & analysts** — build your own historical dataset of the live Twitch ecosystem.

### What it does

- Detects whether each channel is **live or offline**.
- Collects stream **title, streamer, category/game, viewer count, follower count, start time, duration, language, tags, thumbnail, profile image**, and URLs.
- Discovers currently-live channels **by category/game**.
- Computes **viewer change, growth %, velocity, peak/min/average** viewers, and flags trends as `normal`, `rising`, `spike`, or `declining`.
- Emits structured **events**: `stream_start`, `stream_end`, `title_change`, `category_change`, `language_change`, `viewer_change`.
- Aggregates **category intelligence** (live channel count, total/average/median viewers, top channels).
- Produces **streamer intelligence** (latest snapshot + trend per channel).
- Detects **brand & sponsorship signals** from public titles/tags/description — labelled as *detected mentions*, never confirmed sponsorships.

### Input

Run it with just a channel name. All fields:

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `channels` | array | – | Usernames or URLs, e.g. `"xqc"` or `"https://twitch.tv/xqc"`. |
| `categories` | array | – | Games/categories to discover live channels in, e.g. `"Just Chatting"`. |
| `languages` | array | – | Keep only these languages (2-letter, e.g. `"EN"`). |
| `liveOnly` | boolean | `false` | Skip offline channels. |
| `minimumViewers` / `maximumViewers` | integer | `0` | Viewer bounds for live streams (`0` = no bound). |
| `minimumStreamDurationSeconds` | integer | `0` | Minimum uptime for live streams. |
| `monitoringIntervalSeconds` | integer | `0` | Re-check every N seconds within one run (`0` = single snapshot). |
| `maximumMonitoringDurationSeconds` | integer | `0` | Cap for a monitoring run. |
| `maximumChannels` | integer | `0` | Safety cap per cycle (`0` = no cap). |
| `categoryStreamsPerGame` | integer | `30` | How many live streams to pull per category. |
| `enableAnalysis` | boolean | `true` | Compute growth/category/streamer/brand intelligence. |
| `previousDatasetId` | string | – | Dataset ID of a prior run — used as baseline for cross-run change detection. |
| `proxyConfiguration` | object | Apify Proxy | Proxy for Twitch requests. |

#### Example inputs

**Single streamer**

```json
{ "channels": ["xqc"] }
```

**Monitor ten competitors**

```json
{ "channels": ["pokimane","kaicenat","ninja","shroud","amouranth","tarik","summit1g","hasanabi","xqc","ludwig"], "liveOnly": true }
```

**Track a gaming category and find rising channels**

```json
{ "categories": ["League of Legends"], "minimumViewers": 500, "languages": ["EN"], "enableAnalysis": true }
```

**Continuous monitoring (build a short series in one run)**

```json
{ "channels": ["kaicenat"], "monitoringIntervalSeconds": 60, "maximumMonitoringDurationSeconds": 600 }
```

### Output

#### 1) Channel observations (default dataset)

One normalized record per channel per cycle:

```json
{
  "channelName": "eliasn97",
  "streamerName": "eliasn97",
  "channelUrl": "https://www.twitch.tv/eliasn97",
  "streamUrl": "https://www.twitch.tv/eliasn97",
  "isLive": true,
  "title": "Reactions & Talks | !iconleague",
  "category": "Just Chatting",
  "gameId": "509658",
  "viewerCount": 25454,
  "followerCount": 2412771,
  "language": "DE",
  "tags": ["Deutsch"],
  "startedAt": "2026-08-30T17:01:30Z",
  "observedAt": "2026-08-30T17:35:02.000Z",
  "streamDurationSeconds": 2012,
  "thumbnailUrl": "https://static-cdn.jtvnw.net/previews-ttv/live_user_eliasn97-1920x1080.jpg",
  "profileImageUrl": "https://static-cdn.jtvnw.net/.../profile_image-300x300.png",
  "viewerChange": 320,
  "viewerChangePercent": 1.28,
  "growthClassification": "normal",
  "detectedBrands": [{ "brand": "Red Bull", "confidence": 0.6, "sources": ["title"], "detectedMention": true, "confirmedSponsorship": false }],
  "sponsorshipSignals": [{ "source": "title", "phrase": "sponsored by" }],
  "detectedPromoCodes": [{ "source": "title", "code": "ELIAS10" }],
  "dataSource": "twitch-public-gql"
}
```

#### 2) Stream events (named dataset `events`)

```json
{ "channelName": "kaicenat", "eventType": "viewer_change", "observedAt": "2026-08-30T17:35:02.000Z", "previousValue": 40000, "newValue": 62000, "metadata": { "viewerChange": 22000, "viewerChangePercent": 55, "classification": "spike" } }
```

#### 3) Category intelligence (named dataset `category-intelligence`)

```json
{ "category": "Just Chatting", "liveChannelCount": 12, "totalObservedViewers": 184300, "averageObservedViewers": 15358, "medianObservedViewers": 9200, "topChannels": [{ "channelName": "eliasn97", "viewerCount": 25454, "title": "..." }], "observedAt": "2026-08-30T17:35:05.000Z" }
```

Additionally, a **run summary** is written to the key-value store record `OUTPUT`, and **streamer intelligence** (latest + trend per channel) to `STREAMER_INTELLIGENCE`.

### Scheduling & historical data

Schedule the Actor (e.g. every 5–15 minutes). Each run appends observations you can combine into a historical dataset. To detect changes *across* runs, pass the previous run's dataset ID as `previousDatasetId` — the Actor uses each channel's most recent prior observation as the baseline for viewer changes and events.

### Reliability & error handling

- Batched GraphQL requests with **retries + exponential backoff** and rate-limit awareness.
- One unavailable/banned/renamed channel is skipped and logged — it never fails the run.
- Deterministic, consistently-typed output for easy downstream joins.

### Limitations

- Viewer/follower counts reflect **publicly visible values at observation time** — they are point-in-time samples, not Twitch's official historical analytics.
- Brand/sponsorship results are **detected mentions** from public text, not confirmed commercial relationships.
- Category discovery returns a sample of top live streams per category (`categoryStreamsPerGame`), not the entire category.

### Architecture

Modular by design — `twitch` (collection), `normalize`, `compare` (history/events), `analytics`, `state` (cross-run), and `main` (orchestration/output) — so future capabilities (Slack/Discord/email alerts, dashboards, creator ranking, historical DB, e-commerce product matching) drop in cleanly.

# Actor input Schema

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

Twitch channel usernames or URLs to monitor (e.g. "xqc" or "https://twitch.tv/xqc"). Provide one or many.

## `categories` (type: `array`):

Optional. Discover currently-live channels in these Twitch categories/games (e.g. "Just Chatting", "League of Legends"). Combined with any channels above.

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

Optional. Only keep streams in these languages (Twitch 2-letter codes, e.g. "EN", "DE", "ES").

## `liveOnly` (type: `boolean`):

If enabled, offline channels are skipped and only currently-live streams are recorded.

## `minimumViewers` (type: `integer`):

Only keep live streams with at least this many viewers. 0 = no minimum.

## `maximumViewers` (type: `integer`):

Only keep live streams with at most this many viewers. 0 = no maximum.

## `minimumStreamDurationSeconds` (type: `integer`):

Only keep live streams that have been live for at least this long. 0 = no minimum.

## `monitoringIntervalSeconds` (type: `integer`):

If greater than 0, the Actor re-checks the channels every N seconds within a single run to build a short observation series. Leave 0 for a single snapshot (recommended for scheduled runs).

## `maximumMonitoringDurationSeconds` (type: `integer`):

Upper bound on how long a monitoring run keeps polling (only used when a monitoring interval is set). 0 = single snapshot.

## `maximumChannels` (type: `integer`):

Safety cap on how many channels are processed per cycle (after category discovery). 0 = no cap.

## `categoryStreamsPerGame` (type: `integer`):

How many currently-live streams to pull from each category/game in the discovery step.

## `enableAnalysis` (type: `boolean`):

Compute growth metrics, category intelligence, streamer intelligence, and brand/sponsorship signals. Disable for a leaner raw snapshot.

## `previousDatasetId` (type: `string`):

Optional. The dataset ID of a previous run of this Actor. Its most recent observation per channel is used as the baseline so viewer changes and stream events are detected across scheduled runs.

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

Proxy used for requests to Twitch's public API. Apify Proxy (datacenter) is recommended.

## Actor input object example

```json
{
  "channels": [
    "xqc",
    "eliasn97"
  ],
  "categories": [
    "Just Chatting"
  ],
  "languages": [
    "EN"
  ],
  "liveOnly": false,
  "minimumViewers": 0,
  "maximumViewers": 0,
  "minimumStreamDurationSeconds": 0,
  "monitoringIntervalSeconds": 0,
  "maximumMonitoringDurationSeconds": 0,
  "maximumChannels": 0,
  "categoryStreamsPerGame": 30,
  "enableAnalysis": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `channelObservations` (type: `string`):

One normalized record per channel per observation cycle. Stream events and category intelligence are written to the named datasets 'events' and 'category-intelligence'; the run summary is in the key-value store record OUTPUT.

# 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": [
        "xqc",
        "https://www.twitch.tv/pokimane"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("tuhin/twitch-live-stream-intelligence").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": [
        "xqc",
        "https://www.twitch.tv/pokimane",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("tuhin/twitch-live-stream-intelligence").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": [
    "xqc",
    "https://www.twitch.tv/pokimane"
  ]
}' |
apify call tuhin/twitch-live-stream-intelligence --silent --output-dataset

```

## MCP server setup

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

```

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/UtsGOUeHDxk0wtvW2/builds/yjvranDRC6WKF1cLU/openapi.json
