transcriptapi-com YouTube search API

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.

Operations 1

GET /api/v2/youtube/search Search YouTube videos or channels #

Work with this as data

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 Specification

transcriptapi-com-youtube-search-api-openapi.yml Raw ↑
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