# YouTube Transcript to PDF (`maximedupre/youtube-to-pdf`) Actor

Turn public YouTube videos with accessible captions into readable transcript PDFs. Get timed transcript passages, video details, and a PDF download link for each successful video.

- **URL**: https://apify.com/maximedupre/youtube-to-pdf.md
- **Developed by:** [Maxime Dupré](https://apify.com/maximedupre) (community)
- **Categories:** Videos, Education, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.35 / 1,000 transcript pdfs

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/platform/actors/running/actors-in-store#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

### 📄 Turn YouTube videos into readable PDFs

YouTube to PDF is for students, researchers, creators, and teams that need a video transcript they can read or share. Add public YouTube videos with captions to get a PDF and a structured dataset row for each successful video.

- Make a PDF with **[YouTube transcript to PDF](https://apify.com/maximedupre/youtube-to-pdf/examples/youtube-transcript-to-pdf)** for reading, study, or research.
- Use the **[YouTube video to PDF converter](https://apify.com/maximedupre/youtube-to-pdf/examples/youtube-video-to-pdf-converter)** to save a video transcript as a document.
- **[Extract text from YouTube video](https://apify.com/maximedupre/youtube-to-pdf/examples/extract-text-from-youtube-video)** and keep timed passages in JSON.
- Run the **[YouTube transcript generator](https://apify.com/maximedupre/youtube-to-pdf/examples/youtube-transcript-generator)** for a public video with captions.
- Get a **[YouTube transcript](https://apify.com/maximedupre/youtube-to-pdf/examples/youtube-transcript)** with video details and a PDF download link.

#### 📦 What you get

Each successful video creates one dataset row and one PDF in Apify storage. The row contains the full transcript as timed passages, the caption language used, video details when available, transcript size, and a PDF URL. If the same video appears more than once, the Actor saves its first result and skips later copies. One failed video does not stop the rest of the list.

The Actor uses accessible manual or auto-generated YouTube captions. It does not make new captions with speech-to-text, translate or summarize text, discover videos, or process private and login-only videos.

#### ▶️ Running the Actor

1. Add one or more public YouTube URLs or video IDs.
2. Choose a caption language and PDF layout.
3. Choose whether to remove non-speech notes.
4. Click **Start**.
5. Open **Video documents** for the dataset rows and PDF links.

You can submit standard watch URLs, `youtu.be` links, embed URLs, Shorts URLs, or bare video IDs. The Actor uses the best available caption track if the requested language is not available.

#### 📥 Input

| Field | Type | What it does |
| --- | --- | --- |
| `videoReferences` | string array | Adds one or more public YouTube video URLs or video IDs. Standard, short, embed, and Shorts URLs work. |
| `captionLanguage` | string | Sets a preferred caption language code, such as `en` or `es`. The best available track is used if it is not available. |
| `transcriptLayout` | string | Chooses clean paragraphs or a timestamp-focused PDF layout. |
| `removeAnnotations` | boolean | Removes non-speech caption notes such as music, applause, and laughter markers. |

This is the public input from the successful default-input beta run:

```json
{
  "videoReferences": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  ],
  "captionLanguage": "en",
  "transcriptLayout": "paragraphs",
  "removeAnnotations": false
}
```

#### 📤 Output

Each successful video has this shape:

| Field | Type | What it does |
| --- | --- | --- |
| `videoId` | string | YouTube video ID. |
| `videoUrl` | URL | Source YouTube video URL. |
| `title` | string | Video title. |
| `channelName` | string | Channel name, when available. |
| `description` | string | Video description, when available. |
| `durationSeconds` | number | Video length in seconds, when available. |
| `publishedAt` | date-time | Video publish time, when available. |
| `thumbnailUrl` | URL | Video thumbnail URL, when available. |
| `viewCount` | integer | View count, when available. |
| `likeCount` | integer | Like count, when available. |
| `commentCount` | integer | Comment count, when available. |
| `requestedCaptionLanguage` | string | Caption language code you requested. |
| `captionLanguage` | string | Caption language code that was used. |
| `captionsAutoGenerated` | boolean | Says whether YouTube made the captions automatically. |
| `transcriptCharacterCount` | integer | Number of characters in the cleaned transcript. |
| `transcriptWordCount` | integer | Number of words in the cleaned transcript. |
| `transcriptPassages` | object array | Full transcript split into timed passages. |
| `transcriptPassages.startSeconds` | number | Passage start time in seconds. |
| `transcriptPassages.durationSeconds` | number | Passage length in seconds, when available. |
| `transcriptPassages.text` | string | Caption text for the passage. |
| `pdfUrl` | URL | Apify storage URL for the PDF. |

This full row comes from the matching successful beta run:

```json
{
  "videoId": "dQw4w9WgXcQ",
  "videoUrl": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
  "title": "Rick Astley - Never Gonna Give You Up (Official Video) (4K Remaster)",
  "channelName": "Rick Astley",
  "description": "The official video for “Never Gonna Give You Up” by Rick Astley. \n\nNever: The Autobiography 📚 OUT NOW! \nFollow this link to get your copy and listen to Rick’s ‘Never’ playlist ❤️ #RickAstleyNever\nhttps://linktr.ee/rickastleynever\n\n“Never Gonna Give You Up” was a global smash on its release in July 1987, topping the charts in 25 countries including Rick’s native UK and the US Billboard Hot 100.  It also won the Brit Award for Best single in 1988. Stock Aitken and Waterman wrote and produced the track which was the lead-off single and lead track from Rick’s debut LP “Whenever You Need Somebody”.  The album was itself a UK number one and would go on to sell over 15 million copies worldwide.\n\nThe legendary video was directed by Simon West – who later went on to make Hollywood blockbusters such as Con Air, Lara Croft – Tomb Raider and The Expendables 2.  The video passed the 1bn YouTube views milestone on 28 July 2021.\n\nSubscribe to the official Rick Astley YouTube channel: https://RickAstley.lnk.to/YTSubID\n\nFollow Rick Astley:\nFacebook: https://RickAstley.lnk.to/FBFollowID \nTwitter: https://RickAstley.lnk.to/TwitterID \nInstagram: https://RickAstley.lnk.to/InstagramID \nWebsite: https://RickAstley.lnk.to/storeID \nTikTok: https://RickAstley.lnk.to/TikTokID\n\nListen to Rick Astley:\nSpotify: https://RickAstley.lnk.to/SpotifyID \nApple Music: https://RickAstley.lnk.to/AppleMusicID \nAmazon Music: https://RickAstley.lnk.to/AmazonMusicID \nDeezer: https://RickAstley.lnk.to/DeezerID \n\nLyrics:\nWe’re no strangers to love\nYou know the rules and so do I\nA full commitment’s what I’m thinking of\nYou wouldn’t get this from any other guy\n\nI just wanna tell you how I’m feeling\nGotta make you understand\n\nNever gonna give you up\nNever gonna let you down\nNever gonna run around and desert you\nNever gonna make you cry\nNever gonna say goodbye\nNever gonna tell a lie and hurt you\n\nWe’ve known each other for so long\nYour heart’s been aching but you’re too shy to say it\nInside we both know what’s been going on\nWe know the game and we’re gonna play it\n\nAnd if you ask me how I’m feeling\nDon’t tell me you’re too blind to see\n\nNever gonna give you up\nNever gonna let you down\nNever gonna run around and desert you\nNever gonna make you cry\nNever gonna say goodbye\nNever gonna tell a lie and hurt you\n\n#RickAstley #NeverGonnaGiveYouUp #WheneverYouNeedSomebody #OfficialMusicVideo",
  "durationSeconds": 213,
  "publishedAt": "2009-10-25T06:57:33.000Z",
  "thumbnailUrl": "https://i.ytimg.com/vi/dQw4w9WgXcQ/sddefault.jpg",
  "viewCount": 1798755225,
  "requestedCaptionLanguage": "en",
  "captionLanguage": "en",
  "captionsAutoGenerated": false,
  "transcriptPassages": [
    {
      "startSeconds": 1.36,
      "durationSeconds": 1.68,
      "text": "[♪♪♪]"
    },
    {
      "startSeconds": 18.64,
      "durationSeconds": 3.24,
      "text": "♪ We&#39;re no strangers to love ♪"
    },
    {
      "startSeconds": 22.64,
      "durationSeconds": 4.32,
      "text": "♪ You know the rules\nand so do I ♪"
    },
    {
      "startSeconds": 27.04,
      "durationSeconds": 4,
      "text": "♪ A full commitment&#39;s\nwhat I&#39;m thinking of ♪"
    },
    {
      "startSeconds": 31.12,
      "durationSeconds": 3.96,
      "text": "♪ You wouldn&#39;t get this\nfrom any other guy ♪"
    },
    {
      "startSeconds": 35.16,
      "durationSeconds": 4.36,
      "text": "♪ I just wanna tell you\nhow I&#39;m feeling ♪"
    },
    {
      "startSeconds": 40.52,
      "durationSeconds": 2.4,
      "text": "♪ Gotta make you understand ♪"
    },
    {
      "startSeconds": 43,
      "durationSeconds": 2.12,
      "text": "♪ Never gonna give you up ♪"
    },
    {
      "startSeconds": 45.2,
      "durationSeconds": 1.88,
      "text": "♪ Never gonna let you down ♪"
    },
    {
      "startSeconds": 47.32,
      "durationSeconds": 3.8,
      "text": "♪ Never gonna run around\nand desert you ♪"
    },
    {
      "startSeconds": 51.48,
      "durationSeconds": 2,
      "text": "♪ Never gonna make you cry ♪"
    },
    {
      "startSeconds": 53.6,
      "durationSeconds": 1.92,
      "text": "♪ Never gonna say goodbye ♪"
    },
    {
      "startSeconds": 55.72,
      "durationSeconds": 3.64,
      "text": "♪ Never gonna tell a lie\nand hurt you ♪"
    },
    {
      "startSeconds": 60.8,
      "durationSeconds": 4,
      "text": "♪ We&#39;ve known each other\nfor so long ♪"
    },
    {
      "startSeconds": 64.88,
      "durationSeconds": 4.16,
      "text": "♪ Your heart&#39;s been aching\nbut you&#39;re too shy to say it ♪"
    },
    {
      "startSeconds": 69.12,
      "durationSeconds": 3.84,
      "text": "♪ Inside we both know\nwhat&#39;s been going ♪"
    },
    {
      "startSeconds": 73.36,
      "durationSeconds": 3.84,
      "text": "♪ We know the game\nand we&#39;re gonna play it ♪"
    },
    {
      "startSeconds": 77.4,
      "durationSeconds": 4.64,
      "text": "♪ And if you ask me\nhow I&#39;m feeling ♪"
    },
    {
      "startSeconds": 82.4,
      "durationSeconds": 2.84,
      "text": "♪ Don&#39;t tell me\nyou&#39;re too blind to see ♪"
    },
    {
      "startSeconds": 85.32,
      "durationSeconds": 1.96,
      "text": "♪ Never gonna give you up ♪"
    },
    {
      "startSeconds": 87.36,
      "durationSeconds": 1.96,
      "text": "♪ Never gonna let you down ♪"
    },
    {
      "startSeconds": 89.44,
      "durationSeconds": 4.28,
      "text": "♪ Never gonna run around\nand desert you ♪"
    },
    {
      "startSeconds": 93.8,
      "durationSeconds": 1.8,
      "text": "♪ Never gonna make you cry ♪"
    },
    {
      "startSeconds": 95.76,
      "durationSeconds": 2.24,
      "text": "♪ Never gonna say goodbye ♪"
    },
    {
      "startSeconds": 98.08,
      "durationSeconds": 3.96,
      "text": "♪ Never gonna tell a lie\nand hurt you ♪"
    },
    {
      "startSeconds": 102.2,
      "durationSeconds": 1.92,
      "text": "♪ Never gonna give you up ♪"
    },
    {
      "startSeconds": 104.28,
      "durationSeconds": 2.08,
      "text": "♪ Never gonna let you down ♪"
    },
    {
      "startSeconds": 106.48,
      "durationSeconds": 3.6,
      "text": "♪ Never gonna run around\nand desert you ♪"
    },
    {
      "startSeconds": 110.76,
      "durationSeconds": 1.96,
      "text": "♪ Never gonna make you cry ♪"
    },
    {
      "startSeconds": 112.8,
      "durationSeconds": 1.88,
      "text": "♪ Never gonna say goodbye ♪"
    },
    {
      "startSeconds": 114.96,
      "durationSeconds": 3.8,
      "text": "♪ Never gonna tell a lie\nand hurt you ♪"
    },
    {
      "startSeconds": 119.84,
      "durationSeconds": 3.12,
      "text": "♪ (Ooh, give you up) ♪"
    },
    {
      "startSeconds": 123.72,
      "durationSeconds": 3.64,
      "text": "♪ (Ooh, give you up) ♪"
    },
    {
      "startSeconds": 128.48,
      "durationSeconds": 1.64,
      "text": "♪ Never gonna give,\nnever gonna give ♪"
    },
    {
      "startSeconds": 130.24,
      "durationSeconds": 1.32,
      "text": "♪ (Give you up) ♪"
    },
    {
      "startSeconds": 132.48,
      "durationSeconds": 1.76,
      "text": "♪ Never gonna give,\nnever gonna give ♪"
    },
    {
      "startSeconds": 134.36,
      "durationSeconds": 1.56,
      "text": "♪ (Give you up) ♪"
    },
    {
      "startSeconds": 136.76,
      "durationSeconds": 4.32,
      "text": "♪ We&#39;ve known each other\nfor so long ♪"
    },
    {
      "startSeconds": 141.2,
      "durationSeconds": 4,
      "text": "♪ Your heart&#39;s been aching\nbut you&#39;re too shy to say it ♪"
    },
    {
      "startSeconds": 145.28,
      "durationSeconds": 3.84,
      "text": "♪ Inside we both know\nwhat&#39;s been going ♪"
    },
    {
      "startSeconds": 149.52,
      "durationSeconds": 3.68,
      "text": "♪ We know the game\nand we&#39;re gonna play it ♪"
    },
    {
      "startSeconds": 153.36,
      "durationSeconds": 4.68,
      "text": "♪ I just wanna tell you\nhow I&#39;m feeling ♪"
    },
    {
      "startSeconds": 158.64,
      "durationSeconds": 2.68,
      "text": "♪ Gotta make you understand ♪"
    },
    {
      "startSeconds": 161.4,
      "durationSeconds": 1.96,
      "text": "♪ Never gonna give you up ♪"
    },
    {
      "startSeconds": 163.44,
      "durationSeconds": 2.2,
      "text": "♪ Never gonna let you down ♪"
    },
    {
      "startSeconds": 165.72,
      "durationSeconds": 4,
      "text": "♪ Never gonna run around\nand desert you ♪"
    },
    {
      "startSeconds": 169.8,
      "durationSeconds": 1.84,
      "text": "♪ Never gonna make you cry ♪"
    },
    {
      "startSeconds": 171.8,
      "durationSeconds": 2.16,
      "text": "♪ Never gonna say goodbye ♪"
    },
    {
      "startSeconds": 174.04,
      "durationSeconds": 3.56,
      "text": "♪ Never gonna tell a lie\nand hurt you ♪"
    },
    {
      "startSeconds": 178.2,
      "durationSeconds": 2.04,
      "text": "♪ Never gonna give you up ♪"
    },
    {
      "startSeconds": 180.32,
      "durationSeconds": 2.12,
      "text": "♪ Never gonna let you down ♪"
    },
    {
      "startSeconds": 182.52,
      "durationSeconds": 4.12,
      "text": "♪ Never gonna run around\nand desert you ♪"
    },
    {
      "startSeconds": 186.72,
      "durationSeconds": 2,
      "text": "♪ Never gonna make you cry ♪"
    },
    {
      "startSeconds": 188.84,
      "durationSeconds": 1.88,
      "text": "♪ Never gonna say goodbye ♪"
    },
    {
      "startSeconds": 190.84,
      "durationSeconds": 4.36,
      "text": "♪ Never gonna tell a lie\nand hurt you ♪"
    },
    {
      "startSeconds": 195.28,
      "durationSeconds": 1.84,
      "text": "♪ Never gonna give you up ♪"
    },
    {
      "startSeconds": 197.2,
      "durationSeconds": 2.04,
      "text": "♪ Never gonna let you down ♪"
    },
    {
      "startSeconds": 199.4,
      "durationSeconds": 3.72,
      "text": "♪ Never gonna run around\nand desert you ♪"
    },
    {
      "startSeconds": 203.36,
      "durationSeconds": 2.24,
      "text": "♪ Never gonna make you cry ♪"
    },
    {
      "startSeconds": 205.68,
      "durationSeconds": 2.16,
      "text": "♪ Never gonna say goodbye ♪"
    },
    {
      "startSeconds": 207.92,
      "durationSeconds": 3.4,
      "text": "♪ Never gonna tell a lie\nand hurt you ♪"
    }
  ],
  "transcriptCharacterCount": 2165,
  "transcriptWordCount": 487,
  "pdfUrl": "https://api.apify.com/v2/key-value-stores/UljKqhtBllP1H8Nam/records/dQw4w9WgXcQ.pdf?signature=GXDZBJOoIjWyuneyUcoI"
}
```

The **Run summary** output gives the processed, successful, and failed video counts.

#### 💳 Pricing

This Actor uses pay-per-event pricing. You are charged for each video that is successfully turned into a downloadable transcript PDF. Failed videos do not trigger that event. Apify platform usage may also apply under your plan.

#### 🔌 Integrations

Send results to Google Drive, Slack, Zapier, Make, webhooks, or another Apify integration. You can also use the Apify API, schedules, and dataset exports such as JSON, CSV, and Excel.

https://www.youtube.com/watch?v=bNACk1\_S\_6w\&list=PLObrtcm1Kw6MUrlLNDbK9QRg8VDJg0gOW\&index=4

#### ❓ FAQ

##### What happens when a video has no accessible captions?

That video fails, but the Actor keeps working on the rest of the list. It does not use speech-to-text to make new captions.

##### Can I use auto-generated YouTube captions?

Yes. The Actor can use manual or auto-generated captions and tells you which kind it used.

##### What if my chosen caption language is missing?

The Actor uses the best caption track it can access and reports the language it used.

##### Can it process playlists, channels, or keyword searches?

No. Add individual video URLs or IDs. Use a separate YouTube discovery Actor first if you need to find videos.

##### Does it translate or summarize transcripts?

No. It keeps the caption text as a transcript and makes a PDF plus structured results.

### 📝 Changelog

#### 0.0: Initial release

- Convert public YouTube captions into readable PDFs and structured transcript results, with language, layout, and annotation controls.

### 🆘 Support

For issues, questions, or feature requests, [file a ticket](https://console.apify.com/actors/maximedupre~youtube-to-pdf/issues) and I'll fix or implement it in less than 24h 🫡

### 🔗 Related Actors

- [TikTok Transcript Scraper](https://apify.com/maximedupre/tiktok-transcript-scraper) — get transcripts, timed segments, and subtitles from public TikTok videos.
- [YouTube Description Extractor](https://apify.com/maximedupre/youtube-description-extractor) — collect full descriptions and links from YouTube videos.
- [YouTube Tags Extractor](https://apify.com/maximedupre/youtube-tags-extractor) — get hidden tags and video details for content research.
- [YouTube Region Restriction Checker](https://apify.com/maximedupre/youtube-region-restriction-checker) — check where a YouTube video can be viewed.
- [YouTube Music Downloader](https://apify.com/maximedupre/youtube-music-downloader) — save audio from public YouTube videos in common formats.

**Made with ❤️ by Maxime Dupré**

# Actor input Schema

## `videoReferences` (type: `array`):

Add video URLs or video IDs. Standard, short, embed, and Shorts URLs are supported.

## `captionLanguage` (type: `string`):

Enter a language code, such as en or es. If that language is not available, the best caption track is used.

## `transcriptLayout` (type: `string`):

Choose clean paragraphs or a timestamp-focused layout.

## `removeAnnotations` (type: `boolean`):

Remove caption notes such as music, applause, and laughter markers.

## Actor input object example

```json
{
  "videoReferences": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  ],
  "captionLanguage": "en",
  "transcriptLayout": "paragraphs",
  "removeAnnotations": false
}
```

# Actor output Schema

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

Open the successful video results and download each PDF.

## `summary` (type: `string`):

Open the counts for processed, successful, and failed videos.

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

// Run the Actor and wait for it to finish
const run = await client.actor("maximedupre/youtube-to-pdf").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 = {
    "videoReferences": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"],
    "captionLanguage": "en",
}

# Run the Actor and wait for it to finish
run = client.actor("maximedupre/youtube-to-pdf").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 '{
  "videoReferences": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  ],
  "captionLanguage": "en"
}' |
apify call maximedupre/youtube-to-pdf --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,maximedupre/youtube-to-pdf"
        }
    }
}

```

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/52PIH60U4jcV4sX21/builds/ZHjuPQSqbuCouTM0F/openapi.json
