> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vidnavigator.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Search YouTube

> Search YouTube for videos using AI analysis and ranking with optional filters.

**Process:**
1. Enhanced search with prompt engineering to find relevant videos
2. AI analysis of video content and transcripts (per-video residential proxy fetch + per-video LLM analysis)
3. Intelligent ranking based on query relevance
4. Structured results with rich metadata

**Billing:** for each candidate video the API bills one `residential_request` when fetching the transcript — set `max_results` to cap how many candidates are processed and therefore how many residential charges fire. After all per-video AI analyses AND the ranking step complete, a single consolidated `analysis_request` charge is recorded with `quantity = ceil(total_tokens / 15000)`, where `total_tokens` is the sum of LLM input + output tokens across all videos analyzed plus the ranking call. No `search_request` is billed — the residential fetches + analysis fully cover the workflow. If the search returns zero results, nothing is billed. Set `include_usage=true` to receive the full per-charge breakdown — the consolidated `analysis_request` entry also carries a nested `tokens` object reporting `prompt_tokens` / `completion_tokens` / `total_tokens`.

**Partial results:** if the user runs out of `residential_request` credits mid-search, the endpoint returns HTTP `402` with `status: "partial"`, the videos analyzed so far in `data.results`, and `error_code: "insufficient_credits_video_search"`. The `usage` block (when `include_usage=true`) reflects only the charges that succeeded.

Search YouTube for videos using AI-powered analysis and ranking with optional filters.

<Note>
  This endpoint was previously `/search/video`. It is now `/youtube/search` and is dedicated to searching YouTube. To search TikTok, use the [TikTok Search](/api-reference/endpoint/tiktok-search) endpoint. To search your own uploaded files, use [Search Files](/api-reference/endpoint/search-file).
</Note>

## Overview

Find the most relevant YouTube videos using natural language queries. Our AI analyzes video content, transcripts, and metadata to deliver precisely ranked results.

### Search Process

1. **Enhanced query processing**: AI expands and optimizes your search query
2. **Content analysis**: per-video transcript fetch (residential proxy) + per-video AI analysis
3. **Intelligent ranking**: results ranked by relevance, not just keyword matching
4. **Rich results**: detailed video information with explanations

## Billing

Unlike a flat `search_request`, YouTube search bills for the work it actually does:

* **One `residential_request` per candidate video** whose transcript is fetched. Use `max_results` to cap how many candidates are processed — that directly caps how many residential charges fire.
* **One consolidated `analysis_request` charge** after all per-video analyses **and** the ranking step complete, with `quantity = ceil(total_tokens / 15000)` where `total_tokens` is the sum of LLM input + output tokens across every video analyzed plus the ranking call.
* **No `search_request`** is billed — the residential fetches + analysis fully cover the workflow.
* If the search returns zero results, **nothing is billed**.

Set `include_usage: true` to receive the full per-charge breakdown. The consolidated `analysis_request` entry also carries a nested `tokens` object reporting `prompt_tokens` / `completion_tokens` / `total_tokens`.

<Note>
  **Partial results:** if you run out of `residential_request` credits mid-search, the endpoint returns HTTP `402` with `status: "partial"`, the videos analyzed so far in `data.results`, and `error_code: "insufficient_credits_video_search"`. The `usage` block (when `include_usage=true`) reflects only the charges that succeeded.
</Note>

### Search Options

<CardGroup cols={2}>
  <Card title="Enhanced Search" icon="wand-magic-sparkles">
    AI-powered query expansion and optimization (recommended)
  </Card>

  <Card title="Year Filtering" icon="calendar">
    Filter results by publication date range
  </Card>

  <Card title="Duration Filtering" icon="clock">
    Limit results by maximum video duration
  </Card>

  <Card title="Focus Types" icon="bullseye">
    Prioritize relevance, popularity, or brevity
  </Card>
</CardGroup>

## Request Parameters

| Parameter             | Type    | Required | Description                                                                                                                                                                                                                                                                           |
| --------------------- | ------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `query`               | string  | Yes      | Search query                                                                                                                                                                                                                                                                          |
| `use_enhanced_search` | boolean | No       | Whether to use enhanced search (default `true`)                                                                                                                                                                                                                                       |
| `start_year`          | integer | No       | Filter by start year                                                                                                                                                                                                                                                                  |
| `end_year`            | integer | No       | Filter by end year                                                                                                                                                                                                                                                                    |
| `focus`               | string  | No       | `relevance` (default), `popularity`, or `brevity`                                                                                                                                                                                                                                     |
| `duration`            | integer | No       | Maximum duration in seconds                                                                                                                                                                                                                                                           |
| `max_results`         | integer | No       | Maximum number of videos to analyse and return. Each candidate triggers one `residential_request` and contributes tokens to the consolidated `analysis_request` charge, so lowering this caps the per-call cost. Defaults to your plan ceiling; values above it are silently clamped. |
| `include_usage`       | boolean | No       | When `true`, the response includes a `usage` block listing every meter charged, the total credits deducted, and the remaining balance.                                                                                                                                                |

