API ReferenceREF · YTS-API · v1

Documentation

One REST API, CLI, and MCP server over the same four operations — search, metadata, transcripts, and summaries. Every example below is copy-paste runnable against production.

Base URL
https://api.youtubesearch.dev
Auth
Authorization: Bearer ys_live_… — required on every call
Formats
JSON · Markdown · plain text
Interfaces
REST · MCP · CLI
On this page
01 / 10Quickstart

First call in under a minute

Every call needs a free API key — 1,000 credits a month, no card.

Get a free key, then pass it as a bearer token:

1 · your first call
curl -s "https://api.youtubesearch.dev/v1/videos/zjkBMFhNj_g/summary" \
-H "Authorization: Bearer ys_live_YOUR_KEY"

Replace ys_live_YOUR_KEY with your key.

Omit the header and every call returns a typed 401 — this is the envelope, verbatim:

2 · without a key
curl -s "https://api.youtubesearch.dev/v1/videos/xJ8dLd9M4qE/transcript"
401 · key_required
{
"error": "KEY_REQUIRED",
"message": "An API key is required — get a free key (1,000 credits/month, no card) at https://youtubesearch.dev/login."
}
02 / 10Authentication

One header, required everywhere

Send Authorization: Bearer ys_live_… on every call — there is no keyless tier.

A key is ys_live_followed by 32 random characters. It’s shown once when you mint it in the dashboard (from a magic link), then stored only as a hash — save it then. Rotating a key revokes the old one and mints a new one in a single step, keeping your tier and your monthly balance.

Tiers

TierRateCredits / mo
free10 req/s1,000
pro10 req/s20,000

Same speed, same data quality for everyone — pro buys more credits, not more access.

Credits & metering

Each metered response carries X-Credits-Charged and X-Credits-Remaining headers. Charges settle only after a successful response — failed calls are never billed. Per-call costs are listed with each endpoint. Running out returns OUT_OF_CREDITS (402); exceeding your rate returns RATE_LIMITED (429). Errors are typed JSON — see §07 Errors.

GET /v1/credits

Your key’s balance. Takes no parameters.

Request

curl
curl -s "https://api.youtubesearch.dev/v1/credits" \
-H "Authorization: Bearer ys_live_YOUR_KEY"

Response

200 · application/json
{
"tier": "free",
"monthly_allowance": 1000,
"used_this_month": 137,
"remaining": 863
}

CREDITS  0 · unmetered — this call emits no X-Credits-* headers

04 / 10Endpoint

GET /v1/videos/{video_id}

Full native metadata for one video — the cheap look before an expensive extract.

Path parameter

ParameterTypeRequiredDescription
video_idstringRequiredThe 11-character YouTube id. Must match ^[A-Za-z0-9_-]{11}$.

Request

curl
curl -s "https://api.youtubesearch.dev/v1/videos/zjkBMFhNj_g" \
-H "Authorization: Bearer ys_live_YOUR_KEY"

Response

200 · application/json
{
"youtube_id": "zjkBMFhNj_g",
"title": "[1hr Talk] Intro to Large Language Models",
"channel": "Andrej Karpathy",
"channel_id": "UCXUPKJO5MZQN11PqgIvyuvQ",
"duration_s": 3588,
"view_count": 3835399,
"published_at": "2 years ago",
"description": "This is a 1 hour general-audience introduction to Large Language Models...",
"chapters": [
{
"title": "Intro: Large Language Model (LLM) talk",
"start_s": 0
},
{
"title": "LLM Inference",
"start_s": 34
},
{
"title": "LLM Training",
"start_s": 126
}
],
"cached": true
}

Returns youtube_id, title, channel, channel_id, duration_s, published_at, view_count, description, chapters (when the video has them), and cached. The cache refreshes when older than 7 days.

CREDITS  1

ERRORS  INVALID_VIDEO_ID, KEY_REQUIRED, VIDEO_UNAVAILABLE, AGE_RESTRICTED, METADATA_* see §07.

05 / 10Endpoint

GET /v1/videos/{video_id}/transcript

The timestamped transcript. Sourced from captions when present; when they're absent, ASR transcribes the audio. A genuinely unextractable video returns a typed error saying exactly why.

Query parameters

ParameterTypeRequiredDescription
formatstringOptionalmarkdown · json · plain. Default markdown. json returns segments [{ text, offset_ms, duration_ms }]; the others return a string.
start, endfloatOptionalSeconds, decimals allowed (e.g. 1663.5). Clip the transcript to this window. start greater than end is rejected.
max_tokensintegerOptionalCap the returned text to fit a context budget. Minimum 1.

Request

curl
curl -s "https://api.youtubesearch.dev/v1/videos/zjkBMFhNj_g/transcript?start=1663&end=2012" \
-H "Authorization: Bearer ys_live_YOUR_KEY"

Response

200 · application/json
{
"youtube_id": "zjkBMFhNj_g",
"source": "caption",
"language": "en",
"format": "markdown",
"cached": true,
"truncated": false,
"transcript": "So the way we train these models is we take a large chunk of the internet — roughly 10 terabytes of text — and a big cluster of GPUs…"
}

source is caption or asr. transcript is a string, or a segment array when format=json. truncated reflects max_tokens.

CREDITS  1 cached · 2 cold · 10 when ASR transcribes the audio

ERRORS  KEY_REQUIRED, TRANSCRIPTS_DISABLED, NO_TRANSCRIPT_FOUND, AGE_RESTRICTED, the 502 caption family — see §07.

