Every API here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for apis
7 MCP tools reach this
find_apisBrowse and filter every API in the catalog.
get_api_artifactsOne API's artifacts, grouped by type.
get_openapiThe primary OpenAPI for this API.
find_similar_apisAPIs that look like this one.
apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
resolveTurn a domain, URL or GitHub org into the provider it belongs to.
find_cohortsEvery scored population of providers in the catalog.
All 92 tools →
Call it yourself
curl for this page
This API
curl "https://apis.io/api/v1/apis/transcriptapi-com:transcriptapi-com-youtube-search-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"
Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we
store it to create your key and to recognise you if you sign in with another
provider. See our Privacy Policy and
Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: YouTube Transcript API - Public YouTube search API
description: 'TranscriptAPI: extract the transcript of any YouTube video as structured JSON, with or without timestamps. The same API also covers search, channels, playlists, and video metadata.
Base URL: https://transcriptapi.com (every path below is under /api/v2/youtube).
Auth: send Authorization: Bearer YOUR_API_KEY. Get a key at https://transcriptapi.com/dashboard/api-keys.
Credits: failed calls and 429s cost 0; successful calls cost 1 credit unless the endpoint states otherwise. Costs are stated on each endpoint, including per-page pricing on paginated endpoints. Cached responses (HTTP 200) also cost 1 credit.
Rate limits: 200 requests per minute per key. Honor X-RateLimit headers and Retry-After on 429.
Errors: every endpoint documents its status codes and retry flags; retry only 408, 429, and 503.
Common tasks:
- Transcribe a video: GET /api/v2/youtube/transcript?video_url=UF8uR6Z6KLc
- Find videos on a topic to transcribe: GET /api/v2/youtube/search?q=ocean+conservation&type=video&upload_date=week
- Size up a channel (subscribers, video count, tabs): GET /api/v2/youtube/channel/info?channel=@NASA
- Pull a channel''s videos, Shorts, or streams: GET /api/v2/youtube/channel/videos?channel=@NASA&tab=shorts
- Get a video''s likes, views, description links, and related videos: GET /api/v2/youtube/video/metadata?video_url=UF8uR6Z6KLc&include=related
- List a playlist''s videos: GET /api/v2/youtube/playlist/videos?playlist=
- Check a video''s available transcript languages, at no credit cost: GET /api/v2/youtube/info?video_url=UF8uR6Z6KLc
- Do all of this from Claude Desktop or any MCP client: https://transcriptapi.com/docs/mcp
Guides and full reference: https://transcriptapi.com/docs/api'
version: 1.0.0
servers:
- url: https://transcriptapi.com
security:
- bearerAuth: []
tags:
- name: YouTube search
description: 'Find the videos, channels, playlists, or movies worth processing: search a topic, then filter by popularity, upload date, or duration to build a work queue.'
paths:
/api/v2/youtube/search:
get:
tags:
- YouTube search
summary: Search YouTube videos or channels
description: 'Search YouTube for videos or channels.
- `type=video` (default): Returns video results with titles, thumbnails, view counts, etc.
- `type=channel`: Returns channel results with handles, subscriber counts, etc.
Returns YouTube''s full page (~20 items) per call.
**Pagination:** The response includes `continuation_token` (when `has_more=true`). To fetch the next page, call the endpoint again with `continuation=` and omit `q`/`type` (the token already encodes them).
**Credit cost:** 1 credit per successful request (each page).'
operationId: search_api_v2_youtube_search_get
security:
- bearerAuth: []
parameters:
- name: q
in: query
required: false
schema:
anyOf:
- type: string
minLength: 1
maxLength: 200
- type: 'null'
description: Search query (required for first page)
title: Q
description: Search query (required for first page)
- name: type
in: query
required: false
schema:
$ref: '#/components/schemas/SearchType'
description: 'Result type: video, channel, playlist, or movie'
default: video
description: 'Result type: video, channel, playlist, or movie'
examples:
videos:
summary: Videos (default)
value: video
channels:
summary: Channels
value: channel
playlists:
summary: Playlists
value: playlist
movies:
summary: Movies
value: movie
- name: sort
in: query
required: false
schema:
anyOf:
- type: string
pattern: ^(relevance|views)$
- type: 'null'
description: 'Sort order (first page): relevance (default) or views (YouTube ''Popularity''). YouTube no longer offers upload-date or rating sort in search. Use upload_date windows for recency.'
title: Sort
description: 'Sort order (first page): relevance (default) or views (YouTube ''Popularity''). YouTube no longer offers upload-date or rating sort in search. Use upload_date windows for recency.'
examples:
most_viewed:
summary: Most viewed first
value: views
- name: upload_date
in: query
required: false
schema:
anyOf:
- type: string
pattern: ^(hour|today|week|month|year)$
- type: 'null'
description: Upload-date window (first page). Videos only.
title: Upload Date
description: Upload-date window (first page). Videos only.
examples:
past_week:
summary: Uploaded in the last week
value: week
- name: duration
in: query
required: false
schema:
anyOf:
- type: string
pattern: ^(short|medium|long)$
- type: 'null'
description: 'Duration bucket (first page). Videos only: short <4m, medium 4-20m, long >20m.'
title: Duration
description: 'Duration bucket (first page). Videos only: short <4m, medium 4-20m, long >20m.'
examples:
long_form:
summary: Long-form only (>20m)
value: long
- name: features
in: query
required: false
schema:
anyOf:
- type: string
- type: 'null'
description: Comma-separated feature filters (first page), e.g. hd,subtitles,cc,live,4k,hdr,360,vr180,3d,location,creative_commons,purchased.
title: Features
description: Comma-separated feature filters (first page), e.g. hd,subtitles,cc,live,4k,hdr,360,vr180,3d,location,creative_commons,purchased.
- name: sp
in: query
required: false
schema:
anyOf:
- type: string
minLength: 1
maxLength: 256
pattern: ^[A-Za-z0-9+/=_-]+$
- type: 'null'
description: 'Advanced: raw YouTube `sp` filter (base64). Overrides the structured filters above.'
title: Sp
description: 'Advanced: raw YouTube `sp` filter (base64). Overrides the structured filters above.'
- name: continuation
in: query
required: false
schema:
anyOf:
- type: string
minLength: 1
- type: 'null'
description: Continuation token from previous page. When provided, q/type/filters are ignored.
title: Continuation
description: Continuation token from previous page. When provided, q/type/filters are ignored.
examples:
next_page:
summary: Fetch the next page
description: Opaque token copied verbatim from the previous response's `continuation` field.
value: <continuation-token-from-previous-response>
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/SearchResponse'
'400':
description: '**Bad Request** - Invalid parameter combination. Provide either `q` or `continuation`, not both.'
content:
application/json:
schema:
properties:
detail:
description: Human-readable error message
title: Detail
type: string
code:
anyOf:
- type: string
- type: 'null'
description: Optional machine-readable error code
title: Code
required:
- detail
title: ErrorResponse
type: object
examples:
missing:
summary: No parameter provided
value:
detail: Either 'q' or 'continuation' is required
both:
summary: Both parameters provided
value:
detail: Provide either 'q' or 'continuation', not both
'401':
description: Unauthorized - invalid Authorization format or API key
content:
application/json:
schema:
properties:
detail:
description: Human-readable error message
title: Detail
type: string
code:
anyOf:
- type: string
- type: 'null'
description: Optional machine-readable error code
title: Code
required:
- detail
title: ErrorResponse
type: object
headers:
WWW-Authenticate:
description: Authentication scheme for this endpoint
schema:
type: string
example: Bearer
'402':
description: Payment Required - inactive plan or exhausted credits
content:
application/json:
schema:
$defs:
PaymentActionDetail:
properties:
message:
description: User-friendly explanation of why payment is required
title: Message
type: string
reason:
description: Machine-readable reason for the payment requirement
enum:
- insufficient_credits
- no_active_paid_plan
title: Reason
type: string
action_label:
description: Short label for the recommended action CTA
title: Action Label
type: string
action_url:
description: URL to take the recommended action (top-up or pricing)
title: Action Url
type: string
required:
- message
- reason
- action_label
- action_url
title: PaymentActionDetail
type: object
properties:
detail:
$ref: '#/components/schemas/PaymentActionDetail'
required:
- detail
title: PaymentRequiredResponse
type: object
examples:
topup:
summary: Active paid plan but credits exhausted
value:
detail:
message: You have an active plan, but you've run out of credits.
reason: insufficient_credits
action_label: Top up credits
action_url: https://transcriptapi.com/top-up
billing:
summary: No active paid plan
value:
detail:
message: You don't have an active paid plan yet.
reason: no_active_paid_plan
action_label: Go to billing to choose a plan
action_url: https://transcriptapi.com/billing
'408':
description: '**Request Timeout / Retry** - Temporary failure (bot detection, network issues). **Safe to retry** after a short delay (1-5 seconds).'
content:
application/json:
schema:
properties:
detail:
description: Human-readable error message
title: Detail
type: string
code:
anyOf:
- type: string
- type: 'null'
description: Optional machine-readable error code
title: Code
required:
- detail
title: ErrorResponse
type: object
examples:
retry:
summary: Temporary failure - retry recommended
value:
detail: Request failed, please retry
'422':
description: '**Validation Error** - Invalid input format. **Do not retry** with the same input.'
content:
application/json:
schema:
properties:
detail:
description: Human-readable error message
title: Detail
type: string
code:
anyOf:
- type: string
- type: 'null'
description: Optional machine-readable error code
title: Code
required:
- detail
title: ErrorResponse
type: object
'429':
description: '**Too Many Requests** - Rate limit exceeded. **Retry after** the delay in `Retry-After` header.'
headers:
Retry-After:
description: Seconds until the limit resets
schema:
type: integer
content:
application/json:
schema:
properties:
detail:
description: Human-readable error message
title: Detail
type: string
code:
anyOf:
- type: string
- type: 'null'
description: Optional machine-readable error code
title: Code
required:
- detail
title: ErrorResponse
type: object
'500':
description: '**Internal Server Error** - Unexpected error. May retry, but if persistent, contact support.'
content:
application/json:
schema:
properties:
detail:
description: Human-readable error message
title: Detail
type: string
code:
anyOf:
- type: string
- type: 'null'
description: Optional machine-readable error code
title: Code
required:
- detail
title: ErrorResponse
type: object
examples:
server_error:
summary: Unexpected server error
value:
detail: Internal server error
'503':
description: '**Service Unavailable** - Service temporarily down or initializing. **Retry** after a short delay.'
content:
application/json:
schema:
properties:
detail:
description: Human-readable error message
title: Detail
type: string
code:
anyOf:
- type: string
- type: 'null'
description: Optional machine-readable error code
title: Code
required:
- detail
title: ErrorResponse
type: object
examples:
unavailable:
summary: Service temporarily unavailable
value:
detail: Service not initialized
components:
schemas:
SearchPlaylistResult:
properties:
type:
type: string
const: playlist
title: Type
default: playlist
playlistId:
anyOf:
- type: string
- type: 'null'
title: Playlistid
title:
anyOf:
- type: string
- type: 'null'
title: Title
url:
anyOf:
- type: string
- type: 'null'
title: Url
videoCountText:
anyOf:
- type: string
- type: 'null'
title: Videocounttext
thumbnails:
items:
$ref: '#/components/schemas/Thumbnail'
type: array
title: Thumbnails
type: object
title: SearchPlaylistResult
VideoResult:
properties:
type:
type: string
const: video
title: Type
default: video
videoId:
anyOf:
- type: string
- type: 'null'
title: Videoid
title:
anyOf:
- type: string
- type: 'null'
title: Title
channelId:
anyOf:
- type: string
- type: 'null'
title: Channelid
channelTitle:
anyOf:
- type: string
- type: 'null'
title: Channeltitle
channelHandle:
anyOf:
- type: string
- type: 'null'
title: Channelhandle
channelVerified:
type: boolean
title: Channelverified
default: false
lengthText:
anyOf:
- type: string
- type: 'null'
title: Lengthtext
viewCountText:
anyOf:
- type: string
- type: 'null'
title: Viewcounttext
publishedTimeText:
anyOf:
- type: string
- type: 'null'
title: Publishedtimetext
hasCaptions:
type: boolean
title: Hascaptions
default: false
descriptionSnippet:
anyOf:
- type: string
- type: 'null'
title: Descriptionsnippet
isLive:
type: boolean
title: Islive
default: false
is4k:
type: boolean
title: Is4K
default: false
thumbnails:
items:
$ref: '#/components/schemas/Thumbnail'
type: array
title: Thumbnails
type: object
title: VideoResult
SearchType:
type: string
enum:
- video
- channel
- playlist
- movie
title: SearchType
Thumbnail:
properties:
url:
type: string
title: Url
width:
anyOf:
- type: integer
- type: 'null'
title: Width
height:
anyOf:
- type: integer
- type: 'null'
title: Height
type: object
required:
- url
title: Thumbnail
PaymentActionDetail:
properties:
message:
description: User-friendly explanation of why payment is required
title: Message
type: string
reason:
description: Machine-readable reason for the payment requirement
enum:
- insufficient_credits
- no_active_paid_plan
title: Reason
type: string
action_label:
description: Short label for the recommended action CTA
title: Action Label
type: string
action_url:
description: URL to take the recommended action (top-up or pricing)
title: Action Url
type: string
required:
- message
- reason
- action_label
- action_url
title: PaymentActionDetail
type: object
SearchResponse:
properties:
results:
items:
oneOf:
- $ref: '#/components/schemas/VideoResult'
- $ref: '#/components/schemas/ChannelResult'
- $ref: '#/components/schemas/SearchPlaylistResult'
discriminator:
propertyName: type
mapping:
channel: '#/components/schemas/ChannelResult'
playlist: '#/components/schemas/SearchPlaylistResult'
video: '#/components/schemas/VideoResult'
type: array
title: Results
result_count:
type: integer
title: Result Count
default: 0
continuation_token:
anyOf:
- type: string
- type: 'null'
title: Continuation Token
has_more:
type: boolean
title: Has More
default: false
type: object
title: SearchResponse
ChannelResult:
properties:
type:
type: string
const: channel
title: Type
default: channel
channelId:
anyOf:
- type: string
- type: 'null'
title: Channelid
title:
anyOf:
- type: string
- type: 'null'
title: Title
handle:
anyOf:
- type: string
- type: 'null'
title: Handle
url:
anyOf:
- type: string
- type: 'null'
title: Url
description:
anyOf:
- type: string
- type: 'null'
title: Description
subscriberCount:
anyOf:
- type: string
- type: 'null'
title: Subscribercount
verified:
type: boolean
title: Verified
default: false
rssUrl:
anyOf:
- type: string
- type: 'null'
title: Rssurl
thumbnails:
items:
$ref: '#/components/schemas/Thumbnail'
type: array
title: Thumbnails
type: object
title: ChannelResult
securitySchemes:
bearerAuth:
type: http
description: 'Use Authorization: Bearer {your_api_key}'
scheme: bearer