## Example Usage

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://api.vidnavigator.com/v1/youtube/search" \
    -H "X-API-Key: YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "query": "What are the best practices for React development?",
      "use_enhanced_search": true,
      "start_year": 2020,
      "end_year": 2024,
      "focus": "relevance",
      "duration": 1800,
      "max_results": 5
    }'
  ```

  ```python Python theme={null}
  import requests

  url = "https://api.vidnavigator.com/v1/youtube/search"
  headers = {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json"
  }
  data = {
      "query": "What are the best practices for React development?",
      "use_enhanced_search": True,
      "start_year": 2020,
      "end_year": 2024,
      "focus": "relevance",
      "duration": 1800,
      "max_results": 5
  }

  response = requests.post(url, headers=headers, json=data)
  results = response.json()

  for video in results['data']['results']:
      print(f"Title: {video['title']}")
      print(f"Relevance Score: {video['relevance_score']}")
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://api.vidnavigator.com/v1/youtube/search', {
    method: 'POST',
    headers: {
      'X-API-Key': 'YOUR_API_KEY',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      query: 'What are the best practices for React development?',
      use_enhanced_search: true,
      start_year: 2020,
      end_year: 2024,
      focus: 'relevance',
      duration: 1800,
      max_results: 5
    })
  });

  const results = await response.json();
  ```
</CodeGroup>

## Response Example

```json theme={null}
{
  "status": "success",
  "data": {
    "results": [
      {
        "title": "React Best Practices 2024: Clean Code & Performance",
        "description": "Complete guide to writing maintainable React code...",
        "url": "https://youtube.com/watch?v=example123",
        "thumbnail": "https://img.youtube.com/vi/example123/maxresdefault.jpg",
        "channel": "React Mastery",
        "duration": "15:30",
        "views": 125000,
        "published_date": "2024-01-15",
        "relevance_score": 0.95,
        "explanation": "This video directly addresses React best practices with focus on clean code and performance optimization.",
        "key_topics": ["React hooks", "Performance optimization", "Code organization"]
      }
    ],
    "query": "What are the best practices for React development?",
    "total_found": 1,
    "explanation": "Found videos discussing React development best practices, focusing on recent content and high relevance."
  },
  "usage": {
    "charges": [
      { "service_type": "residential_request", "quantity": 5, "credits": 0.025 },
      {
        "service_type": "analysis_request",
        "quantity": 2,
        "credits": 0.02,
        "tokens": { "prompt_tokens": 24000, "completion_tokens": 4200, "total_tokens": 28200 }
      }
    ],
    "total_credits": 0.045
  }
}
```

<Note>
  The `usage` block is only included when `include_usage=true` in the request.
</Note>

## Partial Results (402)

```json theme={null}
{
  "status": "partial",
  "error_code": "insufficient_credits_video_search",
  "message": "Ran out of credits after analyzing some videos.",
  "data": {
    "results": [ ... ],
    "query": "...",
    "total_found": 3,
    "explanation": "..."
  },
  "usage": { "charges": [ ... ], "total_credits": 0.02 }
}
```

## Use Cases

<CardGroup cols={2}>
  <Card title="Research & Learning" icon="graduation-cap">
    Find educational content on specific topics or technologies
  </Card>

  <Card title="Content Curation" icon="list-check">
    Build curated lists of videos for courses or documentation
  </Card>

  <Card title="Competitive Analysis" icon="chart-line">
    Analyze what content exists in your industry or niche
  </Card>

  <Card title="Trend Discovery" icon="arrow-trend-up">
    Identify trending topics and popular content creators
  </Card>
</CardGroup>


## OpenAPI

````yaml POST /youtube/search
openapi: 3.0.3
info:
  title: VidNavigator Developer API
  description: >-
    The VidNavigator Developer API provides programmatic access to video
    analysis, transcription, and search capabilities.


    ## Authentication

    All endpoints require API key authentication via the `X-API-Key` header:

    ```

    X-API-Key: YOUR_API_KEY

    ```


    ## Rate Limits

    Check the documentation for the rate limits for each endpoint.


    ## Error Handling

    The API uses standard HTTP status codes and returns error responses in JSON
    format:

    ```json

    {
      "status": "error",
      "error": "error_type",
      "message": "Human readable error message"
    }

    ```
  version: 1.0.0
  contact:
    name: VidNavigator Support
    url: https://vidnavigator.com/support
    email: support@vidnavigator.com
  license:
    name: Proprietary
    url: https://vidnavigator.com/terms
servers:
  - url: https://api.vidnavigator.com/v1
    description: Production server
security:
  - ApiKeyAuth: []
tags:
  - name: Transcripts
    description: Extract transcripts from online videos
  - name: TikTok
    description: Scrape TikTok profile metadata and per-video stats
  - name: Files
    description: Manage uploaded audio/video files
  - name: Analysis
    description: AI-powered content analysis
  - name: Extraction
    description: >-
      Extract structured data from video and file transcripts using custom
      schemas
  - name: Namespaces
    description: Organize uploaded files into namespaces (folders)
  - name: Search
    description: Search videos and files using AI
  - name: System
    description: System health and information
  - name: Tweet Analysis
    description: Extract structured claims and metadata from X/Twitter tweets
paths:
  /youtube/search:
    post:
      tags:
        - Search
      summary: Search YouTube for videos
      description: >-
        Search YouTube for videos using AI analysis and ranking with optional
        filters.


        **Process:**

        1. Enhanced search with prompt engineering to find relevant videos

        2. AI analysis of video content and transcripts (per-video residential
        proxy fetch + per-video LLM analysis)

        3. Intelligent ranking based on query relevance

        4. Structured results with rich metadata


        **Billing:** for each candidate video the API bills one
        `residential_request` when fetching the transcript — set `max_results`
        to cap how many candidates are processed and therefore how many
        residential charges fire. After all per-video AI analyses AND the
        ranking step complete, a single consolidated `analysis_request` charge
        is recorded with `quantity = ceil(total_tokens / 15000)`, where
        `total_tokens` is the sum of LLM input + output tokens across all videos
        analyzed plus the ranking call. No `search_request` is billed — the
        residential fetches + analysis fully cover the workflow. If the search
        returns zero results, nothing is billed. Set `include_usage=true` to
        receive the full per-charge breakdown — the consolidated
        `analysis_request` entry also carries a nested `tokens` object reporting
        `prompt_tokens` / `completion_tokens` / `total_tokens`.


        **Partial results:** if the user runs out of `residential_request`
        credits mid-search, the endpoint returns HTTP `402` with `status:
        "partial"`, the videos analyzed so far in `data.results`, and
        `error_code: "insufficient_credits_video_search"`. The `usage` block
        (when `include_usage=true`) reflects only the charges that succeeded.
      operationId: searchYouTube
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - query
              properties:
                query:
                  type: string
                  description: Search query
                  example: What are the best practices for React development?
                use_enhanced_search:
                  type: boolean
                  default: true
                  description: Whether to use enhanced search
                start_year:
                  type: integer
                  description: Filter by start year
                  example: 2020
                end_year:
                  type: integer
                  description: Filter by end year
                  example: 2024
                focus:
                  type: string
                  enum:
                    - relevance
                    - popularity
                    - brevity
                  default: relevance
                  description: Search focus
                duration:
                  type: integer
                  description: Maximum duration in seconds
                  example: 600
                max_results:
                  type: integer
                  minimum: 1
                  description: >-
                    Maximum number of videos to analyse and return. Each
                    candidate triggers one `residential_request` (transcript
                    fetch) and contributes tokens to the consolidated
                    `analysis_request` charge, so lowering this caps the
                    per-call cost. When omitted, defaults to the user's plan
                    ceiling (`videos_per_search_count`). Values above the plan
                    ceiling are silently clamped down.
                  example: 2
                include_usage:
                  type: boolean
                  default: false
                  description: >-
                    When true, the response includes a `usage` block listing
                    every meter charged during this request, the total credits
                    deducted, and the user's remaining balance.
      responses:
        '200':
          description: Search completed successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    enum:
                      - success
                  data:
                    type: object
                    properties:
                      results:
                        type: array
                        items:
                          $ref: '#/components/schemas/VideoSearchResult'
                      query:
                        type: string
                      total_found:
                        type: integer
                      explanation:
                        type: string
                  usage:
                    $ref: '#/components/schemas/UsageBlock'
        '400':
          $ref: '#/components/responses/BadRequest'
        '402':
          description: >-
            Either the initial search request was denied for insufficient
            credits (`status: error`), or credits ran out mid-analysis after
            some videos were already processed (`status: partial`, partial
            results included).
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/PaymentRequiredBody'
                  - type: object
                    description: >-
                      Partial-results 402 — some videos were analyzed before
                      credits ran out.
                    properties:
                      status:
                        type: string
                        enum:
                          - partial
                      error_code:
                        type: string
                        enum:
                          - insufficient_credits_video_search
                      message:
                        type: string
                      data:
                        type: object
                        properties:
                          results:
                            type: array
                            items:
                              $ref: '#/components/schemas/VideoSearchResult'
                          query:
                            type: string
                          total_found:
                            type: integer
                          explanation:
                            type: string
                      usage:
                        $ref: '#/components/schemas/UsageBlock'
        '500':
          $ref: '#/components/responses/InternalServerError'
components:
  schemas:
    VideoSearchResult:
      type: object
      properties:
        title:
          type: string
        url:
          type: string
          format: uri
        description:
          type: string
        thumbnail:
          type: string
          format: uri
        channel:
          type: string
        published_date:
          type: string
          description: Publication date
        duration:
          type: number
          description: Duration in seconds
        views:
          type: integer
        likes:
          type: integer
        relevance_score:
          type: number
          description: AI relevance score (0-1)
        transcript_summary:
          type: string
        people:
          type: array
          items:
            type: object
            properties:
              name:
                type: string
              context:
                type: string
        places:
          type: array
          items:
            type: object
            properties:
              name:
                type: string
              context:
                type: string
        key_subjects:
          type: array
          items:
            type: object
            properties:
              name:
                type: string
              description:
                type: string
        timestamp:
          type: number
        relevant_text:
          type: string
        query_relevance:
          type: string
    UsageBlock:
      type: object
      description: >-
        Per-call usage disclosure. Returned only when the caller passes
        `include_usage=true` in the request body. Lists every meter that fired
        during this request and the credits actually deducted. Multiple charges
        of the same meter inside one request are consolidated into a single
        entry (their quantities and credits are summed). When a charge was
        waived through a cache-hit sponsorship (e.g. NGO), it carries `waived:
        true` + `credits_saved`, and a top-level `waived.credits_saved` summary
        appears.


        For endpoints that involve LLM analysis (`/extract/video`,
        `/extract/file`, `/analyze/video`, `/analyze/file`, `/youtube/search`),
        the consolidated `analysis_request` charge entry carries a nested
        `tokens` object reporting the LLM input/output token tally for the
        request.
      properties:
        charges:
          type: array
          description: >-
            Every billed meter for this request, consolidated: one entry per
            `service_type`. Multiple billings of the same meter inside the
            request sum into a single entry. Rollbacks net against the matching
            charge — if a charge is fully refunded inside the request, the entry
            is dropped from the response entirely.
          items:
            type: object
            properties:
              service_type:
                type: string
                enum:
                  - standard_request
                  - residential_request
                  - transcription_hour
                  - analysis_request
                  - search_request
                  - scene_analysis_hour
                description: Which meter fired.
              quantity:
                type: number
                description: >-
                  Net units consumed. For `analysis_request`, this is computed
                  as `ceil(total_tokens / 15000)`. For `transcription_hour` /
                  `scene_analysis_hour`, it's in hours.
              credits:
                type: number
                description: >-
                  Net credits actually deducted for this meter. Will be 0 when
                  the charge was waived.
              waived:
                type: boolean
                description: >-
                  True when these charges were waived (cache hit + user has
                  free_on_cache_hit sponsorship).
              credits_saved:
                type: number
                description: >-
                  When waived=true, the credits that would have been charged
                  otherwise.
              tokens:
                type: object
                description: >-
                  Only present on the `analysis_request` entry for endpoints
                  that run LLM analysis. Reports the cumulative LLM token tally
                  for this request (sum across all internal AI calls).
                properties:
                  prompt_tokens:
                    type: integer
                    description: Total LLM input tokens.
                  completion_tokens:
                    type: integer
                    description: Total LLM output tokens.
                  total_tokens:
                    type: integer
                    description: Sum of `prompt_tokens` + `completion_tokens`.
        total_credits:
          type: number
          description: >-
            Net credits deducted by this request (sum of all
            `charges[].credits`).
        waived:
          type: object
          description: Present only when one or more charges in this request were waived.
          properties:
            credits_saved:
              type: number
              description: Total credits saved via cache-hit sponsorship on this request.
    PaymentRequiredBody:
      type: object
      description: Standard 402 error body returned when the user has insufficient credits.
      properties:
        status:
          type: string
          enum:
            - error
        error:
          type: string
          enum:
            - limit_exceeded
        error_code:
          type: string
          enum:
            - limit_exceeded
        message:
          type: string
  responses:
    BadRequest:
      description: Bad request - invalid parameters
      content:
        application/json:
          schema:
            type: object
            properties:
              status:
                type: string
                enum:
                  - error
              error:
                type: string
              message:
                type: string
    InternalServerError:
      description: Internal server error
      content:
        application/json:
          schema:
            type: object
            properties:
              status:
                type: string
                enum:
                  - error
              error:
                type: string
                enum:
                  - internal_server_error
              message:
                type: string
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: >-
        API key authentication. Include your VidNavigator API key in the
        X-API-Key header.

````