06 / 10Endpoint

GET /v1/videos/{video_id}/summary

The fewest-tokens way to understand a video — one narrative summary.

Request

curl
curl -s "https://api.youtubesearch.dev/v1/videos/zjkBMFhNj_g/summary" \
-H "Authorization: Bearer ys_live_YOUR_KEY"

Response

200 · application/json
{
"youtube_id": "zjkBMFhNj_g",
"summary": "Large Language Models (LLMs) are fundamentally computational artifacts, best understood not as simple chatbots, but as the kernel process of an emerging operating system…"
}

summaryis the video’s full narrative summary — a cold call also queues an async premium upgrade that improves it in place.

CREDITS  1 cached · 5 cold

ERRORS  KEY_REQUIRED, SUMMARY_UNAVAILABLE, SUMMARY_GENERATION_FAILED, the transcript family it reads from — see §07.

07 / 10Errors

Typed, never silent

Every error is the same envelope — a machine-readable code your agent branches on, plus a human message. This is a live 402:

402 · out_of_credits
{
"error": "OUT_OF_CREDITS",
"message": "Monthly credit allowance (1000) is insufficient for this operation. Credits reset at the start of next month. Need more now? See Pro plans at https://youtubesearch.dev/dashboard/billing."
}
StatusCodeRetryTrigger
400INVALID_REQUESTNoBad or empty query, start > end, unknown summary sections, failed validation.
400INVALID_VIDEO_IDNoid doesn't match ^[A-Za-z0-9_-]{11}$.
401INVALID_KEYNoMalformed, unknown, or revoked bearer token.
401KEY_REQUIREDNoNo Authorization header was sent.
402OUT_OF_CREDITSNoMonthly allowance exhausted. No Retry-After — resets next month.
403AGE_RESTRICTED, VIDEO_UNPLAYABLE, TRANSCRIPTS_DISABLEDNoThe video's state forbids the operation.
404VIDEO_UNAVAILABLE, NO_TRANSCRIPT_FOUNDNoVideo removed or private; no caption track exists.
429RATE_LIMITEDYesRate exceeded. Retry-After (seconds) is set.
429IP_BLOCKED, REQUEST_BLOCKED, AUDIO_DOWNLOAD_BLOCKEDVariesUpstream block. Back off; AUDIO_DOWNLOAD_BLOCKED carries no Retry-After.
500INTERNAL_ERRORNoUnhandled server error. Retry once, then report it.
502PO_TOKEN_REQUIRED, YOUTUBE_REQUEST_FAILED, TRANSCRIPT_FETCH_FAILED, METADATA_FETCH_FAILED, ASR_FAILED, SUMMARY_GENERATION_FAILED, and relatedVariesAn upstream fetch or pipeline step failed. Most are transient — retry with backoff.
503SEARCH_UNAVAILABLE, ASR_UNAVAILABLE, SUMMARY_UNAVAILABLE, METADATA_QUOTA_EXCEEDED, AUTH_UNAVAILABLE, and relatedVariesA dependency is unavailable or over quota. Retry later; an unconfigured provider won't clear on retry.

Retry-After (seconds) is set on RATE_LIMITED 429 responses — honor it. OUT_OF_CREDITS 402 never carries Retry-After(credits reset monthly; it isn’t retryable now). When a 429 or 5xx arrives without one, back off exponentially. Failed calls are never billed. All 401s also carry WWW-Authenticate: Bearer.

08 / 10MCP

Wire it into Claude Code

A remote Streamable HTTP server (youtubesearch-mcp) — stateless JSON, a thin client of this API that forwards your Authorization header per request.

It exposes the four operations as read-only tools: search_videos, get_video, get_transcript, and get_summary— same parameters as the endpoints above. There’s no credits tool; check your balance over REST or the CLI.

claude mcp add
claude mcp add --transport http \
youtubesearch \
https://mcp.youtubesearch.dev/mcp \
--header "Authorization: Bearer ys_live_YOUR_KEY"

Every call needs the header — omit it and you get KEY_REQUIRED. Errors surface verbatim as { error, message }, with “(retry after Ns)” appended when Retry-After is present.

09 / 10CLI

The same four operations, from a shell

No install — npx runs the latest version. Log in once with your key.

Commands: search, video, transcript, summary, and auth login / auth status. Pass --json for raw output. The key lives in YOUTUBESEARCH_API_KEY (or the stored config); YOUTUBESEARCH_API_BASE overrides the base URL.

shell
npx @youtubesearch/cli auth login # paste your key once, stored 0600
npx @youtubesearch/cli search "intro to large language models" --limit 5
npx @youtubesearch/cli video zjkBMFhNj_g
npx @youtubesearch/cli transcript zjkBMFhNj_g --start 1663 --end 2012
npx @youtubesearch/cli summary zjkBMFhNj_g

Exit codes: 0 success · 1 API/network · 2 usage · 3 auth. On failure, --json writes { error, message, retryAfter? } to stderr.

View the package on npm.

10 / 10Reference

The machine-readable contract

Every endpoint, parameter, and response shape above is specified in the OpenAPI document — feed it to a generator or an agent.

OpenAPI

https://api.youtubesearch.dev/v1/openapi.json

For agents

Read /llms-full.txt — this entire reference as one plain-markdown file — or the shorter /llms.txt index.

Health

Liveness at GET /health, readiness (with a DB probe) at GET /health/ready — both outside /v1. The MCP server lives at https://mcp.youtubesearch.dev/mcp.