# Twitch VOD & Clip Metadata Extractor (`datascraperes/twitch-video-metadata`) Actor

Extract public Twitch VOD and clip metadata from URLs or numeric VOD IDs: titles, creators, dates, durations, views, thumbnails, chapters, and availability. Metadata only—no video or audio downloads, channel discovery, or media files.

- **URL**: https://apify.com/datascraperes/twitch-video-metadata.md
- **Developed by:** [DataScraperES](https://apify.com/datascraperes) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.75 / 1,000 twitch metadata results

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

### What this Actor does

Extract public metadata from specific Twitch VOD and clip URLs without downloading video or audio. The Actor writes one Dataset row per processed normalized input; duplicate canonical targets are removed by default. Transport data such as media formats, manifests, CDN URLs, temporary headers, and tokens stays out of the output.

It accepts public VOD URLs, public clip URLs, and numeric VOD IDs. It is designed for enriching known Twitch items; it does not discover a channel's catalogue or monitor live channels.

### Use cases

- Enrich a list of Twitch VOD or clip URLs with titles, creators, dates, duration, views, and availability.
- Build a clean metadata catalogue before sending selected items to another workflow.
- Resolve VOD IDs and clip slugs in bulk while keeping the Dataset metadata-only.

### How to use

1. Open the Actor in Apify Console.
2. Add one or more public Twitch VOD/clip URLs or numeric VOD IDs to `inputList`.
3. Choose `maxItems` and whether equivalent inputs should be deduplicated.
4. Start the run and open the default Dataset for item rows. The default key-value store contains a `SUMMARY` record.

Example input:

```json
{
  "inputList": [
    "https://clips.twitch.tv/FaintLightGullWholeWheat",
    "https://www.twitch.tv/videos/1536751224"
  ],
  "maxItems": 2,
  "deduplicate": true
}
```

### Input

| Field | Type | Required | Default | Description |
|---|---|---:|---:|---|
| `inputList` | `string[]` | Yes | — | One to 100 public Twitch VOD URLs, clip URLs, or numeric VOD IDs. |
| `maxItems` | integer | No | `25` | Maximum number of normalized inputs to process. `0` means all supplied inputs, up to 100. |
| `deduplicate` | boolean | No | `true` | Removes duplicate URLs and equivalent VOD ID/URL inputs before extraction. |

The Actor accepts individual VOD and clip targets such as `https://www.twitch.tv/videos/1536751224`, `https://clips.twitch.tv/FaintLightGullWholeWheat`, and the numeric VOD ID `1536751224`. Channel pages, channel video listings, search pages, category pages, and live-channel URLs are not valid inputs for this Actor.

### Output

The default Dataset contains one row per normalized input. Successful rows have `status: "success"` and `availability: "available"`. Unavailable or restricted targets produce a safe error row and the run finishes as failed so incomplete collections are not mistaken for complete ones. Successful rows already written remain available.

Fields such as descriptions, thumbnails, chapters, category names, follower counts, and live-state flags are nullable or empty when Twitch does not provide them for a target. A thumbnail is also `null` when Twitch returns only a temporary or signed URL. `channelLogin` contains the source-provided broadcaster login or name when available. `retrievedAt` is the UTC time of extraction. The Actor does not download or store media files.

This is a complete Dataset item from a successful run:

```json
{
  "status": "success",
  "recordType": "clip",
  "inputUrl": "https://clips.twitch.tv/FaintLightGullWholeWheat",
  "sourceUrl": "https://clips.twitch.tv/FaintLightGullWholeWheat",
  "id": "396245304",
  "displayId": "FaintLightGullWholeWheat",
  "title": "EA Play 2016 Live from the Novo Theatre",
  "description": null,
  "durationSeconds": 32,
  "createdAt": "2016-06-12T21:36:33Z",
  "publishedAt": null,
  "viewCount": 30294,
  "liveStatus": null,
  "wasLive": null,
  "isLive": null,
  "channelName": "EA",
  "channelLogin": "EA",
  "channelId": "25163635",
  "channelFollowerCount": 443065,
  "channelIsVerified": false,
  "creatorName": "stereotype_",
  "creatorId": "43566419",
  "uploaderName": null,
  "uploaderId": null,
  "categories": [],
  "chapters": [],
  "thumbnailUrl": null,
  "availability": "available",
  "retrievedAt": "2026-09-23T18:26:30Z",
  "errorCode": null,
  "errorMessage": null
}
```

VOD rows use `recordType: "vod"`, a numeric VOD `id`, uploader fields, publication metadata, and any chapters exposed by Twitch. Clip rows can additionally include the clip creator and broadcaster fields. The run summary is available at the default key-value store record `SUMMARY`.

### Pricing

This Actor uses Apify pay-per-event pricing. One successfully delivered metadata row is one `twitch-metadata-result` event; unavailable or restricted inputs are not charged for this custom result event.

| Apify tier | Price per result | Equivalent per 1,000 results |
|---|---:|---:|
| FREE | $0.001 | $1.00 |
| BRONZE | $0.0009 | $0.90 |
| SILVER | $0.0008 | $0.80 |
| GOLD | $0.00075 | $0.75 |
| PLATINUM | $0.00075 | $0.75 |
| DIAMOND | $0.00075 | $0.75 |

Apify resolves the active customer tier server-side. The Pricing tab remains the source of truth for the current configuration and any platform usage or storage charges.

### Related Actors

| Actor | Best for |
|---|---|
| [Social Blade Multi-Platform Analytics Scraper](https://apify.com/datascraperes/socialblade-scraper) | Public creator analytics across Twitch and other supported social platforms. |
| [YouTube Channel Videos Scraper | Shorts & Streams](https://apify.com/datascraperes/youtube-channel-scraper) | Building a comparable public video catalogue for YouTube channels. |

### Limits and data quality

The input accepts at most 100 strings and the default run limit is 25 normalized targets. Twitch availability, titles, counts, categories, chapters, and thumbnails can change or be absent for deleted, private, restricted, expired, or otherwise inaccessible content. A successful row describes metadata observed during that run; it does not guarantee that the media or thumbnail remains available later.

The underlying public Twitch extraction surface can change. The Actor does not promise permanent historical coverage, exact counts, or fields that the source does not return. It may make requests needed to resolve metadata, but it does not call a media download operation and does not publish media transport URLs.

### Frequently asked questions

#### Does this Actor download videos or clips?

No. It resolves metadata only and publishes an explicit metadata field list. Media files are not written to the Dataset or Actor storage.

#### Can I give it a Twitch channel URL?

No. This Actor handles known VOD and clip targets. Collect the individual public item URLs first, then pass the selected URLs here for detailed metadata.

#### What happens when one input is unavailable?

The Actor writes a sanitized error row for that input, preserves successful rows, writes the run summary, and fails the run so downstream automation can detect incomplete collection.

#### Why is a field null or an array empty?

The source did not expose that field for the target during the run. The Actor returns null or an empty array rather than inventing values or fetching unrelated content.

#### Can I use a numeric VOD ID?

Yes. Numeric VOD IDs are normalized to Twitch VOD URLs before extraction. Duplicate ID/URL representations are collapsed when `deduplicate` is enabled.

### Responsible use

Use only public Twitch content you are entitled to process. You are responsible for complying with Twitch's terms, applicable copyright and privacy requirements, and local law. Public visibility does not grant permission to republish media or personal information.

### Support

For an unexpected result, open an issue in the Actor's **Issues** tab with the run ID, a small public input, and the returned `errorCode`. Do not include credentials, cookies, private URLs, or temporary media URLs.

# Actor input Schema

## `inputList` (type: `array`):

Enter public Twitch VOD URLs, clip URLs, or numeric VOD IDs. Duplicate canonical targets are removed by default.

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

Limit the number of unique inputs processed. Use 0 to process every supplied input after normalization.

## `deduplicate` (type: `boolean`):

Collapse repeated URLs and equivalent VOD ID/URL inputs before extraction.

## Actor input object example

```json
{
  "inputList": [
    "https://clips.twitch.tv/FaintLightGullWholeWheat"
  ],
  "maxItems": 1,
  "deduplicate": true
}
```

# Actor output Schema

## `results` (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 = {
    "inputList": [
        "https://clips.twitch.tv/FaintLightGullWholeWheat"
    ],
    "maxItems": 1,
    "deduplicate": true
};

// Run the Actor and wait for it to finish
const run = await client.actor("datascraperes/twitch-video-metadata").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 = {
    "inputList": ["https://clips.twitch.tv/FaintLightGullWholeWheat"],
    "maxItems": 1,
    "deduplicate": True,
}

# Run the Actor and wait for it to finish
run = client.actor("datascraperes/twitch-video-metadata").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 '{
  "inputList": [
    "https://clips.twitch.tv/FaintLightGullWholeWheat"
  ],
  "maxItems": 1,
  "deduplicate": true
}' |
apify call datascraperes/twitch-video-metadata --silent --output-dataset

```

## MCP server setup

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

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/yTQxsfdwZZiLfXwDe/builds/1MwapzM3cXp9haR1K/openapi.json
