openapi: 3.0.0
info:
  title: TikTok Profile Videos API
  description: |
    Retrieve a TikTok creator's video feed (their posts), paginated and sortable by latest, popular,
    or oldest. Each video includes the caption, publish time, duration, thumbnail, engagement counts,
    the sound it uses, and the hashtags and mentions parsed from the caption.
  version: 1.0.0
servers:
  - url: https://www.searchapi.io/api/v1
paths:
  /search:
    get:
      summary: TikTok Profile Videos Search
      security:
        - ApiKeyAuth: []
        - ApiKeyQuery: []
      parameters:
        - name: engine
          in: query
          required: true
          description: Search engine identifier
          schema:
            type: string
            enum: ["tiktok_profile_videos"]
            default: "tiktok_profile_videos"
        - name: username
          in: query
          required: true
          description: TikTok username (with or without the @ symbol)
          schema:
            type: string
            pattern: '^@?[a-zA-Z0-9_.]{1,24}$'
        - name: sort_by
          in: query
          required: false
          description: Order of the returned videos
          schema:
            type: string
            enum: ["latest", "popular", "oldest"]
            default: "latest"
        - name: next_page_token
          in: query
          required: false
          description: Token to retrieve the next page of videos, returned as pagination.next_page_token when pagination.has_more is true
          schema:
            type: string
      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'
        profile:
          $ref: '#/components/schemas/Profile'
        videos:
          type: array
          items:
            $ref: '#/components/schemas/Video'
        pagination:
          $ref: '#/components/schemas/Pagination'
        error:
          type: string
          description: Error message when no results are found

    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: TikTok 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: Search engine identifier
        username:
          type: string
          description: TikTok username
        sort_by:
          type: string
          description: Order of the returned videos (latest, popular, or oldest)
        next_page_token:
          type: string
          description: Pagination token used for this request

    Profile:
      type: object
      properties:
        id:
          type: string
          description: TikTok numeric user ID
        username:
          type: string
          description: TikTok username
        link:
          type: string
          description: URL to the profile page
        name:
          type: string
          description: Display name
        bio:
          type: string
          description: Profile bio or description
        avatar:
          type: string
          description: URL to the profile avatar image (signed by TikTok, expires after ~48 hours)
        is_verified:
          type: boolean
          description: Present and true when the account is verified
        is_private:
          type: boolean
          description: Present and true when the account is private
        followers:
          type: integer
          description: Number of followers
        following:
          type: integer
          description: Number of accounts being followed
        hearts:
          type: integer
          description: Total hearts (likes) received across all videos
        posts:
          type: integer
          description: Total number of videos posted

    Video:
      type: object
      properties:
        position:
          type: integer
          description: 1-based position of the video in the returned page
        id:
          type: string
          description: TikTok video ID
        link:
          type: string
          description: Canonical URL to the video (or /photo/ for image carousels)
        caption:
          type: string
          description: Video caption
        language:
          type: string
          description: Caption language code (e.g. en, es)
        hashtags:
          type: array
          description: Hashtags parsed from the caption
          items:
            type: string
        mentions:
          type: array
          description: Usernames mentioned in the caption
          items:
            type: string
        iso_date:
          type: string
          format: date-time
          description: Publish time in ISO 8601 format
        duration:
          type: integer
          description: Video duration in seconds (absent for photo posts)
        width:
          type: integer
          description: Video width in pixels (absent for photo posts)
        height:
          type: integer
          description: Video height in pixels (absent for photo posts)
        is_pinned:
          type: boolean
          description: Present and true when the video is pinned to the top of the profile
        is_ad:
          type: boolean
          description: Present and true when the video is a sponsored/promoted post
        is_duet_enabled:
          type: boolean
          description: Present and true when duets are allowed on the video
        is_stitch_enabled:
          type: boolean
          description: Present and true when stitches are allowed on the video
        views:
          type: integer
          description: Number of views (plays)
        likes:
          type: integer
          description: Number of likes (diggs)
        comments:
          type: integer
          description: Number of comments
        shares:
          type: integer
          description: Number of shares
        saves:
          type: integer
          description: Number of saves (collects)
        thumbnail:
          type: string
          description: Cover image URL (signed by TikTok, expires after ~48 hours)
        dynamic_thumbnail:
          type: string
          description: Animated cover image URL (signed by TikTok, expires after ~48 hours; absent for photo posts)
        video_meta:
          $ref: '#/components/schemas/VideoMeta'
        music:
          $ref: '#/components/schemas/Music'
        subtitles:
          type: array
          description: Available closed captions (absent when the video has none)
          items:
            $ref: '#/components/schemas/Subtitle'

    VideoMeta:
      type: object
      description: Video quality and encoding metadata (absent for photo posts)
      properties:
        definition:
          type: string
          description: Playback definition label (e.g. 540p, 720p)
        ratio:
          type: string
          description: Aspect/quality ratio label
        format:
          type: string
          description: Container format (e.g. mp4)
        codec_type:
          type: string
          description: Video codec (e.g. h264)
        size:
          type: integer
          description: Encoded size in bytes of the default rendition
        bitrate:
          type: integer
          description: Bitrate in bits per second of the default rendition
        bitrates:
          type: array
          description: Per-codec encoding variants
          items:
            $ref: '#/components/schemas/Bitrate'

    Bitrate:
      type: object
      properties:
        gear_name:
          type: string
          description: TikTok internal rendition name
        bitrate:
          type: integer
          description: Bitrate in bits per second
        fps:
          type: integer
          description: Frames per second
        codec_type:
          type: string
          description: Video codec (e.g. h264, h265_hvc1)
        format:
          type: string
          description: Container format (e.g. mp4)

    Subtitle:
      type: object
      properties:
        language:
          type: string
          description: Caption language code (e.g. eng-US)
        format:
          type: string
          description: Caption file format (e.g. webvtt)
        source:
          type: string
          description: How the caption was produced (e.g. ASR for auto-generated)
        url:
          type: string
          description: Caption file URL (signed by TikTok, expires)

    Music:
      type: object
      properties:
        id:
          type: string
          description: TikTok sound ID
        title:
          type: string
          description: Sound title
        author:
          type: string
          description: Sound author name
        cover:
          type: string
          description: Sound cover art URL (signed by TikTok, expires after ~48 hours)
        duration:
          type: integer
          description: Sound duration in seconds
        play_url:
          type: string
          description: Direct audio stream URL (signed by TikTok, expires)
        is_original:
          type: boolean
          description: Present and true when the sound is an original creation
        is_copyrighted:
          type: boolean
          description: Present and true when the sound is copyrighted
        link:
          type: string
          description: URL to the sound's TikTok page

    Pagination:
      type: object
      properties:
        has_more:
          type: boolean
          description: Present and true when more videos are available on a following page
        next_page_token:
          type: string
          description: Token to pass back as next_page_token to retrieve the next page of videos

    ErrorResponse:
      type: object
      required: [error]
      properties:
        error:
          type: string
          description: Error message describing what went wrong
