openapi: 3.0.0
info:
  title: YouTube Hashtag API
  description: |
    Retrieve the videos or shorts YouTube lists under a hashtag, together with the hashtag's approximate video and channel counts, with pagination support.

    **Cross-linking**: The `hashtags` returned by the YouTube Post API can be passed as the `hashtag` parameter. Video and short IDs can be used with the YouTube Video API, and channel IDs with the YouTube Channel API.
  version: 1.0.0
servers:
  - url: https://www.searchapi.io/api/v1
paths:
  /search:
    get:
      summary: YouTube Hashtag Search
      security:
        - ApiKeyAuth: []
        - ApiKeyQuery: []
      parameters:
        - name: engine
          in: query
          required: true
          description: Search engine to use
          schema:
            type: string
            enum: ["youtube_hashtag"]
        - name: hashtag
          in: query
          required: true
          description: The hashtag to look up, with or without the leading "#" (e.g., "funny" or "#funny"), made of letters, numbers and underscores
          schema:
            type: string
            maxLength: 100
        - name: search_type
          in: query
          required: false
          description: Which hashtag feed to return, all videos or shorts only
          schema:
            type: string
            enum: ["all", "shorts"]
            default: "all"
        - name: gl
          in: query
          required: false
          description: Country code for localized results (ISO 3166-1 alpha-2)
          schema:
            type: string
            enum: ["DZ", "AR", "AU", "AT", "AZ", "BH", "BD", "BY", "BE", "BO", "BA", "BR", "BG", "KH", "CA", "CL", "CO", "CR", "HR", "CY", "CZ", "DK", "DO", "EC", "EG", "SV", "EE", "FI", "FR", "GE", "DE", "GH", "GR", "GT", "HN", "HK", "HU", "IS", "IN", "ID", "IQ", "IE", "IL", "IT", "JM", "JP", "JO", "KZ", "KE", "KW", "LA", "LV", "LB", "LY", "LI", "LT", "LU", "MY", "MT", "MX", "ME", "MA", "NP", "NL", "NZ", "NI", "NG", "MK", "NO", "OM", "PK", "PA", "PG", "PY", "PE", "PH", "PL", "PT", "PR", "QA", "RO", "RU", "SA", "SN", "RS", "SG", "SK", "SI", "ZA", "KR", "ES", "LK", "SE", "CH", "TW", "TZ", "TH", "TN", "TR", "UG", "UA", "AE", "GB", "US", "UY", "VE", "VN", "YE", "ZW"]
            default: "US"
        - name: hl
          in: query
          required: false
          description: Language code for the interface language
          schema:
            type: string
            enum: ["af", "az", "id", "ms", "bs", "ca", "cs", "da", "de", "et", "en-in", "en-gb", "en", "es", "es-419", "es-us", "eu", "fil", "fr", "fr-ca", "gl", "hr", "zu", "is", "it", "sw", "lv", "lt", "hu", "nl", "no", "uz", "pl", "pt-pt", "pt", "ro", "sq", "sk", "sl", "sr-latn", "fi", "sv", "vi", "tr", "be", "bg", "ky", "kk", "mk", "mn", "ru", "sr", "uk", "el", "hy", "iw", "ur", "ar", "fa", "ne", "mr", "hi", "as", "bn", "pa", "gu", "or", "ta", "te", "kn", "ml", "si", "th", "lo", "my", "ka", "am", "km", "zh-cn", "zh-tw", "zh-hk", "ja", "ko"]
            default: "en"
        - name: next_page_token
          in: query
          required: false
          description: Token from pagination.next_page_token of a previous response to retrieve the next page of the same hashtag and search_type
          schema:
            type: string
            maxLength: 4096
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SearchResponse'
        '400':
          description: Validation Error. There is an issue with query parameters, such as missing required parameters or invalid values.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Authentication Error. The API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Rate Limit Exceeded. The number of allowed requests has been exceeded. Consider upgrading your plan or waiting for the limit to reset.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Server Error. Internal server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Timeout. We could not retrieve results in 90 seconds.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: Authorization
      description: 'Use Bearer authentication. Format: "Bearer YOUR_API_KEY"'
    ApiKeyQuery:
      type: apiKey
      in: query
      name: api_key
      description: Pass API key as query parameter
  schemas:
    SearchResponse:
      type: object
      properties:
        search_metadata:
          $ref: '#/components/schemas/SearchMetadata'
        search_parameters:
          $ref: '#/components/schemas/SearchParameters'
        hashtag:
          $ref: '#/components/schemas/Hashtag'
        videos:
          type: array
          description: Videos listed under the hashtag
          items:
            $ref: '#/components/schemas/Video'
        shorts:
          type: array
          description: Shorts listed under the hashtag
          items:
            $ref: '#/components/schemas/Short'
        pagination:
          $ref: '#/components/schemas/Pagination'
        error:
          type: string
          description: Error message if the search failed
    SearchMetadata:
      type: object
      required: [id, status, created_at]
      properties:
        id:
          type: string
          description: Unique identifier for the search request
        status:
          type: string
          description: Status of the search request
        created_at:
          type: string
          format: date-time
          description: Timestamp when the search was created
        request_time_taken:
          type: number
          description: Time taken to make the request in seconds
        parsing_time_taken:
          type: number
          description: Time taken to parse the results in seconds
        total_time_taken:
          type: number
          description: Total time taken for the search in seconds
        request_url:
          type: string
          description: YouTube URL for this search
        html_url:
          type: string
          description: URL to view HTML results
        json_url:
          type: string
          description: URL to view JSON results
    SearchParameters:
      type: object
      properties:
        engine:
          type: string
          description: The search engine used
        hashtag:
          type: string
          description: The hashtag searched, without the leading "#"
        search_type:
          type: string
          description: The hashtag feed returned
        gl:
          type: string
          description: Country code used for the search
        hl:
          type: string
          description: Language code used for the search
        next_page_token:
          type: string
          description: Pagination token used for this request
    Hashtag:
      type: object
      required: [title, link]
      properties:
        title:
          type: string
          description: Hashtag as YouTube displays it (e.g., "#funny")
        link:
          type: string
          description: URL of the YouTube hashtag page
        videos:
          type: integer
          description: Approximate number of videos YouTube reports for the hashtag
        channels:
          type: integer
          description: Approximate number of channels YouTube reports for the hashtag
    Video:
      type: object
      required: [position, id, title, link, channel, thumbnail]
      properties:
        position:
          type: integer
          description: Position in the results
        id:
          type: string
          description: YouTube video ID
        title:
          type: string
          description: Video title
        link:
          type: string
          description: Direct link to the video
        views:
          type: integer
          description: Number of views, or current viewers for a live stream
        is_live:
          type: boolean
          description: Whether the video is a live stream airing now
        is_short:
          type: boolean
          description: Whether the video is a YouTube Short
        channel:
          $ref: '#/components/schemas/Channel'
        length:
          type: string
          description: Video duration (e.g., "12:34")
        published_time:
          type: string
          description: Relative time since the video was published (e.g., "3w ago")
        badges:
          type: array
          items:
            type: string
          description: Badges shown on the video (e.g., "LIVE")
        thumbnail:
          $ref: '#/components/schemas/Thumbnail'
    Channel:
      type: object
      required: [id, title, link]
      properties:
        id:
          type: string
          description: Unique channel identifier
        title:
          type: string
          description: Channel name
        link:
          type: string
          description: URL of the channel page
        is_verified:
          type: boolean
          description: Whether the channel carries a verification badge
        thumbnail:
          type: string
          description: URL to the channel avatar image
    Thumbnail:
      type: object
      properties:
        static:
          type: string
          description: URL to the smaller video thumbnail image
        rich:
          type: string
          description: URL to the larger video thumbnail image
    Short:
      type: object
      required: [position, id, link]
      properties:
        position:
          type: integer
          description: Position in the results
        id:
          type: string
          description: YouTube video ID of the short
        title:
          type: string
          description: Short title
        link:
          type: string
          description: Direct link to the short
        views:
          type: integer
          description: Approximate number of views
        thumbnail:
          type: string
          description: URL to the short thumbnail image
    Pagination:
      type: object
      properties:
        next_page_token:
          type: string
          description: Token to retrieve the next page of the same hashtag feed
    ErrorResponse:
      type: object
      required: [error]
      properties:
        error:
          type: string
          description: Error message describing what went wrong
