# Twitch Streamer Finder by Game - Emails, Socials, New Only (`neverempty/twitch-streamer-finder`) Actor

Find the Twitch streamers live in any game right now, with follower and viewer counts, stream title, language, social links and the business email each streamer published in the channel bio or panels. Filter by followers, viewers, language or email, and get only new streamers on each scheduled run.

- **URL**: https://apify.com/neverempty/twitch-streamer-finder.md
- **Developed by:** [NeverEmpty](https://apify.com/neverempty) (community)
- **Categories:** Social media, Lead generation, Marketing
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.50 / 1,000 streamer returneds

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 Streamer Finder by Game - Emails, Socials, New Only

Find the Twitch streamers who are live in any game or category right now, with follower count, current viewers, stream title, language, bio, social links and the **business email the streamer published** in the channel bio or panels. Filter by followers, viewers, language or "has an email", and put it on a schedule with monitoring on to receive **only streamers you have not received before**.

You pay per streamer row returned. Games that do not exist, games nobody is streaming, filters that match nobody and limits that cut the run short come back as free rows that say why.

### Best for

- **Influencer outreach for a game launch or sponsorship** - list the streamers live in your game, or in the games your players play, with the contact address each one published for business.
- **Finding small and mid-size creators** - set `maxFollowers` and `minViewers` to skip the giants and find channels that answer emails and fit a smaller budget.
- **A daily feed of new streamers** - with `monitoringMode` on a daily schedule, each run returns only streamers who were not in an earlier run, so the list grows without repeats.
- **Market lists by language** - the streamers live in a game in Spanish, Japanese, German or any other language.

### What each row contains

- **Who** - `login`, `displayName`, `url`, `userId`, `profileImageUrl`, `isPartner`, `isAffiliate`, `bio`.
- **Size** - `followerCount`, and `viewerCount` at the moment of the run.
- **The stream** - `game`, `gameSlug`, `inputGame` (what you typed), `streamTitle`, `language`, `streamStartedAt`, `liveForMinutes`, `streamId`.
- **Contact** - `email` (the first business email found), `emailOwner`, `emails` (all of them), and `emailDetails` with where each address was found (`bio` or `panel`) and who it seems to belong to.
- **Social links** - `xUrl`, `instagramUrl`, `youtubeUrl`, `tiktokUrl`, `discordUrl`, and all profile links found (also Facebook and LinkedIn) in `socialLinks`.

Measured on 2026-10-19: of the 96 most-watched streamers live in VALORANT, 46 had published an email address in their bio or panels.

#### Emails: only what the streamer published

The email comes **only from text the streamer published on the channel page**: the bio and the text of the channel panels. Addresses written in a common disguised form, such as `name [at] domain [dot] com`, are turned back into a normal address. Nothing is guessed and nothing is looked up elsewhere. An address that appears only inside a panel **image** is not read, so a streamer can have a contact address that this Actor does not return.

`emailOwner` says whose address it seems to be, as far as the text shows:

| `emailOwner` | Meaning |
|---|---|
| `streamer` | The address contains the channel name, so it is most likely the streamer's own. |
| `agency` | The address follows words such as management, agency or booking, or it is on a company domain that does not contain the channel name. It may belong to a talent agency, a team or a company the streamer works with. |
| `unknown` | A free email address (Gmail, Outlook and similar) without the channel name. It may be the streamer's, a manager's or a team's. |

This is a reading of the text, not a confirmation from the streamer. Check before you write.

### Monitoring: only new streamers

Turn on `monitoringMode` and the Actor remembers every streamer it returned **and charged for**. Later runs skip them and return only streamers not returned before. A game where everyone matching was already returned gives one free `no-new-since-last-run` row.

- A streamer who was found but not returned, for example because the run reached its maximum total charge, is **not remembered**, so they still count as new next time.
- The memory is shared by all your runs of this Actor, across all games. `resetMonitoringState` clears it.
- Two monitoring runs that start at the same time do not both charge you for the same streamer: before returning anything, each run marks the streamers it is about to return, waits briefly, and leaves out anyone another run marked first. This works on runs that overlap by more than a couple of seconds; the storage it uses has no atomic update, so it cannot be fully watertight for runs that write at exactly the same instant.
- The 100,000 most recently returned streamers are remembered.

### Rows that are never charged

When there is nothing to return, the run says why instead of returning an empty result:

- `no-such-game` - Twitch has no game or category with that name or slug. The row lists Twitch's closest matches.
- `no-live-streams` - nobody is streaming that game on Twitch right now.
- `no-match` - streamers are live, but none matches your filters. The row says how many each filter left out.
- `no-new-since-last-run` - monitoring is on, and every matching streamer was already returned by an earlier run, or is being returned by another monitoring run that started at the same time.
- `blocked` - Twitch answered with a rate limit, a bot check or an empty answer three times in a row. The game is not reported as empty.
- `unreadable` - Twitch sent an error or an answer that could not be read. Its message is included.
- `invalid-input` - the text is not a game name, slug or category URL, or a filter value is not valid. Nothing was requested.
- `max-records-reached` - `maxRecords` was reached, or more than 50 games were given. The row says which game was not searched to the end and which games were not searched.
- `request-limit-reached` - `maxRequests` was used up. The row says which games were not searched to the end.
- `budget-reached` - the run's maximum total charge was reached. The row says how many streamers fit and which games were not searched.

### Input

| Field | What it does |
|---|---|
| `games` | Games or categories, one per line: the name (`VALORANT`), the slug (`grand-theft-auto-v`) or the category URL. Up to 50 per run. Empty = the example game VALORANT. |
| `maxStreamersPerGame` | Streamers to return per game (1 to 1,000, default 100). |
| `maxRecords` | Charged rows per run in total (default 1,000). |
| `maxRequests` | Safety limit on pages read (default 60). |
| `minFollowers`, `maxFollowers` | Follower range. |
| `minViewers`, `maxViewers` | Current viewer range. |
| `languages` | Two-letter stream language codes, for example `en`, `es`, `ja`. |
| `onlyWithEmail` | Return only streamers with a published email. Streamers without one are not charged. |
| `monitoringMode` | Return only streamers not returned before. |
| `resetMonitoringState` | Forget the remembered streamers. |

Example: the English-speaking VALORANT streamers with 1,000 to 50,000 followers who published an email.

```json
{
    "games": ["VALORANT"],
    "minFollowers": 1000,
    "maxFollowers": 50000,
    "languages": ["en"],
    "onlyWithEmail": true
}
```

Rows come sorted by current viewers within each game, and each streamer appears once per run even if you list two games they could match.

### Good to know

- **About 1,000 streamers per game at most.** Twitch shows visitors only part of the streams in a very large game. The Actor reads as much of each game as Twitch shows and returns up to 1,000 streamers per game. For a game with a few hundred people live, it reaches everyone. For the largest games, some streamers who are live are not reached in a given run; a monitoring schedule picks more of them up over time, as different people go live.
- **Live right now only.** Streamers who are offline at the moment of the run are not found.
- **The language filter uses the language each stream is set to**, as the streamer chose it.
- **Social links come from the bio and the channel panels** (including where a panel links to). Links shown only as buttons on the About page are not read.
- **Follower and viewer counts are the numbers at the moment of the run.**
- The Actor reads public channel pages only, without logging in, with a 1-second pause between requests and a short wait before trying again when Twitch asks it to slow down. Twitch can change its pages without notice; if that happens, runs return `unreadable` or `blocked` rows instead of wrong data, and we fix the Actor.
- Use the emails for genuine business contact, and follow the anti-spam and privacy laws that apply to you.

### Thanks for using this Actor

We build these tools for people who run them every day, and we improve them from what users tell us.

- **Missing a field, or need another filter?** Tell us in the **Issues** tab. If the data is there, we add it.
- **Found a bug or a wrong value?** Post the run ID in the **Issues** tab. Wrong data is the thing we fix first.

If this Actor saved you time, a short review helps other people find it.

# Actor input Schema

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

The Twitch games or categories to search, one per line: the name as Twitch shows it (VALORANT, Grand Theft Auto V, Just Chatting), the slug (grand-theft-auto-v) or the category URL (https://www.twitch.tv/directory/category/valorant). Names are matched without regard to upper or lower case. A name Twitch does not know comes back as a free row with Twitch's closest matches. Up to 50 per run. If you leave this empty, the example game VALORANT is searched and every row says so in inputGame.

## `maxStreamersPerGame` (type: `integer`):

How many matching streamers to return for each game. Popular games have more than 1,000 people live at once; this Actor reaches about 1,000 of them per game (see Good to know in the README).

## `maxRecords` (type: `integer`):

The most charged rows this run returns across all games. When it is reached, a free row says which games were not searched to the end.

## `maxRequests` (type: `integer`):

A safety limit on how many pages are read in this run. Each page holds up to 100 live streams. Finding one game's streamers takes 1 to about 50 pages, depending on how many people stream it. When the limit is hit, a free row says what was not searched.

## `minFollowers` (type: `integer`):

Return only channels with at least this many followers. Leave empty for no lower limit.

## `maxFollowers` (type: `integer`):

Return only channels with at most this many followers, for example to find small and mid-size streamers. Leave empty for no upper limit.

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

Return only streams with at least this many viewers at the moment of the run.

## `maxViewers` (type: `integer`):

Return only streams with at most this many viewers at the moment of the run.

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

Two-letter language codes of the stream, for example en, es, ja. Leave empty for all languages.

## `onlyWithEmail` (type: `boolean`):

On = return only streamers who published an email address in their channel bio or panels. Streamers without one are read but not returned, so they cost nothing.

## `monitoringMode` (type: `boolean`):

On = the Actor remembers every streamer it returned and charged for, and later runs return only streamers it has not returned before. Put it on a schedule to receive new streamers in a game each day. Streamers who were found but not returned (for example because the run hit its maximum total charge) are not remembered, so they still count as new next time. The memory is shared by all your runs of this Actor.

## `resetMonitoringState` (type: `boolean`):

Clears the list of streamers already returned, so the next monitoring run returns everyone again. This affects all your monitoring runs of this Actor.

## Actor input object example

```json
{
  "games": [
    "VALORANT"
  ],
  "maxStreamersPerGame": 100,
  "maxRecords": 1000,
  "maxRequests": 60,
  "onlyWithEmail": false,
  "monitoringMode": false,
  "resetMonitoringState": false
}
```

# Actor output Schema

## `results` (type: `string`):

One row per Twitch streamer live in the games you asked for: login, display name, channel URL, follower count, current viewer count, stream title, language, start time, partner and affiliate flags, bio, the business email the streamer published in the bio or panels with whether it looks like the streamer's own or an agency's, and links to X, Instagram, YouTube, TikTok and Discord. Games Twitch does not know, games nobody is streaming, filters that match nobody and limits that cut the run short come back as their own free rows.

# 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 = {
    "games": [
        "VALORANT"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("neverempty/twitch-streamer-finder").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 = { "games": ["VALORANT"] }

# Run the Actor and wait for it to finish
run = client.actor("neverempty/twitch-streamer-finder").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 '{
  "games": [
    "VALORANT"
  ]
}' |
apify call neverempty/twitch-streamer-finder --silent --output-dataset

```

## MCP server setup

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

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/Kv4vpGEbaAce4ck69/builds/ihGF6nxtl5gLK8epX/openapi.json
