API reference · v1

Every YouTube video, over one REST call.

Eight endpoints cover transcripts, video and channel search, channel uploads, RSS latest and playlists. Bearer auth, JSON out, credits charged only on a 200.

Base URL
https://api.localhost
Auth
Authorization: Bearer sk_…
Rate limit
300 requests / minute
Authentication

One bearer token, every request.

Send your key in the Authorization header. Keys are prefixed sk_, never expire unless revoked, and work for both the REST API and the MCP server.

Authorization
curl -X GET "https://api.localhost/youtube/transcript?video_url=dQw4w9WgXcQ" \
-H "Authorization: Bearer sk_your_key"
Keys are created and revoked in the API keys dashboard.
The same key authenticates the REST API and the MCP server.
Store keys in environment variables, never in the client.
Use separate keys per environment and rotate them regularly.
Transcripts

YouTube transcript

GET/youtube/transcript
1 credit

Pull the caption track from any YouTube video. Returns structured segments or plain text, with timestamps on or off, in the language you ask for.

Parameters
NameTypeNeedDescriptionDefault
video_urlstringRequiredFull YouTube URL, youtu.be short URL, or the bare 11-character video ID. Pattern ^([a-zA-Z0-9_-]{11}|https?://.*)$
formatstringOptionaljson returns structured segments; text returns the transcript as one string.json
include_timestampbooleanOptionalInclude start and duration on each segment, or [123.45s] prefixes in text format.true
send_metadatabooleanOptionalAdd title, author_name, author_url and thumbnail_url to the response.false
languagestringOptionalComma-separated priority list of up to 10 codes, tried left to right, for example de,en,asr.en, else first available
Codes are case-insensitive and region is ignored: en-GB and en-US both resolve to en. asr requests auto-generated captions, and asr-hi a specific auto-generated language. The language field in a 200 is the resolved code.
Every 200 also carries length_seconds and lengthText, independent of send_metadata. Both are null for live streams.
The response header X-Cache-Status is HIT, PARTIAL-HIT or MISS. Cached responses still cost a credit.
Request
curl -X GET "https://api.localhost/youtube/transcript?video_url=dQw4w9WgXcQ&language=de,en,asr" \
-H "Authorization: Bearer YOUR_API_KEY"
Response
JSON, timestamps
{
"video_id": "dQw4w9WgXcQ",
"language": "en",
"transcript": [
{ "text": "Never gonna give you up", "start": 0.0, "duration": 4.12 },
{ "text": "Never gonna let you down", "start": 4.12, "duration": 3.85 }
],
"metadata": {
"title": "Rick Astley - Never Gonna Give You Up",
"author_name": "RickAstleyVEVO",
"author_url": "https://www.youtube.com/@RickAstley",
"thumbnail_url": "https://i.ytimg.com/vi/dQw4w9WgXcQ/hqdefault.jpg"
},
"length_seconds": 213,
"lengthText": "3:33"
}

Video info

GET/youtube/info
Free

Metadata plus the transcript languages a video offers, so you can pick a language before spending a transcript credit.

Parameters
NameTypeNeedDescription
video_urlstringRequiredFull YouTube URL, short URL, or the bare 11-character video ID.
Each available_languages code can be passed straight to the transcript endpoint’s language parameter: en for creator captions, asr-en for auto-generated English.
Free, but the request still needs a valid key and at least one active credit. Returns 404 when the video does not exist or has no captions.
Request
curl -X GET "https://api.localhost/youtube/info?video_url=dQw4w9WgXcQ" \
-H "Authorization: Bearer YOUR_API_KEY"
JSON
{
"video_id": "dQw4w9WgXcQ",
"metadata": {
"title": "Rick Astley - Never Gonna Give You Up",
"author_name": "RickAstleyVEVO",
"author_url": "https://www.youtube.com/@RickAstley",
"thumbnail_url": "https://i.ytimg.com/vi/dQw4w9WgXcQ/hqdefault.jpg"
},
"available_languages": [
{ "code": "en", "name": "English" },
{ "code": "asr-en", "name": "English (auto-generated)" }
]
}
Channels

Resolve channel

GET/youtube/channel/resolve
Free

Resolve any channel reference, an @handle, channel URL, or UC… ID, to a canonical UC… channel ID.

Parameters
NameTypeNeedDescription
inputstringRequired@handle, channel URL, or UC… ID, 1–200 characters.
Fast path: if input is already a valid UC… channel ID (24 characters starting with UC) the API returns immediately, with no external lookup.
Free, but the request still needs a valid key and at least one active credit.
Request
curl -X GET "https://api.localhost/youtube/channel/resolve?input=@MrBeast" \
-H "Authorization: Bearer YOUR_API_KEY"
JSON
{
"channel_id": "UCX6OQ3DkcsbYNE6H8uQQuVA",
"resolved_from": "@MrBeast"
}

Channel videos

GET/youtube/channel/videos
1 credit / page

List every video uploaded to a channel, paginated at roughly 100 per page, with the uploads playlist metadata alongside.

Parameters
NameTypeNeedDescription
channelstringConditional@handle, channel URL, or UC… channel ID. First page only.
continuationstringConditionalContinuation token from the previous response.
Provide exactly one of channel or continuation. Repeat until has_more is false or continuation_token is null; each page costs 1 credit.
The legacy channel_id parameter still works but is no longer documented.
Request
# First page, by handle or by URL
curl -X GET "https://api.localhost/youtube/channel/videos?channel=@MrBeast" \
-H "Authorization: Bearer YOUR_API_KEY"
# Next page
curl -X GET "https://api.localhost/youtube/channel/videos?continuation=4qmFsgKlARIYVVV1QVhGa2dz..." \
-H "Authorization: Bearer YOUR_API_KEY"
JSON
{
"results": [
{
"videoId": "abc123xyz00",
"title": "Latest Video",
"channelId": "UCX6OQ3DkcsbYNE6H8uQQuVA",
"channelTitle": "TED",
"channelHandle": "@MrBeast",
"lengthText": "15:22",
"viewCountText": "3.2M views 2 weeks ago",
"thumbnails": [],
"index": "0"
}
],
"playlist_info": {
"title": "Uploads from TED",
"numVideos": "5200",
"description": "",
"ownerName": "TED",
"viewCount": null
},
"continuation_token": "4qmFsgKlARIYVVV1QVhGa2dz...",
"has_more": true
}

Channel latest, via RSS

GET/youtube/channel/latest
Free

The 15 most recent videos from a channel, read from YouTube’s RSS feed. Returns exact publish timestamps and view counts.

Parameters
NameTypeNeedDescription
channelstringRequired@handle, channel URL, or UC… channel ID.
Free: no credits charged, so it is the cheap way to poll a channel before spending credits on transcripts.
The legacy channel_id parameter still works but is no longer documented.
Request
curl -X GET "https://api.localhost/youtube/channel/latest?channel=@MrBeast" \
-H "Authorization: Bearer YOUR_API_KEY"
JSON
{
"channel": {
"channelId": "UCX6OQ3DkcsbYNE6H8uQQuVA",
"title": "TED",
"author": "TED",
"url": "https://www.youtube.com/channel/UCX6OQ3DkcsbYNE6H8uQQuVA",
"published": "2006-12-18T00:00:00Z"
},
"results": [
{
"videoId": "abc123xyz00",
"title": "Latest Video Title",
"channelId": "UCX6OQ3DkcsbYNE6H8uQQuVA",
"author": "TED",
"published": "2026-01-30T16:00:00Z",
"updated": "2026-01-31T02:00:00Z",
"link": "https://www.youtube.com/watch?v=abc123xyz00",
"description": "Full video description...",
"thumbnail": { "url": "https://i1.ytimg.com/vi/abc123xyz00/hqdefault.jpg", "width": "480", "height": "360" },
"viewCount": "2287630",
"starRating": { "average": "4.92", "count": "45000", "min": "1", "max": "5" }
}
],
"result_count": 15
}
Playlists

Playlist videos

GET/youtube/playlist/videos
1 credit / page

List the videos in a playlist, paginated at roughly 100 per page. Accepts a playlist URL or a bare playlist ID.

Parameters
NameTypeNeedDescription
playliststringConditionalPlaylist URL or ID starting with PL, UU, LL, FL or OL. First page only.
continuationstringConditionalContinuation token from the previous response.
Provide exactly one of playlist or continuation. Pagination follows the same flow as channel videos.
The legacy playlist_id parameter still works but is no longer documented.
Request
# First page
curl -X GET "https://api.localhost/youtube/playlist/videos?playlist=PLrAXtmErZgOeiKm4sgNOknGvNjby9efdf" \
-H "Authorization: Bearer YOUR_API_KEY"
# Next page
curl -X GET "https://api.localhost/youtube/playlist/videos?continuation=4qmFsgKlARIYVVV1QVhGa2dz..." \
-H "Authorization: Bearer YOUR_API_KEY"
JSON
{
"results": [
{
"videoId": "abc123xyz00",
"title": "Playlist Video",
"channelId": "UCX6OQ3DkcsbYNE6H8uQQuVA",
"channelTitle": "TED",
"channelHandle": "@MrBeast",
"lengthText": "10:05",
"viewCountText": "1.5M views 6 months ago",
"thumbnails": [],
"index": "0"
}
],
"playlist_info": {
"title": "Best Tech of 2025",
"numVideos": "47",
"description": "My picks for the best tech this year",
"ownerName": "TED",
"viewCount": "5000000"
},
"continuation_token": "4qmFsgKlARIYVVV1QVhGa2dz...",
"has_more": true
}
Credits and billing

You pay for answers, not attempts.

Credits are deducted in real time on a successful response. Cached hits still cost a credit; failures and rate limits cost nothing. When the balance runs out the API returns 402 Payment Required.

EndpointNoteCost
/youtube/transcriptCharged only on a 200 response1 credit
/youtube/infoRequires auth and at least 1 active creditFree
/youtube/searchPaginated: each page costs 1 credit1 / page
/youtube/channel/resolveRequires auth and at least 1 active creditFree
/youtube/channel/searchPaginated: each page costs 1 credit1 / page
/youtube/channel/videosPaginated: each page costs 1 credit1 / page
/youtube/channel/latestRequires auth and at least 1 active creditFree
/youtube/playlist/videosPaginated: each page costs 1 credit1 / page
Successful requests (200) cost 1 credit on paid endpoints.
Cached responses (200) still cost 1 credit.
Free endpoints cost 0 credits, but need 1 active credit on the account.
Failed requests (4xx, 5xx) cost nothing.
Rate-limited requests (429) cost nothing.
Rate limits

300 requests per minute, per key.

Limits are shared across REST and MCP usage. Every response carries the current window in its headers, so a client can pace itself without guessing.

HeaderDescription
X-RateLimit-LimitTotal allowed requests in the window
X-RateLimit-RemainingRequests left in the window
X-RateLimit-ResetUTC epoch seconds when the window resets
Retry-AfterSeconds until you can retry, sent on 429 only
429 Too Many Requests
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1735689600
Retry-After: 12
{
"detail": "Rate limit exceeded, wait for Retry-After, then retry."
}
Errors

Standard codes, and what to do next.

StatusMeaningActionRetry
200SuccessResponse returned, 1 credit charged on paid endpointsN/A
400Bad requestCheck your request parametersNo
401UnauthorizedInvalid or missing API key; carries WWW-Authenticate: BearerNo
402Payment requiredNo credits remaining: top up or choose a planNo
404Not foundVideo missing, or no transcript in the requested languagesNo
408TimeoutTemporary failure such as bot detection, retry in 1–5sYes
422Validation errorInvalid YouTube URL or IDNo
429Too many requestsRate limit exceeded, wait for Retry-AfterYes
500Server errorContact support if it persistsMaybe
503Service unavailableTemporarily down, retry in 1–5sYes
Example error
404 · language list missed
{
"detail": "No transcript available for the requested languages: en, de",
"code": "no_transcript_for_requested_languages",
"available_languages": [
{ "code": "hi", "name": "Hindi" },
{ "code": "asr-hi", "name": "Hindi (auto-generated)" }
]
}
Code examples

A working call, in three languages.

Quickstart
cURL
# Basic request
curl -X GET "https://api.localhost/youtube/transcript?video_url=dQw4w9WgXcQ" \
-H "Authorization: Bearer YOUR_API_KEY"
# Every parameter
curl -X GET "https://api.localhost/youtube/transcript?video_url=dQw4w9WgXcQ&format=json&include_timestamp=true&send_metadata=true&language=de,en,asr" \
-H "Authorization: Bearer YOUR_API_KEY"
# Plain text, no timestamps
curl -X GET "https://api.localhost/youtube/transcript?video_url=dQw4w9WgXcQ&format=text&include_timestamp=false" \
-H "Authorization: Bearer YOUR_API_KEY"
MCP tools

The same endpoints, as agent tools.

Point any MCP client at https://mcp.localhost. Claude and ChatGPT authorize over OAuth 2.1; OpenAI Agent Builder and custom clients send the same sk_ key as a bearer token.

mcp.json
{
"mcpServers": {
"transcriptapi": {
"url": "https://mcp.localhost",
"apiKey": "sk_your_api_key_here"
}
}
}
get_youtube_transcript

Fetch a video transcript as markdown or JSON

1 credit
search_youtube

Search YouTube for videos or channels

1 / page
get_channel_latest_videos

Latest ~15 videos from a channel, via RSS

Free
search_channel_videos

Search within one channel

1 / page
list_channel_videos

Paginated list of all channel uploads

1 / page
list_playlist_videos

Paginated list of playlist videos

1 / page
Claude

Dynamic client registration, add the URL and authorize once.

OAuth
ChatGPT

Static registration with a client ID and secret from the dashboard.

OAuth
OpenAI Agent Builder

API key authentication; OAuth is not supported there yet.

API key
Best practices

Running this in production.

Back off, then give up

Retry only 408, 429 and 503, two or three times with exponential backoff, honouring Retry-After.

Cache transcripts

Transcripts rarely change, and a cached response still costs a credit. Store them and invalidate metadata separately.

Watch the headers

Queue requests as X-RateLimit-Remaining falls rather than discovering the limit at 429.

Handle 402 in the UI

Read detail.action_label and detail.action_url and send the user straight to top-up.