YouTube Transcript API 🚨 Real-Time, Under 1 Second
DeprecatedPricing
Pay per usage
YouTube Transcript API 🚨 Real-Time, Under 1 Second
DeprecatedReal-time YouTube transcript API: send one YouTube link to an always-on web address and get the transcript and captions back in 0.2–0.7 seconds once warm, with likes, chapters and comments on request. For chatbots, voice assistants and AI agents; unreachable videos are free.
Pricing
Pay per usage
Rating
0.0
(0)
Developer
nokia2k
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
a month ago
Last modified
Categories
Security
Limited permissionsShare
A real-time YouTube transcript API: send one video link to an always-on web address and get the transcript back in 0.2–0.7 seconds once it is awake, with likes, chapters and top comments on request, for chatbots, voice assistants, AI agents and live apps.
$99.00 per 1,000 answers at the time of writing, about ten cents a video.
Videos that do not exist, are private or could not be reached are never charged; on the always-on address a video without captions is free unless you ask for its details.
What does the real-time YouTube Transcript API do?
This Actor (Apify's word for a ready-made tool that runs on Apify's servers) is for when a person or an AI agent is waiting for the answer right now. It stays switched on at a fixed address (Apify calls this mode Standby), so there is no start-up wait between your question and the answer. Every request is raced over several lines at once, and the first answer wins. Nothing to set up on YouTube's side: no API key, no login, no proxy.
Why people pick it
- No start-up wait. The address is already running: 0.2–0.7 seconds per video for the transcript, measured from inside Apify's network on 7–8 October 2026.
- No spinner because of one slow line. Each request goes out over several lines at the same moment; the fastest one answers.
- One address to paste. A plain
GET ?url=request works in a browser, in n8n, in Make or in a few lines of code.format=textreturns just the words. - Details in the same answer. Add
details=truefor likes, exact date, chapters, most replayed moments and channel facts, andcomments=20for the top comments. - An answer for every request. Every request gets a
statusand a plainmessage. A video without captions gets a normal answer with its reason, not a failed request. - Batches too. The Start button runs lists of videos, whole channels, playlists and searches, with Only new videos since the last run for schedules.
Is it the right Actor for you?
This is the premium product of a family of six, priced for urgency: about ten cents a video. If nobody is waiting, you are paying for speed you do not need.
| Your situation | Use | Price per 1,000, at the time of writing |
|---|---|---|
| A person or an AI agent is waiting and every second counts | This Actor | $99.00 |
| You can wait about 3 seconds for a video | YouTube Transcript Scraper | $4.99 |
| You have a long list of video links and want plain text | YouTube Video to Text | $1.99 |
| You want every video of a channel or a playlist | YouTube Channel Transcripts | $9.99 |
Buy this one when the wait itself costs you something: a customer in a chat, a caller on a voice line, an agent in the middle of a conversation.
Measured speed and reliability
Speed of the always-on address, measured on 7–8 October 2026 from inside Apify's network (your own connection adds a little):
- First request after a pause: 4–5 s (the container wakes up).
- After that: 0.2–0.7 s per video for the transcript.
- With details and comments: 0.6–1.4 s per video.
Reliability, measured on the Apify platform on 8 October 2026: 3,629 videos from 20 channels in two runs gave 3,447 transcripts, 171 videos without captions, 10 age-restricted, 1 video that failed on a timeout (0.03 %) and 0 blocked by YouTube. 25 difficult videos (no captions, live, age-restricted, private, deleted, paid, blocked in the US, a 5-hour video, Japanese, Korean, Spanish, Shorts) all got the right answer. Before a video is reported as blocked or error, two separate app identities and three kinds of connection are tried: home addresses, datacenter addresses and the server's own address. A normal run always ends as Succeeded, with one row per entry that says what happened.
Quick start: your first real-time YouTube transcript in 5 steps
You need no code and no card.
-
Create a free account. Open
https://console.apify.com/sign-up. Type an email and a password and click Sign up, then click the link in the email Apify sends you. Or click Continue with Google, which needs no email check.- You see: Apify Console, the web panel of your account. The free plan gives you $5 of credit each month.
-
Copy your token. In Console open Settings, then API & Integrations.
- You see: your API token, a long line of letters and numbers. Copy it.
-
Copy this address into a plain text editor and replace
<YOUR_APIFY_TOKEN>, including the two angle brackets, with your token:https://nokia2k--youtube-transcript-instant-api.apify.actor/?url=arj7oStGLkU&format=text&token=<YOUR_APIFY_TOKEN> -
Paste the address into your browser's address bar and press Enter.
- You see: the words of a TED talk, beginning "So in college, I was a government major…". This first request can take about 4 to 5 seconds, because the Actor was asleep and had to wake up. Load the page again: now the answer is there almost at once.
-
Try your own video. Replace
arj7oStGLkUwith the 11 characters that followv=in any YouTube link, or with the whole link. To keep the text, select it, copy it and paste it into a document.
Two honest notes. Each time you load the page you send a new request, and each answer with a transcript costs $0.099, plus what Apify bills for the container while it is awake (see the cost section). And a token inside an address is fine for a private test like this one, but not for real use: see Keep the token secret.
Your first file with the Start button
- Open
https://apify.com/nokia2k/youtube-transcript-instant-apiand click Try for free. Sign in if you are asked. - Open the Input tab.
- You see: a form. The first field, 📺 Videos, channels or playlists, already holds one example video.
- Click Start.
- You see: the run (one execution of the Actor) working, and after a moment it is marked as succeeded.
- Open the Output tab, click Export, choose a format (JSON, CSV, XML, Excel, HTML table, RSS or JSONL) and click Download.
- You see: first a table with one row per video: title, status, language, transcript. Then the file lands in your browser's downloads folder.
This run delivers one row, so it costs $0.099, plus Apify's start event of $0.00005.
The smallest input for a normal run, in JSON (the Input tab has a switch between the form and JSON):
{"urls": ["https://www.youtube.com/watch?v=arj7oStGLkU"]}
What data do you get from each video?
One row per video, whether it comes from the address or from a run. On the address, details are off unless you ask for them with details=true; in the form they are on by default.
Every output field
| Field | Meaning | Example |
|---|---|---|
| The answer itself | ||
status | What happened. See Errors and troubleshooting. | success |
message | The reason in plain words when the status is not success, or a note. | "" |
charged | true when this row was billed. | true |
seconds | Always-on address only: time the Actor spent on the request, rounded to two decimals. | 0.84 |
input | The value you sent, to match answers to your list. | arj7oStGLkU |
scrapedAt | When the row was made (UTC). | 2026-10-08T09:00:00+00:00 |
detailsMissing | Parts of the details YouTube did not answer this time. Empty when all arrived. | [] |
| Transcript | ||
text | The whole transcript as one paragraph. | So in college, I was a government major… |
timestampedText | One line per caption with its time. | [00:01] All right… |
segments | Lines with start, duration, end (seconds) and text. | [{"start": 1.2, …}] |
srt, vtt | The content of an SRT or WebVTT subtitle file. | WEBVTT… |
markdown | The transcript as a document with title, channel, date and link. | # Video title… |
files | Download links of saved files (normal runs with saveFiles). | {"srt": "https://…"} |
data | Caption lines as start, dur, text strings, when the request used the single videoUrl field. | [{"start": "0.280", …}] |
segmentCount, wordCount, charCount | Lines, words and characters of the transcript. | 315, 2277, 12671 |
| Language | ||
language, languageName | Language of the returned transcript. | en, English |
isAutoGenerated | true for YouTube's speech recognition, false when a person wrote the captions. | false |
isTranslated, translatedFrom | Whether it is a machine translation, and from which language. | false, null |
availableLanguages | Every caption track the video has: code, name, isAutoGenerated, isTranslatable. | [{"code": "en", …}] |
| Video | ||
videoId, url | The 11-character ID and the watch link. | arj7oStGLkU |
title, description | Title and description. | Inside the Mind of a Master Procrastinator… |
keywords, hashtags | The uploader's tags; the hashtags above the title. | ["#TED"] |
thumbnailUrl | Link to the largest thumbnail. | https://i.ytimg.com/… |
durationSeconds, viewCount | Length in seconds; views at that moment. | 844, 62013820 |
category | YouTube's category. | People & Blogs |
descriptionLinks | Every link in the description, as text and url. | [{"text": "ted.com", …}] |
isShort, isUnlisted, isFamilySafe, isMembersOnly, isPaid | Yes/no flags as YouTube sets them. | false |
availableCountries, blockedCountries | Country codes where the video can or cannot be watched. | [] |
| Dates | ||
publishedAt, uploadedAt | Exact moment of publication and of upload. | 2016-04-06T09:59:35-07:00 |
publishedDateText | The date as YouTube prints it under the video. | Apr 6, 2016 |
publishedText | The age as YouTube's lists show it. | 2 hours ago |
| Live streams | ||
isLive, isLiveNow, liveViewers | Live content; on air now; people watching now. | false |
liveStartedAt, liveEndedAt | When the stream started and ended. | null |
| Reactions | ||
likeCount | Exact number of likes. | 2054977 |
commentCount, commentCountText | Number of comments, and as YouTube prints it. | 79650 |
commentsDisabled | true when comments are switched off. | false |
comments | Top comments: id, text, author, likes, likesText, replyCount, publishedText, isPinned, isHearted, authorIsChannelOwner. | see the sample |
| Inside the video | ||
chapters, chaptersAreAuto | Chapters with title, start, startText; whether YouTube made them itself. | see the sample |
mostReplayed | The moments viewers replay most: start, end, intensity (a relative score from 0 to 1). | see the sample |
music, musicTracks | Song, artist and album when YouTube credits them. | null |
aiSummary | YouTube's AI summary, when the video has one. | null |
relatedVideos | Up to 10 videos YouTube suggests next. | [{"videoId": "…", …}] |
| Channel | ||
channelName, channelId | Name and ID of the channel. | TED, UCAuUUnT6oDeKwE6v1NGQxug |
channelHandle, channelUrl | The @handle and the link. | @TED |
channelSubscribers, channelSubscribersText | Subscribers, rounded by YouTube, and as printed. | 27900000, 27.9M subscribers |
channelVerified, channelAvatar | Verified badge; link to the profile picture. | true |
| Where it was found (normal runs) | ||
source, sourceType, sourceTitle | The channel, playlist or search the video came from. | https://www.youtube.com/@TED, channel, TED |
positionInSource | Its place in that list, starting at 1. | 1 |
Sample output: one success answer and one no_captions answer
An answer to ?url=arj7oStGLkU&details=true&comments=1, shortened. Real values of 8 October 2026; scrapedAt and seconds are illustrations.
{"videoId": "arj7oStGLkU","url": "https://www.youtube.com/watch?v=arj7oStGLkU","status": "success","message": "","title": "Inside the Mind of a Master Procrastinator | Tim Urban | TED","channelName": "TED","channelId": "UCAuUUnT6oDeKwE6v1NGQxug","channelHandle": "@TED","channelSubscribers": 27900000,"channelSubscribersText": "27.9M subscribers","channelVerified": true,"durationSeconds": 844,"viewCount": 62013820,"publishedAt": "2016-04-06T09:59:35-07:00","category": "People & Blogs","likeCount": 2054977,"commentCount": 79650,"language": "en","languageName": "English","isAutoGenerated": false,"segmentCount": 315,"wordCount": 2277,"charCount": 12671,"text": "So in college, I was a government major, which means I had to write a lot of papers. …","chapters": [{ "title": "My procrastination journey", "start": 0, "startText": "0:00" },{ "title": "The procrastinator's brain", "start": 176, "startText": "2:56" },{ "title": "The monkey and the playground", "start": 249, "startText": "4:09" },{ "title": "The role of the panic monster", "start": 436, "startText": "7:16" },{ "title": "Two types of procrastination", "start": 599, "startText": "9:59" },{ "title": "The life calendar", "start": 756, "startText": "12:36" }],"chaptersAreAuto": true,"mostReplayed": [{ "start": 481.08, "end": 489.52, "intensity": 1 },{ "start": 16.88, "end": 25.32, "intensity": 0.951 }],"comments": [{"text": "He procrastinated in creating a Ted talk about procrastination. Ted definitely picked the right man for the job.","author": "@SWIFTzTrigger","likes": 3200,"likesText": "3.2K","replyCount": 2,"publishedText": "7 years ago"}],"detailsMissing": [],"input": "arj7oStGLkU","scrapedAt": "2026-10-08T09:00:00+00:00","charged": true,"seconds": 0.84}
An answer to ?url=<video> for a video without captions, without details=true. The ID and the title are placeholders here; the other values are what such an answer carries. It is free:
{"videoId": "<11-character ID>","url": "https://www.youtube.com/watch?v=<11-character ID>","status": "no_captions","message": "The video has no captions, neither uploaded nor auto-generated.","title": "<title of the video>","language": null,"availableLanguages": [],"wordCount": 0,"charged": false}
With details=true the same answer would carry the video's details and be charged.
Use cases
- Let a chatbot answer questions about any YouTube video a customer pastes, without a pause in the conversation.
- Give a voice assistant the words of a video fast enough to read a summary back while the caller is still on the line.
- Add a "summarize this video" button to a browser extension or an app, with your own server holding the token.
- Equip your AI agent with a sub-second transcript tool for research, support or sales conversations.
- Show a video's chapters, likes and top comments next to its transcript in a live dashboard.
- Run the same Actor in batches for channels, playlists and searches, with only new videos on a schedule.
Input examples
Two doors into the same Actor
- The always-on address (Standby). You send it a request, one question sent over the internet, and the answer goes straight back to whoever asked. One video per request.
- The Start button. This starts a run that works through a batch (videos, whole channels, playlists, searches) and puts the results in a table you can download. It costs the same per result. It has to start up first, so it is for work where nobody is waiting.
Everything this Actor can do is available through the Start button. The address does the urgent part: one video, now.
Parameters of the always-on address
Base address: https://nokia2k--youtube-transcript-instant-api.apify.actor. Sign in: header Authorization: Bearer <YOUR_APIFY_TOKEN>, or ?token=<YOUR_APIFY_TOKEN>. Requests: GET /?url=<video link or 11-character ID>, or POST / with a JSON body that uses the same fields as the input form, for one video.
| Parameter | What it does | Example |
|---|---|---|
url (also video, v, id) | The video: a link or the 11-character ID. Required. | url=arj7oStGLkU |
language (also lang) | Language code or name. Several, separated by commas, are tried in order. Without it you get the original language of the video. | language=es,en |
translate | YouTube's machine translation into this language when the video has no captions in it. | translate=es |
format | text, timestampedText, srt, vtt or markdown: the answer is the bare text in that format. Without it the answer is the JSON row. | format=srt |
details=true | Adds everything YouTube shows about the video and its channel. | details=true |
comments=<number> | Adds the top comments, up to 100. Needs details=true. | comments=20 |
Other fields of the input form can be sent under their own names, for example captionType=manual or mergeSegmentsSeconds=60. The two file options, saveFiles and combinedFile, belong to normal runs.
One video on the address, plain text
curl -s "https://nokia2k--youtube-transcript-instant-api.apify.actor/?url=arj7oStGLkU&format=text" \-H "Authorization: Bearer <YOUR_APIFY_TOKEN>"
One video with details and five comments, as JSON
curl -s "https://nokia2k--youtube-transcript-instant-api.apify.actor/?url=arj7oStGLkU&details=true&comments=5" \-H "Authorization: Bearer <YOUR_APIFY_TOKEN>"
Spanish first, or translated into Spanish, as SRT
curl -s "https://nokia2k--youtube-transcript-instant-api.apify.actor/?url=arj7oStGLkU&language=es,en&translate=es&format=srt" \-H "Authorization: Bearer <YOUR_APIFY_TOKEN>"
POST with a JSON body, one video
curl -s -X POST "https://nokia2k--youtube-transcript-instant-api.apify.actor/" \-H "Authorization: Bearer <YOUR_APIFY_TOKEN>" \-H "Content-Type: application/json" \-d '{"urls": ["https://www.youtube.com/watch?v=arj7oStGLkU"], "languages": ["es", "en"], "includeDetails": true, "maxComments": 5}'
A batch through the Start button: videos with details
{"urls": ["https://www.youtube.com/watch?v=arj7oStGLkU","https://youtu.be/jNQXAC9IVRw"],"outputFormats": ["text"],"includeDetails": true,"maxComments": 5}
The 20 newest videos of a channel, Spanish first, as Markdown
{"urls": ["https://www.youtube.com/@TED"],"maxVideosPerSource": 20,"languages": ["es", "en"],"outputFormats": ["markdown"],"contentTypes": ["videos"]}
A topic instead of links, this month's most viewed first
{"searchQueries": ["how to learn spanish"],"maxVideosPerSearch": 10,"searchUploadDate": "month","searchSortBy": "views"}
Only new videos of a channel, for a schedule
{"urls": ["https://www.youtube.com/@TED"],"maxVideosPerSource": 50,"onlyNewVideos": true,"stateKey": "ted-daily","outputFormats": ["text"]}
Every field of the form (normal runs)
Only the first field or the search field is needed. The rest has sensible defaults.
| Field in the form | Name | What it is and when to touch it | Example |
|---|---|---|---|
| 📺 Videos, channels or playlists | urls | YouTube links, one per line. A video link gives that video; a channel link or @name gives the channel's videos, newest first; a playlist link gives its videos. | https://www.youtube.com/@TED |
| 🔢 Videos per channel or playlist | maxVideosPerSource | How many videos to take from each channel or playlist. Default 50, up to 5,000. Start small: every row costs. | 5 |
| 🌐 Transcript language | languages | Leave on "Original language" to get each video in the language it is spoken in. Or pick languages in order of preference: 70 in the list, and any other code or name can be typed. | ["es", "en"] |
| 📄 Output formats | outputFormats | segments, text, timestampedText, srt, vtt, markdown. Several cost the same as one. | ["text", "markdown"] |
| 📚 Also give me everything as one Markdown file | combinedFile | Saves all transcripts of the run in one file, ALL_TRANSCRIPTS.md, for ChatGPT, Claude, NotebookLM or a knowledge base. Off by default. | true |
| 💾 Also save subtitle files I can download | saveFiles | Saves a .srt, .vtt or .txt file per video and adds download links in files. | true |
| 📊 Video and channel details | includeDetails | Adds exact date, likes, comment count, chapters, hashtags, channel subscribers and more. On by default. | true |
| 💬 Top comments per video | maxComments | How many top comments to add to each row. Default 0, up to 100. | 20 |
| 🔎 What to search for | searchQueries | What you would type into YouTube's search box, one search per line. | how to learn spanish |
| 🔢 Videos per search | maxVideosPerSearch | How many of the top results to take per search. Default 10, up to 500. | 5 |
| 📅 Uploaded | searchUploadDate | YouTube's own filter: any, hour, today, week, month, year. | month |
| ⏱️ Length | searchDuration | YouTube's own filter: any, short (under 4 minutes), medium (4 to 20), long (over 20). | medium |
| ↕️ Order | searchSortBy | relevance is YouTube's order; date and views put the found videos in that order. | views |
| Only videos that have captions (recommended) | onlyWithCaptions | Asks YouTube for videos with captions only. On by default. | true |
| 📅 Only videos newer than | newerThan | A date, or an age such as 30 days. For channels and playlists. The cut is approximate. | 6 months |
| Only new videos since the last run | onlyNewVideos | For scheduled runs: only videos not delivered before for the same channels, playlists and searches. Off by default. | true |
| Memory name | stateKey | Optional, with the field above: the name of the list of delivered videos. | ted-daily |
| 🎞️ Kinds of videos to take from a channel | contentTypes | Regular videos, Shorts, recordings of live streams. Untick what you do not need. | ["videos"] |
| 🔁 Translate to | translateTo | YouTube's machine translation, used when the video has no captions in that language. | es |
| If my language is missing, give me the original language | fallbackToAnyLanguage | On: you still get a transcript, in the original language. Off: such videos are skipped. | false |
| Caption type | captionType | any (human-made first), manual (human-made only), auto (auto-generated only). | manual |
| Merge caption lines into blocks | mergeSegmentsSeconds | Joins the short caption lines into blocks of about this many seconds. 0 keeps the original lines. | 60 |
| Include video details | includeMetadata | Adds channel, duration, views, description, keywords and thumbnail. The title is always there. | true |
Run it on a schedule and get only new videos
The always-on address answers one video per request. Following channels, playlists or searches is a job for normal runs on a schedule.
How "Only new videos since the last run" works
- Turn on Only new videos since the last run (
onlyNewVideos). It is off by default and made for scheduled runs (Apify Schedules). - Each run then delivers only the videos it has not delivered before for the same channels, playlists and searches. Videos already delivered are left out before anything is fetched, so they are neither fetched nor charged.
- The first run delivers everything it finds and remembers it.
- Video links you paste directly are always delivered, never left out. They are remembered, so a channel or search that contains them later does not deliver them again.
Set it up step by step
- Fill the form: your channels, playlists or searches and your formats. Tick Only new videos since the last run. Optional: type a Memory name such as
ted-daily. - Click Start once by hand. The first run delivers what it finds and remembers it. It also makes the Actor schedulable: an Actor must have run once before it can be scheduled.
- Click Save as a new task at the top right of the Actor page. A task is a saved form; it appears under Saved tasks.
- Open Schedules in the left menu and click Create new.
- In the Schedule setup card choose how often (a cron expression such as
@daily, or the visual builder) and your time zone. Next runs shows the coming dates. - In the Add dropdown pick your task.
- Click Enable. New schedules start disabled.
What you see in later runs
- The log and the run's final status message say how many videos were left out, for example: "Skipped 37 videos already delivered in earlier runs (memory 'x')."
- A run with nothing new ends normally, with no rows: "No new videos since the last run: … Nothing was charged."
Memory name: one list or several
- Left empty: the memory is named
auto-…after your list of channels, playlists and searches. The order and the letter case of searches do not matter; any other change to the list starts a new memory. - With a name: you pick the record. The same name keeps one list even when the links change; a different name keeps a separate list.
- Letters, digits and
-_.!'()are kept; other characters become-.
Where the memory lives and how to start afresh
The memory is kept in your own Apify account: Storage > Key-value stores, in the store named youtube-transcripts-memory. Each memory is one record that holds the IDs of the most recent 20,000 delivered videos and the time it was last updated. Delete the record, or the whole store, and the next run starts afresh and delivers everything again.
Good to know
- Remembered: videos delivered as
successorno_captions, and every row that was charged. Free rows (blocked,error,age_restrictedwithout details) and a live stream that is still running or has not started are tried again next run. - Never charged twice: a row can be charged for its details even when its status is not
successorno_captions, for example anage_restrictedvideo whose details arrived. Every charged video is remembered, so a later run with Only new videos since the last run never charges it again. - Keep the numbers high enough. 🔢 Videos per channel or playlist and 🔢 Videos per search count the videos looked at in each run, before the known ones are left out.
- The memory is saved at the end of the run, also when the run stops before its time limit or at the spending cap (then only the videos that were processed). After a server move the run continues and saves at its end; nothing is counted or charged twice.
- If the memory cannot be read, the run logs a warning and delivers all videos like a normal run. If it cannot be saved, the results are still delivered, and the next run may repeat some videos.
- Two runs with the same memory at the same time can both deliver the same new video. The memory itself keeps the videos of both.
Send new videos to Google Sheets or Slack
- n8n: add the Apify Trigger node (Resource to Watch: Task, your task; Event Type: Succeeded). Then an Apify node with Resource Dataset, Get Items, and the
defaultDatasetIdof the run as Dataset ID (raise Limit: it starts at 50). Then a Google Sheets node that appends one row per item (title,url,publishedAt,text), or a Slack node that poststitleandurl. A self-hosted n8n needs a publicWEBHOOK_URLso that Apify can reach it. - Make: start with Watch Actor Runs (it fires when a run finishes), then Get Dataset Items, then a Google Sheets module (Apify's guide uses "Bulk Add Rows") or a Slack module.
- Any other tool: on the task's Integrations tab add a webhook for the event
ACTOR.RUN.SUCCEEDED. Apify sends a POST to your address; the dataset ID is inresource.defaultDatasetId. The receiver must answer within 2 minutes, and a webhook can arrive twice.
A run with no new videos still finishes as Succeeded, with an empty dataset: your sheet simply gets no new rows that time.
Use the real-time YouTube Transcript API from AI agents (MCP)
MCP is the standard that lets an AI assistant use outside tools. Apify's MCP address with this Actor as a tool is:
https://mcp.apify.com?tools=nokia2k/youtube-transcript-instant-api
Be aware: through MCP the assistant starts a normal run and waits for it (up to 45 seconds), so this path has the start-up wait. If your own agent must answer within a second, give its code a tool that calls the always-on address directly (see Integrations).
Sign-in is OAuth: a browser window opens on the first connection and no token is stored in the configuration. A header Authorization: Bearer <YOUR_APIFY_TOKEN> works too.
Claude.ai and Claude Desktop
- Open Connectors in Claude (Settings > Connectors, or Customize > Connectors depending on your version).
- Choose Add custom connector.
- Fill in Name and Remote MCP server URL with the address above, click Continue, then Add.
- Sign in to Apify in the browser window that opens.
- In a chat, click +, then Connectors, and switch it on.
On the free Claude plan you can add one custom connector. On Team and Enterprise plans an Owner adds it for the organization.
Claude Desktop with a local server
claude_desktop_config.json, needs Node.js:
{"mcpServers": {"youtube-instant": {"command": "npx","args": ["-y", "@apify/actors-mcp-server", "--tools", "nokia2k/youtube-transcript-instant-api"],"env": {"APIFY_TOKEN": "<YOUR_APIFY_TOKEN>"}}}}
Cursor
.cursor/mcp.json in your project, or ~/.cursor/mcp.json:
{"mcpServers": {"youtube-instant": {"url": "https://mcp.apify.com?tools=nokia2k/youtube-transcript-instant-api"}}}
With a token instead of OAuth, add "headers": { "Authorization": "Bearer <YOUR_APIFY_TOKEN>" } next to "url".
VS Code
Needs GitHub Copilot. Open the Command Palette, run MCP: Open User Configuration and add:
{"servers": {"youtube-instant": {"type": "http","url": "https://mcp.apify.com?tools=nokia2k/youtube-transcript-instant-api"}}}
Claude Code and ChatGPT
claude mcp add --transport http youtube-instant \"https://mcp.apify.com?tools=nokia2k/youtube-transcript-instant-api" \--header "Authorization: Bearer $APIFY_TOKEN"
ChatGPT: Developer mode is required. Go to Settings > Apps & Connectors > Create, fill in Name, Description and MCP Server URL, leave Authentication on OAuth, click Create. In a chat, click +, then More, and pick the connector.
Example prompts
- "Get the transcript of https://www.youtube.com/watch?v=arj7oStGLkU and answer: what is the 'panic monster'?"
- "Fetch this video with its chapters and tell me which chapter covers the life calendar and at what time: https://youtu.be/arj7oStGLkU"
- "Get the transcript and the top 5 comments of this video and draft a short reply to the most liked comment: [link]"
Integrations: n8n, Make, Zapier, Python, JavaScript and LangChain
What a token and a header are, and how to keep the token secret
A token is a long secret password that tells Apify which account is asking and which account pays. It is in Console under Settings, then API & Integrations; here it is written <YOUR_APIFY_TOKEN>. A header is a labelled line that travels with a request but outside the address, like the sender's name on an envelope instead of inside the letter.
You can hand over the token in two ways:
- In a header (the better way): the header is named
Authorizationand its value is the wordBearer, one space, then your token. - In the address: add
token=<YOUR_APIFY_TOKEN>as a parameter. This is the only way that works when you type an address into a browser.
How to keep it secret:
- Prefer the header. An address is saved in browser history and gets copied into chats, screenshots and logs. A header is not.
- In n8n, Make or Zapier, store the token in the tool's own box for credentials or connections, not in a text field of a workflow you may share or export.
- Never put the token in something that runs on your visitor's device: a web page, a browser extension, a mobile app. Anyone can read it there. Let your own server hold the token and call the address.
- Do not paste it into forums, screenshots or the Issues tab.
- If it leaks, go back to Settings, API & Integrations. A token can be rotated (replaced by a new one), given an expiry date, and limited with the toggle "Limit token permissions".
n8n (HTTP Request node, the always-on address)
- In your workflow add the HTTP Request node.
- You see: its settings panel.
- Set Method to GET.
- In URL paste
https://nokia2k--youtube-transcript-instant-api.apify.actor/ - Under Authentication choose the generic credential type, then Header auth. Create a credential with Name
Authorizationand ValueBearer <YOUR_APIFY_TOKEN>. n8n now keeps your token out of the workflow itself. - Turn on Send Query Parameters. Add a parameter named
urland give it the YouTube link from your earlier node. Add a second one namedformatwith the valuetextif you want only the words. - Click Add Option, choose Timeout and type
60000. That is 60 seconds in milliseconds, so the wake-up after a pause never cuts the request short. - Run the node.
- You see: with
format, the transcript as text. Without it, one item with fields such asstatus,title,textandseconds.
- You see: with
- Connect the next node. When you read the fields, check that
statusissuccessbefore you usetext.
To send more options, change Method to POST, turn on Send Body, set Body Content Type to JSON and Specify Body to Using JSON, and paste the POST example from Input examples.
For batches, n8n also has an Apify node, which you install from the nodes panel by searching Apify: Resource Actor, Operation Run an Actor and Get Dataset. Pick this Actor and paste the input into Input JSON. That starts a normal run.
Make (HTTP module)
Make's own screens are not quoted here, so look for these things by what they do.
- Add Make's HTTP app to your scenario and pick the module that sends a request.
- In the field for the address, paste
https://nokia2k--youtube-transcript-instant-api.apify.actor/ - Choose GET as the method.
- Add one header. Name:
Authorization. Value:Bearer <YOUR_APIFY_TOKEN>. - Add a query parameter named
urland map the YouTube link from your earlier module into it. Addformatwith the valuetextif you want only the words. - Run the scenario once.
- You see: the status code 200 and the transcript in the module's output.
- If you left
formatout, switch on the module's option that reads the answer as data. Thentitle,textand the other fields can be mapped in the next module.
For batches, Make's Apify app has Run an Actor (set Run synchronously to Yes) followed by Get Dataset Items. For runs longer than about 2 minutes, use Watch Actor Runs and then Get Dataset Items.
Zapier
- For the always-on address: use a Zapier step that can send a web request and fill in the same things as in Make: address, method GET, the
Authorizationheader and theurlparameter. - For a batch: add the Apify app and choose the action Run Actor. Click Allow Access to connect your account, pick this Actor and give it the input.
- A synchronous Run Actor has a hard limit of 30 seconds. For anything that may take longer, use two Zaps: Zap A ends with Run Actor (asynchronous); Zap B starts with Finished Actor Run, then Fetch Dataset Items.
Python (requests, the always-on address)
import requestsADDRESS = "https://nokia2k--youtube-transcript-instant-api.apify.actor/"HEADERS = {"Authorization": "Bearer <YOUR_APIFY_TOKEN>"}response = requests.get(ADDRESS,params={"url": "https://www.youtube.com/watch?v=arj7oStGLkU","details": "true","comments": 5,},headers=HEADERS,timeout=60,)row = response.json() # 200, 400 and 402 all answer with JSON hereif response.status_code == 200 and row["status"] == "success":print(row["title"], "-", row["wordCount"], "words in", row["seconds"], "s")print(row["text"][:200])else:print(response.status_code, row["status"], row["message"])
JavaScript (fetch, the always-on address)
Run this on your server, not in a web page, so the token stays private.
const address = new URL('https://nokia2k--youtube-transcript-instant-api.apify.actor/');address.searchParams.set('url', 'https://www.youtube.com/watch?v=arj7oStGLkU');address.searchParams.set('format', 'srt');const response = await fetch(address, {headers: { Authorization: 'Bearer <YOUR_APIFY_TOKEN>' },});const type = response.headers.get('content-type') || '';if (type.includes('json')) {const row = await response.json(); // no transcript, or a problemconsole.log(response.status, row.status, row.message);} else {console.log(await response.text()); // the subtitle file}
Normal runs through the Apify API: curl and Python
A batch goes through Apify's own API. This call starts a run, waits and returns the rows. It has a limit of 300 seconds; a longer run answers with HTTP 408, so start big jobs with POST /v2/acts/nokia2k~youtube-transcript-instant-api/runs and read the dataset when the run has finished.
curl -X POST "https://api.apify.com/v2/acts/nokia2k~youtube-transcript-instant-api/run-sync-get-dataset-items?maxTotalChargeUsd=5" \-H "Authorization: Bearer <YOUR_APIFY_TOKEN>" \-H "Content-Type: application/json" \-d '{"urls": ["https://www.youtube.com/@TED"], "maxVideosPerSource": 5, "outputFormats": ["text"]}'
With pip install apify-client (version 3, Python 3.11 or newer):
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("nokia2k/youtube-transcript-instant-api").call(run_input={"urls": ["https://www.youtube.com/@TED"],"maxVideosPerSource": 5,"outputFormats": ["text"],},)for row in client.dataset(run.default_dataset_id).iterate_items():print(row["status"], row["charged"], row.get("title"))
LangChain
For an agent that must answer within a second, wrap the always-on address in your own tool (the Python example above is the whole call). For batches, langchain-apify runs the Actor as a normal run: pip install langchain-apify langchain-core, set APIFY_API_TOKEN, then:
from langchain_apify import ApifyWrapperfrom langchain_core.documents import Documentloader = ApifyWrapper().call_actor(actor_id="nokia2k/youtube-transcript-instant-api",run_input={"urls": ["https://www.youtube.com/watch?v=arj7oStGLkU"],"outputFormats": ["text"],},dataset_mapping_function=lambda row: Document(page_content=row.get("text") or "",metadata={"source": row.get("url"),"title": row.get("title"),"status": row.get("status"),},),)docs = [d for d in loader.load() if d.metadata["status"] == "success"]
Google Sheets and Excel
- By hand: after a normal run click Export, choose Excel or CSV, click Download. Open the file in Excel or import it into Google Sheets.
- Automatically: in n8n, Make or Zapier, put a spreadsheet step after the HTTP step and write
title,urlandtextinto a new row. - Afterwards: every answer from the always-on address is also saved in the dataset of the standby run. A dataset is the table where Apify keeps results. In Console open Storage, then the Datasets tab, click the Dataset ID and use Export.
How much does a real-time YouTube transcript API cost?
$99.00 per 1,000 answers at the time of writing. "Per 1,000" is only a way of printing the price: each answer is charged on its own, $99.00 ÷ 1,000 = $0.099 per video. There is no subscription. The price that counts is the one on the Actor's Pricing tab.
What is charged: an answer or row that carries a transcript, or the video's details, or both. The charged field of every row says which it was.
What else you pay:
- Normal runs: Apify's start event, $0.00005 per run for each GB of memory (this Actor uses 1 GB by default). Nothing else: no platform usage, no proxy fees.
- The always-on address: Apify also bills you the platform usage of the standby container while it is up. This is Apify's rule for every Standby Actor. The container goes to sleep after 5 minutes without requests. That usage depends on how long the container stays up, so it is not in the table below.
| One normal run with | Rows charged | Videos | Run start (1 GB) | Total |
|---|---|---|---|---|
| 10 videos | 10 | $0.99 | $0.00005 | $0.99005 |
| 1,000 videos | 1,000 | $99.00 | $0.00005 | $99.00005 |
| 10,000 videos | 10,000 | $990.00 | $0.00005 | $990.00005 |
On the always-on address the same counts cost $0.99, $99.00 and $990.00 in answers, plus the platform usage of the container. 100 requests of which 12 are for private or deleted videos cost 88 × $0.099 = $8.71 in answers.
What is never charged: videos that do not exist, are private or could not be reached; values that are not a YouTube video; the 400 and 402 answers; extra formats, translation, comments. On the always-on address, a video without captions is free unless you asked for details=true and the details were delivered.
The free plan: $5 of credit each month, no card needed. At this price that is about 50 answers a month: enough to test, not to run a product.
How to cap spending: before a normal run, open Run options and fill in Maximum cost per run. The Actor stops at the cap and says so. Through the API the same cap is the parameter maxTotalChargeUsd. On the always-on address, a request over the cap gets HTTP 402. What you have spent is under Billing in Console.
Errors and troubleshooting
What each status means
Read status, then message. The last column is the rule of thumb; the charged field of each row is the final word.
status | In plain words | What to do | Charged |
|---|---|---|---|
success | The transcript was delivered. | Use it. | Yes |
no_captions | The video has no captions, or it is a live stream that is still running. | Nothing can be read. For a stream, ask again after it ends. | Only if the row carries the details |
language_unavailable | No captions in the languages you chose, and the fallback is off. | Look at availableLanguages, or turn the fallback on. | Only if the row carries the details |
video_unavailable | Deleted, or never existed. | Check the link. | No |
video_unplayable | Private, paid, blocked in the region or removed by YouTube. message has YouTube's reason. | Nothing to do: it is not public. | No for private videos; otherwise only if the details arrived |
age_restricted | YouTube shows it only to signed-in adults. | Cannot be read. | Only if the details arrived |
blocked | YouTube refused every connection that was tried. | Ask again later. | No, unless the details arrived |
error | Something unexpected. message says what. | Ask again. | No, unless the details arrived |
invalid_input | The value is not a YouTube link or ID. On the address this is HTTP 400. | Correct the value. One video per request. | No |
source_problem | A channel, playlist or search could not be listed (normal runs). message says why. | Check the link or the search words. | No |
Status codes of the always-on address
| Code | When | Body |
|---|---|---|
| 200 | The request was answered | The JSON row: the same fields as a dataset row, plus seconds. Or the bare text, when format is given and there is a transcript. |
| 400 | No video in the request, or more than one | JSON with status: "invalid_input" and a message |
| 402 | The spending limit of the run is reached | JSON with status: "error" and a message. Nothing is charged. |
What to handle in your code:
- 200 does not mean "transcript". Read
status. A video without captions is a 200 withstatus: "no_captions". - With
format, check the content type. A transcript arrives astext/plain(text,timestampedText),application/x-subrip(srt),text/vttortext/markdown. If there is no transcript, you get the JSON row asapplication/jsoninstead. secondsis the time the Actor spent on your request. The trip between you and Apify is not in it.- Cold start: after 5 minutes without requests the container goes to sleep, and the next request wakes it, which takes about 4 to 5 seconds. Give your client a generous timeout, for example 60 seconds.
- One video per request. Lists, channels and searches go through a normal run.
Problems and solutions
- "My first request took 4 to 5 seconds." The container was asleep. Requests after it are fast again.
- "I get HTTP 400." The request has no video, or more than one. Send exactly one
url. - "I get HTTP 402." The spending limit of the run is reached. Nothing was charged.
- "The answer is JSON although I asked for format=text." There is no transcript for that video; read
statusandmessage. - "Detail fields are empty." On the address, details come only with
details=true. Some things do not exist for every video (chapters, music, AI summary);detailsMissinglists what YouTube did not answer this time. - "My MCP assistant is slow." MCP starts a normal run with a start-up wait. Call the address from your agent's code for sub-second answers.
- "n8n times out on the first call." Set the HTTP Request Timeout option to
60000.
Limits to know
- It does not listen to the audio. A video with no captions at all gives
no_captions. - It cannot read age-restricted, private or members-only videos.
- It has no dislikes: YouTube does not show them.
- Subscriber counts are rounded by YouTube ("27.9M"). Comment likes above 999 are rounded too ("1.2K"); you get both
likesandlikesText. - The address takes one video per request.
- After 5 quiet minutes, the next request waits about 4 to 5 seconds.
FAQ
Why did a video come back without a transcript?
Because YouTube has no captions for it, or it is not public. The status field names the case and message explains it.
Am I charged when there is no result?
Not when the video does not exist, is private or could not be reached. An answer is charged when it carries a transcript or the video's details. Look at charged on any row.
What does "$99.00 per 1,000" mean, and what will I pay?
It is the price of 1,000 answers. You pay per answer: $0.099 each at the time of writing. Ten videos cost $0.99, plus the platform usage of the container on the always-on address.
Why does it cost so much more than the other Actors of the family?
You pay for an Actor that is already awake and for several lines raced on every request. If you can wait about 3 seconds, YouTube Transcript Scraper costs $4.99 per 1,000.
Why did my first request take about 4 to 5 seconds?
The container sleeps after 5 minutes without requests. The next request wakes it. The ones after that took 0.2–0.7 s for the transcript in the measurement above.
Can I keep it awake?
A request within every 5 minutes keeps it up. Remember that Apify bills the platform usage of the container for as long as it is up.
Does it work with YouTube Shorts and live streams?
Shorts: yes, when they have captions. A live stream that is still running gives no_captions; ask again after it ends.
Can I give it a channel or a playlist?
Through the Start button, yes: paste the link into 📺 Videos, channels or playlists. The address takes one video per request and answers 400 to anything else.
Which language do I get, and can it translate?
By default the language the video is spoken in. Choose others with language, or with 🌐 Transcript language in the form. translate asks for YouTube's own machine translation, which YouTube does not offer for every video.
Does it transcribe the audio when there are no captions?
No. It reads captions that already exist on YouTube.
Will YouTube block it? Do I need a proxy or a YouTube API key?
No and no. There is nothing to set up. In the measurement above, 0 of 3,629 videos were blocked.
Where are my results?
On the address, the answer is the result: it comes back to whoever asked. A copy is in the dataset of the standby run. After a normal run, open the Output tab.
A field is empty or missing. Why?
Detail fields come only with details=true (address) or 📊 Video and channel details (form). Transcript formats come only when chosen. Some things do not exist for every video: chapters, music, AI summary. detailsMissing lists what YouTube did not answer this time.
How exact is the date filter?
📅 Only videos newer than is approximate, because YouTube's lists show ages roughly ("3 weeks ago"). Nothing newer is left out; a few videos just past the limit can slip in. The exact date is in publishedAt.
Why did a run return fewer rows than I asked for?
The channel or search had fewer videos, a filter removed some, a link was pasted twice (each video is fetched once), the memory left out videos delivered earlier, or the spending cap or the run's timeout was reached. The run's message says how many videos were not processed.
How do I get the answer into n8n, Make, Zapier or Google Sheets?
Follow Integrations. It is one HTTP step with the address, one header and one parameter.
Can ChatGPT or Claude use it?
Yes, through Apify's MCP server. That path starts a normal run. For an agent that must answer within a second, call the address from the agent's own code.
What do the timestamps mean? SRT or VTT?
Each line has a start and an end in seconds from the beginning of the video. SRT and VTT are two subtitle file types with the same lines: SRT is the common one for video editors, VTT the one web players use.
Can I get comments, likes and the publish date?
Yes: details=true adds likes, the exact date and the rest; comments=20 adds the top 20 comments, up to 100.
How many videos per request, and per run?
One per request. Requests can be sent side by side. A run takes up to 5,000 videos per channel or playlist and up to 500 per search. How many runs you may have at once depends on your Apify plan.
Is it safe to call the address from my web page or extension?
Not directly: the token would be visible to every visitor. Let your own server hold the token and make the call.
Is it legal? What about private videos?
The Actor reads only what YouTube shows publicly to any visitor. It does not read private videos. What you do with the texts is your responsibility: respect copyright and YouTube's terms.
What do Standby, request, header and status code mean?
- Actor: a ready-made tool that runs on Apify's servers.
- Run: one execution of an Actor, from Start to finished.
- Standby: Apify's name for an Actor that stays switched on and answers requests at a fixed address.
- Request: one question sent over the internet to an address.
- Parameter: a setting written into an address after the
?, asname=value, joined with&. - Token (API token): the secret password of your Apify account.
- Header: a labelled line sent with a request, outside the address.
- Status code: the number every web answer begins with. 200 means answered, 400 means the request was wrong, 402 means the spending limit was reached.
- JSON: a text format for data that programs read easily, made of names and values.
- Dataset: the table in which Apify stores results.
- Key-value store: the folder of a run where files such as
ALL_TRANSCRIPTS.mdare kept. - Captions and transcript: captions are the text lines YouTube shows over a video; the transcript is all of those lines together.
- Auto-generated captions: captions made by YouTube's speech recognition, not by a person. Many have no punctuation.
- SRT and VTT: two common subtitle file types.
- Cold start: the wake-up of a sleeping container, about 4 to 5 seconds here.
- MCP: the standard through which AI assistants use outside tools.
Something went wrong. Where do I get help?
Open the Issues tab of this Actor. See Support and updates.
Related YouTube tools
Six Actors by the same developer, each made for a different starting point: pick the one that matches what you have. Prices per 1,000 results at the time of writing.
| Actor | Use it when you have | You get | Price |
|---|---|---|---|
| YouTube Video to Text 📝 | A big list of video links | Plain text only, the lowest price | $1.99 |
| YouTube Transcript Scraper ⚡ | Video links, and about 3 seconds is fast enough | Text, timestamps, SRT, VTT, translation | $4.99 |
| YouTube Channel Transcripts 📚 | A channel, @handle or playlist | Every video, publish date, likes, one Markdown file, only new videos | $9.99 |
| YouTube Search Transcripts Scraper 🔎 | A topic, no links | Transcripts of the videos YouTube ranks highest | $14.99 |
| YouTube Scraper 🧰 | Any of the above, you need numbers, and nobody is waiting | Transcript plus likes, comments, chapters, channel facts | $19.99 |
| YouTube Transcript API 🚨 (you are here) | An app that needs one video right now | An always-on web address, no start-up wait | $99.00 |
Support and updates
Open an issue on the Issues tab of this Actor. Include the video link, the address you called without your token, the status and message you received and, for a normal run, the link to the run.
Last updated: October 2026.
Get your first transcript: paste one link and click Start, or open the address above in your browser.
🇪🇸 Guía completa en español
Una API de transcripciones de YouTube en tiempo real: envía un enlace de video a una dirección web siempre encendida y recibe la transcripción en 0.2–0.7 segundos cuando está despierta, con «me gusta», capítulos y comentarios principales si los pides, para chatbots, asistentes de voz, agentes de IA y aplicaciones en vivo.
$99.00 por cada 1000 respuestas en el momento de escribir esto, unos diez centavos por video.
Los videos que no existen, son privados o no se pudieron alcanzar nunca se cobran; en la dirección siempre encendida, un video sin subtítulos es gratis salvo que pidas sus datos.
Este Actor (así llama Apify a una herramienta lista para usar que funciona en sus servidores) es para cuando una persona o un agente de IA está esperando la respuesta ahora mismo. Se queda encendido en una dirección fija (Apify llama a este modo Standby, «en espera»), así que no hay espera de arranque entre tu pregunta y la respuesta. Cada petición compite por varias líneas a la vez, y gana la primera respuesta. No hay nada que configurar del lado de YouTube: ni clave de API, ni inicio de sesión, ni proxy.
Las pantallas de Apify están en inglés. Por eso los botones y pestañas aparecen aquí en inglés y en negrita, con su significado entre comillas angulares la primera vez. Los nombres de los campos, los parámetros, los valores de status y el JSON también se quedan en inglés.
Por qué lo eligen
- Sin espera de arranque. La dirección ya está en marcha: de 0.2 a 0.7 segundos por video para la transcripción, medido desde dentro de la red de Apify el 7 y 8 de octubre de 2026.
- Sin ruedita girando por una línea lenta. Cada petición sale por varias líneas en el mismo momento; responde la más rápida.
- Una dirección que pegar. Una petición sencilla
GET ?url=funciona en un navegador, en n8n, en Make o en unas pocas líneas de código.format=textdevuelve solo las palabras. - Los datos en la misma respuesta. Añade
details=truepara «me gusta», fecha exacta, capítulos, momentos más repetidos y datos del canal, ycomments=20para los comentarios principales. - Una respuesta para cada petición. Cada petición recibe un
statusy unmessageen lenguaje claro. Un video sin subtítulos recibe una respuesta normal con su motivo, no una petición fallida. - También por lotes. El botón Start («Iniciar») procesa listas de videos, canales enteros, listas de reproducción y búsquedas, con Only new videos since the last run («Solo videos nuevos desde la última ejecución») para programaciones.
¿Es el Actor que necesitas?
Es el producto premium de una familia de seis, con un precio pensado para la urgencia: unos diez centavos por video. Si nadie está esperando, pagas una velocidad que no necesitas.
| Tu situación | Usa | Precio por cada 1000, en el momento de escribir esto |
|---|---|---|
| Una persona o un agente de IA está esperando y cada segundo cuenta | Este Actor | $99.00 |
| Puedes esperar unos 3 segundos por video | YouTube Transcript Scraper | $4.99 |
| Tienes una lista larga de enlaces de videos y quieres texto plano | YouTube Video to Text | $1.99 |
| Quieres todos los videos de un canal o de una lista de reproducción | YouTube Channel Transcripts | $9.99 |
Elige este cuando la propia espera te cuesta algo: un cliente en un chat, alguien al teléfono con un asistente de voz, un agente en mitad de una conversación.
Velocidad y fiabilidad medidas
Velocidad de la dirección siempre encendida, medida el 7 y 8 de octubre de 2026 desde dentro de la red de Apify (tu propia conexión añade un poco):
- Primera petición tras una pausa: de 4 a 5 s (el contenedor se despierta).
- Después: de 0.2 a 0.7 s por video para la transcripción.
- Con datos y comentarios: de 0.6 a 1.4 s por video.
Fiabilidad, medida en la plataforma de Apify el 8 de octubre de 2026: 3629 videos de 20 canales en dos ejecuciones dieron 3447 transcripciones, 171 videos sin subtítulos, 10 con restricción de edad, 1 video fallido por tiempo agotado (0.03 %) y 0 bloqueados por YouTube. 25 videos difíciles (sin subtítulos, en directo, con restricción de edad, privados, borrados, de pago, bloqueados en Estados Unidos, un video de 5 horas, en japonés, coreano y español, Shorts) recibieron todos la respuesta correcta. Antes de dar un video por blocked o error, se prueban dos identidades de aplicación distintas y tres tipos de conexión: direcciones domésticas, direcciones de centros de datos y la dirección del propio servidor. Una ejecución normal siempre termina como Succeeded («completada»), con una fila por entrada que dice qué pasó.
Inicio rápido: tu primera transcripción de YouTube en tiempo real en 5 pasos
No necesitas código ni tarjeta.
-
Crea una cuenta gratuita. Abre
https://console.apify.com/sign-up. Escribe un correo y una contraseña y haz clic en Sign up («Registrarse»); después haz clic en el enlace del correo que te envía Apify. O haz clic en Continue with Google («Continuar con Google»), que no necesita comprobar el correo.- Verás: Apify Console («Consola de Apify»), el panel web de tu cuenta. El plan gratuito te da $5 de crédito cada mes.
-
Copia tu token. En la consola abre Settings («Configuración») y luego API & Integrations («API e integraciones»).
- Verás: tu token de API, una línea larga de letras y números. Cópialo.
-
Copia esta dirección en un editor de texto sencillo y sustituye
<YOUR_APIFY_TOKEN>, incluidos los dos signos angulares, por tu token:https://nokia2k--youtube-transcript-instant-api.apify.actor/?url=arj7oStGLkU&format=text&token=<YOUR_APIFY_TOKEN> -
Pega la dirección en la barra de direcciones del navegador y pulsa Intro.
- Verás: las palabras de una charla TED, que empiezan por "So in college, I was a government major…". Esta primera petición puede tardar unos 4 o 5 segundos, porque el Actor estaba dormido y tuvo que despertarse. Vuelve a cargar la página: ahora la respuesta llega casi al instante.
-
Prueba con tu propio video. Sustituye
arj7oStGLkUpor los 11 caracteres que siguen av=en cualquier enlace de YouTube, o por el enlace entero. Para guardar el texto, selecciónalo, cópialo y pégalo en un documento.
Dos avisos honestos. Cada vez que cargas la página envías una petición nueva, y cada respuesta con transcripción cuesta $0.099, más lo que Apify factura por el contenedor mientras está despierto (mira «¿Cuánto cuesta una API de transcripciones de YouTube en tiempo real?»). Y un token dentro de una dirección vale para una prueba privada como esta, pero no para el uso real: mira «Qué son un token y una cabecera, y cómo guardar el token en secreto».
Tu primer archivo con el botón Start
- Abre
https://apify.com/nokia2k/youtube-transcript-instant-apiy haz clic en Try for free («Probar gratis»). Inicia sesión si te lo pide. - Abre la pestaña Input («Entrada»).
- Verás: un formulario. El primer campo, 📺 Videos, channels or playlists («Videos, canales o listas»), ya trae un video de ejemplo.
- Haz clic en Start.
- Verás: la ejecución (cada vez que el Actor trabaja) en marcha, y al poco aparece como completada.
- Abre la pestaña Output («Salida»), haz clic en Export («Exportar»), elige un formato (JSON, CSV, XML, Excel, HTML table, RSS o JSONL) y haz clic en Download («Descargar»).
- Verás: primero una tabla con una fila por video: título, estado, idioma, transcripción. Después el archivo llega a la carpeta de descargas de tu navegador.
Esta ejecución entrega una fila, así que cuesta $0.099, más el evento de inicio de Apify de $0.00005.
La entrada más pequeña para una ejecución normal, en JSON (la pestaña Input tiene un selector entre el formulario y JSON):
{"urls": ["https://www.youtube.com/watch?v=arj7oStGLkU"]}
Qué datos recibes de cada video
Una fila por video, venga de la dirección o de una ejecución. En la dirección, los datos están desactivados salvo que los pidas con details=true; en el formulario están activados por defecto.
Todos los campos de salida
| Campo | Qué significa | Ejemplo |
|---|---|---|
| La respuesta | ||
status | Qué pasó. Mira «Errores y solución de problemas». | success |
message | El motivo en palabras sencillas cuando el estado no es success, o una nota. | "" |
charged | true cuando esta fila se facturó. | true |
seconds | Solo en la dirección siempre encendida: el tiempo que el Actor dedicó a la petición, redondeado a dos decimales. | 0.84 |
input | El valor que enviaste, para emparejar respuestas con tu lista. | arj7oStGLkU |
scrapedAt | Cuándo se creó la fila (UTC). | 2026-10-08T09:00:00+00:00 |
detailsMissing | Partes de los datos que YouTube no respondió esta vez. Vacío cuando llegó todo. | [] |
| Transcripción | ||
text | Toda la transcripción como un párrafo. | So in college, I was a government major… |
timestampedText | Una línea por subtítulo con su tiempo. | [00:01] All right… |
segments | Líneas con start, duration, end (segundos) y text. | [{"start": 1.2, …}] |
srt, vtt | El contenido de un archivo de subtítulos SRT o WebVTT. | WEBVTT… |
markdown | La transcripción como documento con título, canal, fecha y enlace. | # Video title… |
files | Enlaces de descarga de los archivos guardados (ejecuciones normales con saveFiles). | {"srt": "https://…"} |
data | Líneas de subtítulos como cadenas start, dur, text, cuando la petición usó el campo único videoUrl. | [{"start": "0.280", …}] |
segmentCount, wordCount, charCount | Líneas, palabras y caracteres de la transcripción. | 315, 2277, 12671 |
| Idioma | ||
language, languageName | Idioma de la transcripción devuelta. | en, English |
isAutoGenerated | true para el reconocimiento de voz de YouTube, false cuando los subtítulos los escribió una persona. | false |
isTranslated, translatedFrom | Si es una traducción automática, y desde qué idioma. | false, null |
availableLanguages | Todas las pistas de subtítulos del video: code, name, isAutoGenerated, isTranslatable. | [{"code": "en", …}] |
| Video | ||
videoId, url | El identificador de 11 caracteres y el enlace de reproducción. | arj7oStGLkU |
title, description | Título y descripción. | Inside the Mind of a Master Procrastinator… |
keywords, hashtags | Las etiquetas de quien lo subió; los hashtags sobre el título. | ["#TED"] |
thumbnailUrl | Enlace a la miniatura más grande. | https://i.ytimg.com/… |
durationSeconds, viewCount | Duración en segundos; visualizaciones en ese momento. | 844, 62013820 |
category | Categoría de YouTube. | People & Blogs |
descriptionLinks | Todos los enlaces de la descripción, como text y url. | [{"text": "ted.com", …}] |
isShort, isUnlisted, isFamilySafe, isMembersOnly, isPaid | Marcas sí/no tal como las pone YouTube. | false |
availableCountries, blockedCountries | Códigos de los países donde el video se puede o no se puede ver. | [] |
| Fechas | ||
publishedAt, uploadedAt | Momento exacto de publicación y de subida. | 2016-04-06T09:59:35-07:00 |
publishedDateText | La fecha tal como YouTube la imprime bajo el video. | Apr 6, 2016 |
publishedText | La antigüedad tal como la muestran las listas de YouTube. | 2 hours ago |
| Directos | ||
isLive, isLiveNow, liveViewers | Contenido en directo; en emisión ahora; personas viéndolo ahora. | false |
liveStartedAt, liveEndedAt | Cuándo empezó y terminó la emisión. | null |
| Reacciones | ||
likeCount | Número exacto de «me gusta». | 2054977 |
commentCount, commentCountText | Número de comentarios, y tal como lo imprime YouTube. | 79650 |
commentsDisabled | true cuando los comentarios están desactivados. | false |
comments | Comentarios principales: id, text, author, likes, likesText, replyCount, publishedText, isPinned, isHearted, authorIsChannelOwner. | mira el ejemplo |
| Dentro del video | ||
chapters, chaptersAreAuto | Capítulos con title, start, startText; si los hizo YouTube. | mira el ejemplo |
mostReplayed | Los momentos que más vuelven a ver los espectadores: start, end, intensity (una puntuación relativa de 0 a 1). | mira el ejemplo |
music, musicTracks | Canción, artista y álbum cuando YouTube los acredita. | null |
aiSummary | El resumen de IA de YouTube, cuando el video lo tiene. | null |
relatedVideos | Hasta 10 videos que YouTube sugiere a continuación. | [{"videoId": "…", …}] |
| Canal | ||
channelName, channelId | Nombre e identificador del canal. | TED, UCAuUUnT6oDeKwE6v1NGQxug |
channelHandle, channelUrl | El @handle y el enlace. | @TED |
channelSubscribers, channelSubscribersText | Suscriptores, redondeados por YouTube, y tal como se imprimen. | 27900000, 27.9M subscribers |
channelVerified, channelAvatar | Insignia de verificación; enlace a la foto de perfil. | true |
| Dónde se encontró (ejecuciones normales) | ||
source, sourceType, sourceTitle | El canal, la lista o la búsqueda de donde vino el video. | https://www.youtube.com/@TED, channel, TED |
positionInSource | Su puesto en esa lista, empezando en 1. | 1 |
Ejemplo de salida: una respuesta correcta y una respuesta no_captions
Una respuesta a ?url=arj7oStGLkU&details=true&comments=1, acortada. Valores reales del 8 de octubre de 2026; scrapedAt y seconds son ilustrativos.
{"videoId": "arj7oStGLkU","url": "https://www.youtube.com/watch?v=arj7oStGLkU","status": "success","message": "","title": "Inside the Mind of a Master Procrastinator | Tim Urban | TED","channelName": "TED","channelId": "UCAuUUnT6oDeKwE6v1NGQxug","channelHandle": "@TED","channelSubscribers": 27900000,"channelSubscribersText": "27.9M subscribers","channelVerified": true,"durationSeconds": 844,"viewCount": 62013820,"publishedAt": "2016-04-06T09:59:35-07:00","category": "People & Blogs","likeCount": 2054977,"commentCount": 79650,"language": "en","languageName": "English","isAutoGenerated": false,"segmentCount": 315,"wordCount": 2277,"charCount": 12671,"text": "So in college, I was a government major, which means I had to write a lot of papers. …","chapters": [{ "title": "My procrastination journey", "start": 0, "startText": "0:00" },{ "title": "The procrastinator's brain", "start": 176, "startText": "2:56" },{ "title": "The monkey and the playground", "start": 249, "startText": "4:09" },{ "title": "The role of the panic monster", "start": 436, "startText": "7:16" },{ "title": "Two types of procrastination", "start": 599, "startText": "9:59" },{ "title": "The life calendar", "start": 756, "startText": "12:36" }],"chaptersAreAuto": true,"mostReplayed": [{ "start": 481.08, "end": 489.52, "intensity": 1 },{ "start": 16.88, "end": 25.32, "intensity": 0.951 }],"comments": [{"text": "He procrastinated in creating a Ted talk about procrastination. Ted definitely picked the right man for the job.","author": "@SWIFTzTrigger","likes": 3200,"likesText": "3.2K","replyCount": 2,"publishedText": "7 years ago"}],"detailsMissing": [],"input": "arj7oStGLkU","scrapedAt": "2026-10-08T09:00:00+00:00","charged": true,"seconds": 0.84}
Una respuesta a ?url=<video> para un video sin subtítulos, sin details=true. El identificador y el título son marcadores; los demás valores son los que lleva una respuesta así. Es gratis:
{"videoId": "<11-character ID>","url": "https://www.youtube.com/watch?v=<11-character ID>","status": "no_captions","message": "The video has no captions, neither uploaded nor auto-generated.","title": "<title of the video>","language": null,"availableLanguages": [],"wordCount": 0,"charged": false}
Con details=true, la misma respuesta traería los datos del video y se cobraría.
Casos de uso
- Haz que un chatbot responda preguntas sobre cualquier video de YouTube que pegue un cliente, sin pausas en la conversación.
- Dale a un asistente de voz las palabras de un video lo bastante rápido para leer un resumen mientras la persona sigue al teléfono.
- Añade un botón «resumir este video» a una extensión del navegador o a una aplicación, con tu propio servidor guardando el token.
- Equipa a tu agente de IA con una herramienta de transcripción de menos de un segundo para investigación, soporte o ventas.
- Muestra los capítulos, los «me gusta» y los comentarios principales de un video junto a su transcripción en un panel en vivo.
- Usa el mismo Actor por lotes para canales, listas y búsquedas, con solo videos nuevos de forma programada.
Ejemplos de entrada
Dos puertas al mismo Actor
- La dirección siempre encendida (Standby). Le envías una petición, una pregunta enviada por internet, y la respuesta vuelve directamente a quien preguntó. Un video por petición.
- El botón Start. Inicia una ejecución que procesa un lote (videos, canales enteros, listas, búsquedas) y deja los resultados en una tabla que puedes descargar. Cuesta lo mismo por resultado. Primero tiene que arrancar, así que es para trabajos en los que nadie espera.
Todo lo que puede hacer este Actor está disponible con el botón Start. La dirección hace la parte urgente: un video, ahora.
Parámetros de la dirección siempre encendida
Dirección base: https://nokia2k--youtube-transcript-instant-api.apify.actor. Inicio de sesión: cabecera Authorization: Bearer <YOUR_APIFY_TOKEN>, o ?token=<YOUR_APIFY_TOKEN>. Peticiones: GET /?url=<enlace del video o identificador de 11 caracteres>, o POST / con un cuerpo JSON que usa los mismos campos que el formulario de entrada, para un video.
| Parámetro | Qué hace | Ejemplo |
|---|---|---|
url (también video, v, id) | El video: un enlace o el identificador de 11 caracteres. Obligatorio. | url=arj7oStGLkU |
language (también lang) | Código o nombre de idioma. Varios, separados por comas, se prueban en orden. Sin él recibes el idioma original del video. | language=es,en |
translate | La traducción automática de YouTube a este idioma cuando el video no tiene subtítulos en él. | translate=es |
format | text, timestampedText, srt, vtt o markdown: la respuesta es el texto a secas en ese formato. Sin él, la respuesta es la fila JSON. | format=srt |
details=true | Añade todo lo que YouTube muestra del video y de su canal. | details=true |
comments=<número> | Añade los comentarios principales, hasta 100. Necesita details=true. | comments=20 |
Otros campos del formulario se pueden enviar con su propio nombre, por ejemplo captionType=manual o mergeSegmentsSeconds=60. Las dos opciones de archivos, saveFiles y combinedFile, son de las ejecuciones normales.
Un video en la dirección, en texto plano
curl -s "https://nokia2k--youtube-transcript-instant-api.apify.actor/?url=arj7oStGLkU&format=text" \-H "Authorization: Bearer <YOUR_APIFY_TOKEN>"
Un video con datos y cinco comentarios, en JSON
curl -s "https://nokia2k--youtube-transcript-instant-api.apify.actor/?url=arj7oStGLkU&details=true&comments=5" \-H "Authorization: Bearer <YOUR_APIFY_TOKEN>"
Primero español, o traducido al español, en SRT
curl -s "https://nokia2k--youtube-transcript-instant-api.apify.actor/?url=arj7oStGLkU&language=es,en&translate=es&format=srt" \-H "Authorization: Bearer <YOUR_APIFY_TOKEN>"
POST con un cuerpo JSON, un video
curl -s -X POST "https://nokia2k--youtube-transcript-instant-api.apify.actor/" \-H "Authorization: Bearer <YOUR_APIFY_TOKEN>" \-H "Content-Type: application/json" \-d '{"urls": ["https://www.youtube.com/watch?v=arj7oStGLkU"], "languages": ["es", "en"], "includeDetails": true, "maxComments": 5}'
Un lote con el botón Start: videos con datos
{"urls": ["https://www.youtube.com/watch?v=arj7oStGLkU","https://youtu.be/jNQXAC9IVRw"],"outputFormats": ["text"],"includeDetails": true,"maxComments": 5}
Los 20 videos más nuevos de un canal, primero en español, en Markdown
{"urls": ["https://www.youtube.com/@TED"],"maxVideosPerSource": 20,"languages": ["es", "en"],"outputFormats": ["markdown"],"contentTypes": ["videos"]}
Un tema en lugar de enlaces, primero los más vistos de este mes
{"searchQueries": ["how to learn spanish"],"maxVideosPerSearch": 10,"searchUploadDate": "month","searchSortBy": "views"}
Solo los videos nuevos de un canal, para una programación
{"urls": ["https://www.youtube.com/@TED"],"maxVideosPerSource": 50,"onlyNewVideos": true,"stateKey": "ted-daily","outputFormats": ["text"]}
Todos los campos del formulario (ejecuciones normales)
Solo hace falta el primer campo o el de búsqueda. El resto tiene valores por defecto razonables.
| Campo del formulario | Nombre | Qué es y cuándo tocarlo | Ejemplo |
|---|---|---|---|
| 📺 Videos, channels or playlists | urls | Enlaces de YouTube, uno por línea. Un enlace de video da ese video; un enlace de canal o @nombre da los videos del canal, primero los más nuevos; un enlace de lista da sus videos. | https://www.youtube.com/@TED |
| 🔢 Videos per channel or playlist | maxVideosPerSource | «Videos por canal o lista»: cuántos tomar de cada uno. Por defecto 50, hasta 5000. Empieza con poco: cada fila cuesta. | 5 |
| 🌐 Transcript language | languages | «Idioma de la transcripción». Déjalo en "Original language" para recibir cada video en el idioma en que se habla. O elige idiomas por orden de preferencia: 70 en la lista, y se puede escribir cualquier otro código o nombre. | ["es", "en"] |
| 📄 Output formats | outputFormats | «Formatos de salida»: segments, text, timestampedText, srt, vtt, markdown. Varios cuestan lo mismo que uno. | ["text", "markdown"] |
| 📚 Also give me everything as one Markdown file | combinedFile | Guarda todas las transcripciones de la ejecución en un archivo, ALL_TRANSCRIPTS.md, para ChatGPT, Claude, NotebookLM o una base de conocimiento. Desactivado por defecto. | true |
| 💾 Also save subtitle files I can download | saveFiles | Guarda un archivo .srt, .vtt o .txt por video y añade enlaces de descarga en files. | true |
| 📊 Video and channel details | includeDetails | «Datos del video y del canal»: fecha exacta, «me gusta», número de comentarios, capítulos, hashtags, suscriptores del canal y más. Activado por defecto. | true |
| 💬 Top comments per video | maxComments | «Comentarios principales por video»: cuántos añadir a cada fila. Por defecto 0, hasta 100. | 20 |
| 🔎 What to search for | searchQueries | «Qué buscar»: lo que escribirías en el buscador de YouTube, una búsqueda por línea. | how to learn spanish |
| 🔢 Videos per search | maxVideosPerSearch | Cuántos de los primeros resultados tomar por búsqueda. Por defecto 10, hasta 500. | 5 |
| 📅 Uploaded | searchUploadDate | Filtro propio de YouTube: any, hour, today, week, month, year. | month |
| ⏱️ Length | searchDuration | Filtro propio de YouTube: any, short (menos de 4 minutos), medium (de 4 a 20), long (más de 20). | medium |
| ↕️ Order | searchSortBy | relevance es el orden de YouTube; date y views ordenan así los videos encontrados. | views |
| Only videos that have captions (recommended) | onlyWithCaptions | Pide a YouTube solo videos con subtítulos. Activado por defecto. | true |
| 📅 Only videos newer than | newerThan | Una fecha, o una antigüedad como 30 days. Para canales y listas. El corte es aproximado. | 6 months |
| Only new videos since the last run | onlyNewVideos | Para ejecuciones programadas: solo los videos no entregados antes para los mismos canales, listas y búsquedas. Desactivado por defecto. | true |
| Memory name | stateKey | «Nombre de la memoria». Opcional, con el campo anterior: el nombre de la lista de videos entregados. | ted-daily |
| 🎞️ Kinds of videos to take from a channel | contentTypes | Videos normales, Shorts, grabaciones de directos. Desmarca lo que no necesites. | ["videos"] |
| 🔁 Translate to | translateTo | La traducción automática de YouTube, que se usa cuando el video no tiene subtítulos en ese idioma. | es |
| If my language is missing, give me the original language | fallbackToAnyLanguage | Activado: recibes igualmente una transcripción, en el idioma original. Desactivado: esos videos se omiten. | false |
| Caption type | captionType | any (primero los de personas), manual (solo de personas), auto (solo automáticos). | manual |
| Merge caption lines into blocks | mergeSegmentsSeconds | Junta las líneas cortas en bloques de unos tantos segundos. 0 conserva las líneas originales. | 60 |
| Include video details | includeMetadata | Añade canal, duración, visualizaciones, descripción, etiquetas y miniatura. El título va siempre. | true |
Ejecútalo de forma programada y recibe solo los videos nuevos
La dirección siempre encendida responde un video por petición. Seguir canales, listas o búsquedas es trabajo de las ejecuciones normales programadas.
Cómo funciona «Only new videos since the last run»
- Activa Only new videos since the last run (
onlyNewVideos). Está desactivado por defecto y está pensado para ejecuciones programadas (las Schedules de Apify, «Programaciones»). - Cada ejecución entrega entonces solo los videos que no había entregado antes para los mismos canales, listas y búsquedas. Los videos ya entregados se dejan fuera antes de pedir nada, así que ni se piden ni se cobran.
- La primera ejecución entrega todo lo que encuentra y lo recuerda.
- Los enlaces de videos que pegas directamente se entregan siempre, nunca se dejan fuera. Se recuerdan, así que un canal o una búsqueda que los contenga más adelante no los vuelve a entregar.
Configúralo paso a paso
- Rellena el formulario: tus canales, listas o búsquedas y tus formatos. Marca Only new videos since the last run. Opcional: escribe un Memory name como
ted-daily. - Haz clic en Start una vez a mano. La primera ejecución entrega lo que encuentra y lo recuerda. Además deja el Actor listo para programarse: un Actor tiene que haberse ejecutado una vez antes de poder programarlo.
- Haz clic en Save as a new task («Guardar como tarea nueva»), arriba a la derecha en la página del Actor. Una tarea es un formulario guardado; aparece en Saved tasks («Tareas guardadas»).
- Abre Schedules en el menú de la izquierda y haz clic en Create new («Crear nueva»).
- En la tarjeta Schedule setup («Configuración de la programación») elige cada cuánto (una expresión cron como
@daily, o el constructor visual) y tu zona horaria. Next runs («Próximas ejecuciones») muestra las fechas siguientes. - En el desplegable Add («Añadir») elige tu tarea.
- Haz clic en Enable («Activar»). Las programaciones nuevas empiezan desactivadas.
Qué verás en las ejecuciones siguientes
- El registro y el mensaje final de la ejecución dicen cuántos videos se dejaron fuera, por ejemplo: "Skipped 37 videos already delivered in earlier runs (memory 'x')."
- Una ejecución sin nada nuevo termina con normalidad, sin filas: "No new videos since the last run: … Nothing was charged."
Nombre de la memoria: una lista o varias
- Vacío: la memoria se llama
auto-…según tu lista de canales, listas y búsquedas. El orden y las mayúsculas de las búsquedas no importan; cualquier otro cambio en la lista empieza una memoria nueva. - Con un nombre: eliges tú el registro. El mismo nombre mantiene una sola lista aunque cambien los enlaces; un nombre distinto mantiene una lista aparte.
- Se conservan las letras, las cifras y
-_.!'(); los demás caracteres se convierten en-.
Dónde se guarda la memoria y cómo empezar de cero
La memoria se guarda en tu propia cuenta de Apify: Storage («Almacenamiento») > Key-value stores («almacenes de archivos»), en el almacén llamado youtube-transcripts-memory. Cada memoria es un registro que guarda los identificadores de los 20 000 videos entregados más recientes y la hora de su última actualización. Borra el registro, o el almacén entero, y la siguiente ejecución empieza de cero y vuelve a entregarlo todo.
Conviene saber
- Se recuerdan: los videos entregados como
successono_captions, y toda fila que se cobró. Las filas gratuitas (blocked,error,age_restrictedsin datos) y un directo que sigue en marcha o no ha empezado se vuelven a intentar en la siguiente ejecución. - Nunca se cobra dos veces: una fila puede cobrarse por sus datos aunque su estado no sea
successnino_captions, por ejemplo un videoage_restrictedcuyos datos llegaron. Todo video cobrado queda recordado, así que una ejecución posterior con Only new videos since the last run no vuelve a cobrarlo. - Mantén las cantidades lo bastante altas. 🔢 Videos per channel or playlist y 🔢 Videos per search cuentan los videos que se miran en cada ejecución, antes de dejar fuera los conocidos.
- La memoria se guarda al final de la ejecución, también cuando la ejecución se detiene antes de su tiempo máximo o en el tope de gasto (entonces, solo con los videos que se procesaron). Tras un traslado de servidor, la ejecución continúa y guarda al final; nada se cuenta ni se cobra dos veces.
- Si la memoria no se puede leer, la ejecución anota un aviso y entrega todos los videos como una ejecución normal. Si no se puede guardar, los resultados se entregan igualmente, y la siguiente ejecución puede repetir algunos videos.
- Dos ejecuciones con la misma memoria al mismo tiempo pueden entregar las dos el mismo video nuevo. La memoria guarda los videos de ambas.
Envía los videos nuevos a Google Sheets o Slack
- n8n: añade el nodo Apify Trigger (Resource to Watch: Task, tu tarea; Event Type: Succeeded). Después un nodo Apify con Resource Dataset, Get Items y el
defaultDatasetIdde la ejecución como Dataset ID (sube Limit: empieza en 50). Después un nodo de Google Sheets que añada una fila por elemento (title,url,publishedAt,text), o un nodo de Slack que publiquetitleyurl. Un n8n en tu propio servidor necesita unaWEBHOOK_URLpública para que Apify pueda llegar a él. - Make: empieza con Watch Actor Runs («Vigilar ejecuciones del Actor»; se dispara cuando termina una ejecución), después Get Dataset Items y después un módulo de Google Sheets (la guía de Apify usa "Bulk Add Rows") o de Slack.
- Cualquier otra herramienta: en la pestaña Integrations («Integraciones») de la tarea añade un webhook («aviso automático a otra aplicación») para el evento
ACTOR.RUN.SUCCEEDED. Apify envía un POST a tu dirección; el identificador del dataset está enresource.defaultDatasetId. El receptor debe responder en menos de 2 minutos, y un webhook puede llegar dos veces.
Una ejecución sin videos nuevos termina igualmente como Succeeded, con un dataset vacío: esa vez tu hoja simplemente no recibe filas nuevas.
Usa la API de transcripciones de YouTube en tiempo real desde agentes de IA (MCP)
MCP es el estándar que permite a un asistente de IA usar herramientas externas. La dirección MCP de Apify con este Actor como herramienta es:
https://mcp.apify.com?tools=nokia2k/youtube-transcript-instant-api
Ten en cuenta: mediante MCP el asistente inicia una ejecución normal y la espera (hasta 45 segundos), así que este camino tiene la espera de arranque. Si tu propio agente debe responder en menos de un segundo, dale en su código una herramienta que llame directamente a la dirección siempre encendida (mira «Integraciones»).
El inicio de sesión es OAuth: en la primera conexión se abre una ventana del navegador y no se guarda ningún token en la configuración. También sirve una cabecera Authorization: Bearer <YOUR_APIFY_TOKEN>.
Claude.ai y Claude Desktop
- Abre Connectors («Conectores») en Claude (Settings > Connectors, o Customize > Connectors según tu versión).
- Elige Add custom connector («Añadir conector personalizado»).
- Rellena Name («Nombre») y Remote MCP server URL («URL del servidor MCP remoto») con la dirección de arriba, haz clic en Continue («Continuar») y luego en Add («Añadir»).
- Inicia sesión en Apify en la ventana del navegador que se abre.
- En un chat, haz clic en +, luego en Connectors, y actívalo.
En el plan gratuito de Claude puedes añadir un conector personalizado. En los planes Team y Enterprise lo añade un propietario («Owner») para toda la organización.
Claude Desktop con un servidor local
claude_desktop_config.json, necesita Node.js:
{"mcpServers": {"youtube-instant": {"command": "npx","args": ["-y", "@apify/actors-mcp-server", "--tools", "nokia2k/youtube-transcript-instant-api"],"env": {"APIFY_TOKEN": "<YOUR_APIFY_TOKEN>"}}}}
Cursor
.cursor/mcp.json en tu proyecto, o ~/.cursor/mcp.json:
{"mcpServers": {"youtube-instant": {"url": "https://mcp.apify.com?tools=nokia2k/youtube-transcript-instant-api"}}}
Con un token en lugar de OAuth, añade "headers": { "Authorization": "Bearer <YOUR_APIFY_TOKEN>" } junto a "url".
VS Code
Necesita GitHub Copilot. Abre la paleta de comandos, ejecuta MCP: Open User Configuration («abrir la configuración de usuario de MCP») y añade:
{"servers": {"youtube-instant": {"type": "http","url": "https://mcp.apify.com?tools=nokia2k/youtube-transcript-instant-api"}}}
Claude Code y ChatGPT
claude mcp add --transport http youtube-instant \"https://mcp.apify.com?tools=nokia2k/youtube-transcript-instant-api" \--header "Authorization: Bearer $APIFY_TOKEN"
ChatGPT: necesita el modo Developer («modo de desarrollador»). Ve a Settings > Apps & Connectors > Create («Crear»), rellena Name, Description («Descripción») y MCP Server URL, deja Authentication («Autenticación») en OAuth y haz clic en Create. En un chat, haz clic en +, luego en More («Más»), y elige el conector.
Ejemplos de peticiones
- «Consigue la transcripción de https://www.youtube.com/watch?v=arj7oStGLkU y responde: ¿qué es el "panic monster"?»
- «Trae este video con sus capítulos y dime qué capítulo trata del calendario de la vida y en qué minuto: https://youtu.be/arj7oStGLkU»
- «Consigue la transcripción y los 5 comentarios principales de este video y redacta una respuesta breve al comentario con más "me gusta": [enlace]»
Integraciones: n8n, Make, Zapier, Python, JavaScript y LangChain
Qué son un token y una cabecera, y cómo guardar el token en secreto
Un token es una contraseña secreta larga que le dice a Apify qué cuenta pregunta y qué cuenta paga. Está en la consola, en Settings y luego API & Integrations; aquí se escribe <YOUR_APIFY_TOKEN>. Una cabecera es una línea con etiqueta que viaja con una petición pero fuera de la dirección, como el remitente escrito en el sobre en lugar de dentro de la carta.
Puedes entregar el token de dos formas:
- En una cabecera (la mejor forma): la cabecera se llama
Authorizationy su valor es la palabraBearer, un espacio y tu token. - En la dirección: añade
token=<YOUR_APIFY_TOKEN>como parámetro. Es la única forma que funciona cuando escribes una dirección en un navegador.
Cómo guardarlo en secreto:
- Prefiere la cabecera. Una dirección se guarda en el historial del navegador y acaba copiada en chats, capturas de pantalla y registros. Una cabecera no.
- En n8n, Make o Zapier, guarda el token en el apartado propio de la herramienta para credenciales o conexiones, no en un campo de texto de un flujo que puedas compartir o exportar.
- No pongas nunca el token en algo que se ejecuta en el dispositivo de tu visitante: una página web, una extensión del navegador, una aplicación móvil. Cualquiera puede leerlo ahí. Deja que tu propio servidor guarde el token y llame a la dirección.
- No lo pegues en foros, capturas de pantalla ni en la pestaña Issues («Incidencias»).
- Si se filtra, vuelve a Settings, API & Integrations. Un token se puede rotar (sustituir por uno nuevo), se le puede poner fecha de caducidad y se puede limitar con el interruptor "Limit token permissions" («Limitar los permisos del token»).
n8n (nodo HTTP Request, la dirección siempre encendida)
En n8n una automatización es un «flujo de trabajo» y cada paso, un «nodo».
- En tu flujo añade el nodo HTTP Request.
- Verás: su panel de ajustes.
- Pon Method («Método») en GET.
- En URL pega
https://nokia2k--youtube-transcript-instant-api.apify.actor/ - En Authentication («Autenticación») elige el tipo de credencial genérico y luego Header auth. Crea una credencial con Name
Authorizationy ValueBearer <YOUR_APIFY_TOKEN>. Así n8n mantiene tu token fuera del propio flujo. - Activa Send Query Parameters («Enviar parámetros de consulta»). Añade un parámetro llamado
urly dale el enlace de YouTube de tu nodo anterior. Añade otro llamadoformatcon el valortextsi solo quieres las palabras. - Haz clic en Add Option («Añadir opción»), elige Timeout («Tiempo máximo») y escribe
60000. Son 60 segundos en milisegundos, para que el despertar tras una pausa nunca corte la petición. - Ejecuta el nodo.
- Verás: con
format, la transcripción como texto. Sin él, un elemento con campos comostatus,title,textyseconds.
- Verás: con
- Conecta el nodo siguiente. Cuando leas los campos, comprueba que
statusseasuccessantes de usartext.
Para enviar más opciones, cambia Method a POST, activa Send Body («Enviar cuerpo»), pon Body Content Type en JSON y Specify Body en Using JSON, y pega el ejemplo POST de «Ejemplos de entrada».
Para lotes, n8n tiene también un nodo Apify, que instalas desde el panel de nodos buscando Apify: Resource («Recurso») Actor, Operation («Operación») Run an Actor and Get Dataset («Ejecutar un Actor y obtener los resultados»). Elige este Actor y pega la entrada en Input JSON. Eso inicia una ejecución normal.
Make (módulo HTTP)
En Make una automatización es un «escenario» y cada paso, un «módulo». Aquí no se citan las pantallas propias de Make, así que busca estas cosas por lo que hacen.
- Añade la aplicación HTTP de Make a tu escenario y elige el módulo que envía una petición.
- En el campo de la dirección, pega
https://nokia2k--youtube-transcript-instant-api.apify.actor/ - Elige GET como método.
- Añade una cabecera. Nombre:
Authorization. Valor:Bearer <YOUR_APIFY_TOKEN>. - Añade un parámetro de consulta llamado
urly asígnale el enlace de YouTube de tu módulo anterior. Añadeformatcon el valortextsi solo quieres las palabras. - Ejecuta el escenario una vez.
- Verás: el código de estado 200 y la transcripción en la salida del módulo.
- Si no pusiste
format, activa la opción del módulo que lee la respuesta como datos. Así podrás asignartitle,texty los demás campos en el módulo siguiente.
Para lotes, la aplicación de Apify en Make tiene Run an Actor («Ejecutar un Actor»; pon Run synchronously, «Ejecutar de forma síncrona», en Yes) seguido de Get Dataset Items («Obtener los resultados»). Para ejecuciones de más de unos 2 minutos, usa Watch Actor Runs («Vigilar ejecuciones del Actor») y después Get Dataset Items.
Zapier
- Para la dirección siempre encendida: usa un paso de Zapier que pueda enviar una petición web y rellena lo mismo que en Make: la dirección, el método GET, la cabecera
Authorizationy el parámetrourl. - Para un lote: añade la aplicación de Apify y elige la acción Run Actor. Haz clic en Allow Access («Permitir acceso») para conectar tu cuenta, elige este Actor y dale la entrada.
- Un Run Actor síncrono tiene un límite estricto de 30 segundos. Para lo que pueda tardar más, usa dos Zaps: el Zap A termina con Run Actor (asíncrono); el Zap B empieza con Finished Actor Run («Ejecución del Actor terminada») y sigue con Fetch Dataset Items («Traer los resultados»).
Python (requests, la dirección siempre encendida)
import requestsADDRESS = "https://nokia2k--youtube-transcript-instant-api.apify.actor/"HEADERS = {"Authorization": "Bearer <YOUR_APIFY_TOKEN>"}response = requests.get(ADDRESS,params={"url": "https://www.youtube.com/watch?v=arj7oStGLkU","details": "true","comments": 5,},headers=HEADERS,timeout=60,)row = response.json() # 200, 400 and 402 all answer with JSON hereif response.status_code == 200 and row["status"] == "success":print(row["title"], "-", row["wordCount"], "words in", row["seconds"], "s")print(row["text"][:200])else:print(response.status_code, row["status"], row["message"])
JavaScript (fetch, la dirección siempre encendida)
Ejecútalo en tu servidor, no en una página web, para que el token siga siendo privado.
const address = new URL('https://nokia2k--youtube-transcript-instant-api.apify.actor/');address.searchParams.set('url', 'https://www.youtube.com/watch?v=arj7oStGLkU');address.searchParams.set('format', 'srt');const response = await fetch(address, {headers: { Authorization: 'Bearer <YOUR_APIFY_TOKEN>' },});const type = response.headers.get('content-type') || '';if (type.includes('json')) {const row = await response.json(); // no transcript, or a problemconsole.log(response.status, row.status, row.message);} else {console.log(await response.text()); // the subtitle file}
Ejecuciones normales con la API de Apify: curl y Python
Un lote pasa por la API propia de Apify. Esta llamada inicia una ejecución, espera y devuelve las filas. Tiene un límite de 300 segundos; una ejecución más larga responde HTTP 408, así que inicia los trabajos grandes con POST /v2/acts/nokia2k~youtube-transcript-instant-api/runs y lee el dataset cuando la ejecución haya terminado.
curl -X POST "https://api.apify.com/v2/acts/nokia2k~youtube-transcript-instant-api/run-sync-get-dataset-items?maxTotalChargeUsd=5" \-H "Authorization: Bearer <YOUR_APIFY_TOKEN>" \-H "Content-Type: application/json" \-d '{"urls": ["https://www.youtube.com/@TED"], "maxVideosPerSource": 5, "outputFormats": ["text"]}'
Con pip install apify-client (versión 3, Python 3.11 o posterior):
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("nokia2k/youtube-transcript-instant-api").call(run_input={"urls": ["https://www.youtube.com/@TED"],"maxVideosPerSource": 5,"outputFormats": ["text"],},)for row in client.dataset(run.default_dataset_id).iterate_items():print(row["status"], row