# YouTube Related Videos Scraper (`scrapemamba/youtube-related-videos-scraper`) Actor

Get YouTube related videos and recommendation neighbors for seed watch URLs or IDs. Export adjacency maps (sourceVideoId → related IDs) for discovery pipelines. Metadata only — not a downloader.

- **URL**: https://apify.com/scrapemamba/youtube-related-videos-scraper.md
- **Developed by:** [Scrape Mamba](https://apify.com/scrapemamba) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$2.30 / 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

## YouTube Related Videos Scraper

**YouTube Related Videos Scraper** is the Actor to get **YouTube related videos** as structured graph edges — recommendation neighbors you can schedule, join, and analyze. Built by **ScrapeMamba**, this **apify youtube scraper** (a practical **youtube scraper** for adjacency maps) calls ScrapeMamba’s `POST /youtube/video_recommendations` endpoint so teams that need to **scrape YouTube** related rails get Dataset rows instead of brittle browser scrapes. Use it when you already have video IDs and want recommendation-graph data — not a video downloader or an essay on the **YouTube recommendation algorithm**.

Actor URL: <https://apify.com/scrapemamba/youtube-related-videos-scraper>

Pricing on Apify: **$2.30 per 1,000 results** (billed for successful Dataset rows).

Feed it IDs from Search, Channel Videos, Video Scraper, or your CRM. Chain carefully: recommendation fan-out grows quickly without deduplication.

***

### Overview

YouTube’s related / recommended rail changes over time, varies by context, and is not a keyword SERP. Product and research teams still need that adjacency graph: which creators co-occur, which topics cluster around a hero upload, and how “people also watch” neighborhoods drift.

Searches for the **YouTube recommendation algorithm** usually want either (a) an ML ranking explanation, or (b) a way to **export related/recommendation graph data**. This Actor answers **(b)**. It does not reverse-engineer ranking models, personalization weights, or feed experiments. It fetches the public recommendations listing for each seed and writes warehouse-friendly rows.

**Behavioral facts:** endpoint **`/youtube/video_recommendations`**; **single-page** fetch per seed (continuation short-circuits — no infinite related rail). Cap with `maxResults` (default **`"40"`**).

Under the hood:

1. `videoIds` is validated as a non-empty string list (URLs or bare IDs).
2. IDs are normalized and **deduped**.
3. Up to **8 workers** process seeds concurrently.
4. Each seed calls `POST /youtube/video_recommendations` with `{ video_id }`.
5. Rows whose `videoId` equals the **seed** are filtered out.
6. Success rows are **`type: "related"`** with **`sourceVideoId`**, **`page`**, mapped fields, and **`raw`**.
7. Per-seed failures become `type: "error"` with `videoId` and `error`.

**Integrator note:** related hits are **`type: "related"`**, not `"video"`. Filters that expect `"video"` will miss them. Keep **`sourceVideoId`** — that pair is your directed edge for recommendation-graph analysis.

***

### Recommendation graph data (not algorithm reverse-engineering)

What most teams need is an edge list:

- **From:** `sourceVideoId` (seed)
- **To:** `videoId` (related / recommended neighbor)
- **When:** run timestamp / Dataset run ID (recommendations are ephemeral)

That is what this **youtube data scraper** produces. Build adjacency maps, co-recommendation tables, competitor “people also watch” scans, and scheduled drift diffs — without pretending the Actor explains YouTube’s ML. If your research brief says “understand the recommendation algorithm,” translate that into an engineering brief: *export the public related graph for these seeds, store edges with timestamps, and measure membership change.* That is the problem this Actor solves.

Treat every Dataset as a **snapshot** of the public related rail at request time. Logged-in browser results, A/B experiment arms, and session personalization can differ from the API snapshot. For product work, that is usually fine: you care about stable join keys (`sourceVideoId`, `videoId`) and repeatable schedules more than pixel-perfect parity with one logged-in homepage.

When you recurse (related-of-related), store a global seen-set. Recommendation neighborhoods overlap heavily inside a niche; without dedupe you pay repeatedly for the same `videoId` and inflate graphs with duplicate nodes.

***

### Who this is for

- Analysts building related-video / recommendation **graphs** from known seeds
- Competitive researchers scanning associations around a hero upload
- Pipelines expanding Search or Channel Videos hits one hop outward
- Teams already running ScrapeMamba **youtube scraping** Actors on Apify

### Who this is not for

- Anyone seeking a **YouTube video downloader** — this extracts **related listing metadata**, not media files
- Keyword discovery without seed IDs (use **YouTube Search Scraper**)
- Deep multi-page recommendation shelf crawls (single page per seed)
- Readers who want an internal tutorial on how recommendation ranking works

***

### What it does

- Accepts watch URLs, Shorts-style links (when normalizable), or bare 11-character IDs
- Deduplicates seeds before fetching
- Returns related / recommended listings per seed
- Caps neighbors with `maxResults` (default 40)
- Tags every success row with **`sourceVideoId`** and **`type: "related"`**
- Excludes the seed’s own ID from neighbors
- Parallelizes up to **8** seeds
- Records per-seed errors without aborting the batch

***

### Use cases

**Topic clustering and adjacency maps** — Directed edges `sourceVideoId` → `videoId`. Cluster titles and channels; re-run on a schedule to watch drift. Export CSV edge lists into NetworkX, Neo4j, or a simple warehouse SQL graph table.

**“People also watch” competitive scans** — From a competitor hero upload, pull related IDs. Enrich neighbors with Video Scraper; captions with Subtitles when needed. Rank neighbors by how often they co-appear across your seed set.

**Expansion after Search or Channel Videos** — Expand strong seeds without inventing keywords. Prefer one hop unless you have hard dedupe and budget caps. A common pattern: take the top 5 Search hits, run Related once, then enrich only the union.

**Seed lists for enrichment** — Collect neighbor IDs, dedupe globally, then batch Video Scraper / Subtitles. Often cheaper than guessing more search queries when you already know a strong canonical video.

**Research sampling** — Snapshot fixed seed neighborhoods on a cadence; compare week-over-week membership. These are **snapshots**, not permanent ground truth — recommendations change, and that change is often the signal.

**Why ScrapeMamba on Apify** — Recommendation rails are awkward to babysit with DIY browsers. This Actor gives you Apify Input/Dataset/schedules, a shared suite join key (`videoId`), and a clear schema (`type: "related"` + `sourceVideoId`) so **youtube scraping** pipelines stay composable.

***

### What data can it extract?

| Field | Description |
|-------|-------------|
| `type` | **`"related"`** on success; `"error"` on failure |
| `sourceVideoId` | Seed that requested recommendations |
| `page` | Page index (single page in practice) |
| `videoId` | Related video’s 11-character ID |
| `title` / `author` / `channelId` | When present on the listing |
| `views` / `length` / `publishedTime` | When available |
| `description` / `text` | Short text when present |
| `thumbnail` / `url` | Preview and watch URL |
| `raw` | Original mapped item payload |
| `error` | On `type: "error"` rows (keyed with seed `videoId`) |

Join/dedupe on `videoId`; use `sourceVideoId` for graph edges.

***

### Input

| Field | Type | Required | Default | Description |
|-------|------|----------|---------|-------------|
| `videoIds` | `string[]` | **Yes** | — | Watch URLs or 11-character IDs |
| `maxResults` | `string` / number | No | `"40"` | Max related videos **per seed** (clamped 1–500) |

Prefill example: `https://www.youtube.com/watch?v=dQw4w9WgXcQ` with `maxResults` `"40"`.

```json
{
  "videoIds": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  ],
  "maxResults": "40"
}
```

**Tips:** URLs and bare IDs mix fine. Duplicate seeds collapse before workers run. `maxResults` is per seed. Smoke-test one public seed with `10`–`20`.

***

### Output

Consume success rows as **`type: "related"`** + **`sourceVideoId`** + mapped fields + `raw`. Do **not** expect `type: "video"`.

#### Success example

```json
{
  "type": "related",
  "sourceVideoId": "dQw4w9WgXcQ",
  "page": 1,
  "videoId": "relatedId123",
  "title": "Related Example Title",
  "author": "Another Channel",
  "channelId": "UCyyyyyyyyyyyyyyyyyyyyyy",
  "views": 120000,
  "thumbnail": "https://i.ytimg.com/vi/relatedId123/hqdefault.jpg",
  "url": "https://www.youtube.com/watch?v=relatedId123",
  "raw": { }
}
```

#### Error example

```json
{
  "type": "error",
  "videoId": "dQw4w9WgXcQ",
  "error": "HTTP 500: Upstream request failed after retries"
}
```

The seed’s own ID is filtered out of success rows even if the listing includes it. Zero valid IDs after normalize → `No valid video IDs found.` and exit code `1`.

***

### How to run on Apify Console

1. Open **[YouTube Related Videos Scraper](https://apify.com/scrapemamba/youtube-related-videos-scraper)**.
2. Paste `videoIds`; set `maxResults` (default `"40"`).
3. Start; confirm Dataset rows show **`type: "related"`** and **`sourceVideoId`**.
4. Export or pull via Dataset API; **dedupe** before recursive fan-out.
5. Save as a task + schedule, or call via Apify API.

**Checklist:** one public seed → confirm `type` / neighbors → dedupe before scaling.

***

### Apify API example

```bash
curl "https://api.apify.com/v2/acts/scrapemamba~youtube-related-videos-scraper/runs" \
  -H "Content-Type: application/json" \
  -d '{
    "videoIds": [
      "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
    ],
    "maxResults": "40"
  }'
```

```bash
curl "https://api.apify.com/v2/actor-runs/RUN_ID/dataset/items"
```

Client SDKs (JS/Python) use the same Input.

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

const client = new ApifyClient();
const run = await client.actor('scrapemamba/youtube-related-videos-scraper').call({
  videoIds: ['https://www.youtube.com/watch?v=dQw4w9WgXcQ'],
  maxResults: '40',
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.filter((row) => row.type === 'related').length);
```

***

### Pricing

- **$2.30 per 1,000 results** on this listing
- ScrapeMamba usage is separate from Apify compute

**Fan-out warning:** Re-seeding every related ID without caps grows cost multiplicatively. Prefer low `maxResults`, single-hop expansion, and global dedupe.

***

### Errors and status handling

Retries on **429 / 500 / 502 / 503 / 504** (3 attempts, 2s / 5s / 10s); **60s** timeout.

| Situation | Behavior |
|-----------|----------|
| Empty / invalid `videoIds` | Exit code `1` |
| No valid IDs after normalize | Exit code `1` |
| Per-seed API failure | `type: "error"`; other seeds continue |
| Related item equals seed / lacks `videoId` | Filtered out |

***

### Best practices

1. Validate with low `maxResults` first — confirm schema before raising caps.
2. Dedupe ruthlessly across seeds and recursive hops; keep a seen-`videoId` set.
3. Avoid blind recursion — one hop is enough for many products; multi-hop needs budgets and stop rules.
4. Treat recommendations as ephemeral; re-fetch when freshness matters.
5. Filter on **`type: "related"`**, not `"video"`. Downstream Video Scraper filters will miss these rows.
6. Always keep **`sourceVideoId`** for edge lists and debugging which seed produced a neighbor.
7. Public seeds only — private or unavailable videos error or yield empty neighborhoods.
8. Chain deliberately: Related → Video Scraper for metadata; Related → Subtitles for text; Search for keyword seeds upstream.
9. Schedule weekly snapshots for drift analysis rather than constant live crawling.

***

### Limitations

- **Single page** of recommendations per seed
- Sets **change over time** and may differ from a logged-in browser
- Seed ID excluded from outputs by design
- Public data only
- Fan-out can explode Dataset size without controls
- **Not a media downloader** — metadata / listing fields only

***

### Troubleshooting

| Symptom | What to try |
|---------|-------------|
| No valid video IDs | Watch URLs or 11-char IDs — not channel URLs or search phrases |
| Empty for a browser-working seed | Restricted/removed video or unmappable payload; try another public seed |
| Expected `type: "video"` | This Actor emits **`type: "related"`**; keep **`sourceVideoId`** |
| Huge Dataset | Too many seeds / high caps / recursive re-seed — lower and dedupe |
| Overlapping neighbors | Normal — unique-set for catalogs; multi-edges for co-rec frequency |
| Need keywords / captions | Search Scraper upstream; Subtitles Scraper after dedupe |

***

### FAQ

#### Does this explain the YouTube recommendation algorithm?

No. It **exports related / recommendation graph data** (`sourceVideoId` → `videoId`) from the public recommendations surface. It does not document ranking ML or personalization.

#### What Output type do success rows use?

**`"related"`**, with **`sourceVideoId`**, `page`, mapped fields, and `raw`. Not `"video"`.

#### Is this a YouTube video downloader?

No. Like the rest of the suite, this **youtube scraper** returns **metadata and listing text**, not video or audio files.

#### Endpoint, pagination, and defaults?

`POST /youtube/video_recommendations` with `{ "video_id": "<seedId>" }`. **Single-page** only. Default `maxResults` is `"40"` (clamped 1–500). `videoIds` required. Up to **8** workers. Seed itself is never returned as a related row.

#### Why do recommendations differ from my browser?

Personalization, time, region, and experiments differ. Treat output as an API snapshot for the seed ID.

#### How do I stop cost explosions?

Low `maxResults`, limit recursion depth, **dedupe** before re-seeding.

#### How do I enrich / start from keywords / get subtitles?

Enrich with **[YouTube Video Scraper](https://apify.com/scrapemamba/youtube-video-scraper)**. Keywords first via **[YouTube Search Scraper](https://apify.com/scrapemamba/youtube-search-scraper)**. Captions via **[YouTube Subtitles Scraper](https://apify.com/scrapemamba/youtube-subtitles-scraper)** on deduped IDs.

#### How do I scrape YouTube related videos on Apify?

Pass `videoIds`, start the run, confirm `type: "related"` + `sourceVideoId`, then export or pull via Apify API / Client (JS or Python).

#### How is this different from Search?

Search is keyword-driven discovery (`queries` → listing hits). Related Videos expands from **known IDs** into recommendation neighbors. Many pipelines use both: Search for seeds, Related for one-hop graph expansion.

#### Can I use this as a best youtube scraper step for niche mapping?

As part of the suite, yes — especially when your niche is defined by a few hero videos. Related neighborhoods often surface creators you would not find with a single keyword. Combine with Video Scraper enrichment and optional Subtitles for a fuller map.

***

### Pipeline patterns

**Search → Related → Enrich:** Search → pick top IDs → Related (`maxResults` modest) → global dedupe → Video Scraper (+ optional Subtitles).

**Hero neighborhood:** One canonical seed → Related once → score neighbors (views, channel overlap, title keywords) → enrich only the top N.

**Scheduled graph drift:** Fixed seed task → daily/weekly schedule → store edges `(sourceVideoId, videoId, runDate)` → diff membership over time to see which neighbors stick.

***

### Export and automation

Console Dataset download (JSON / CSV / Excel), Apify Dataset API, tasks + **schedules**, **webhooks** for enrichment, warehouse loads keyed by `sourceVideoId` + `videoId` + run timestamp.

***

### Related ScrapeMamba Actors

| Actor | Best for |
|-------|----------|
| [YouTube Video Scraper](https://apify.com/scrapemamba/youtube-video-scraper) | Enrich related IDs |
| [YouTube Search Scraper](https://apify.com/scrapemamba/youtube-search-scraper) | Keyword seeds upstream |
| [YouTube Subtitles Scraper](https://apify.com/scrapemamba/youtube-subtitles-scraper) | Captions on neighbors |

Channel, Channel Videos, Channel Shorts, and Trending help when seeds come from uploads or charts.

***

### Compliance note

Use only on **public** YouTube recommendation listings, per YouTube’s terms, applicable law, and your policies. Do not access private videos. You are responsible for how related-video data is stored and used.

# Actor input Schema

## `videoIds` (type: `array`):

YouTube video URLs or 11-character video IDs.

## `maxResults` (type: `string`):

Maximum number of results to return.

## Actor input object example

```json
{
  "videoIds": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  ],
  "maxResults": "40"
}
```

# Actor output Schema

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

Default dataset items produced by this Actor.

# 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 = {
    "videoIds": [
        "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
    ],
    "maxResults": "40"
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapemamba/youtube-related-videos-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 = {
    "videoIds": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"],
    "maxResults": "40",
}

# Run the Actor and wait for it to finish
run = client.actor("scrapemamba/youtube-related-videos-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 '{
  "videoIds": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  ],
  "maxResults": "40"
}' |
apify call scrapemamba/youtube-related-videos-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapemamba/youtube-related-videos-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/EEyLPfgusbqtGOGrC/builds/Xd1MI0qbJ6L6LJJsU/openapi.json
