openapi: 3.1.0
info:
  title: Influship API
  version: 1.0.0
  description: >
    Public API for creator search, profile lookup, and campaign-fit analysis.


    ## Authentication


    Send your API key in the `X-API-Key` header on every authenticated request.


    ```bash

    curl -H "X-API-Key: your_api_key" https://api.influship.com/v1/creators/autocomplete?q=fitness

    ```


    ## Billing and Rate Limits


    The API uses credit-based billing and credit-based rate limits.


    - every endpoint has a credit cost

    - successful responses include `X-Credits-Charged` and `X-Credits-Features`

    - rate limits are enforced with per-minute and per-hour credit budgets

    - rate limit state is returned in the `RateLimit-*` headers


    Account-specific credit budgets take precedence over tier defaults. Use the returned

    `RateLimit-Limit-Minute` and `RateLimit-Limit-Hour` headers to read your effective budgets.


    ## Agentic Payments


    Use `https://api.influship.com/openapi.json` to discover endpoints that accept x402 v2 or MPP payments without an
    API key. It includes `402` payment challenges and `x-payment-info` metadata for the available payment methods.


    ## Pagination


    List endpoints use cursor pagination.


    - send `limit` to control page size

    - use `next_cursor` from the response to fetch the next page

    - stop when `has_more` is `false`


    Search has one special rule:


    - `POST /v1/search` creates a persisted search session

    - `GET /v1/search/{id}` paginates that session for free

    - free pagination is capped by the original search `limit`


    ## Errors


    Errors use a consistent shape:


    ```json

    {
      "error": {
        "code": "rate_limit_exceeded",
        "message": "Rate limit exceeded (per minute)"
      }
    }

    ```


    See each operation for exact request and response schemas.
  contact:
    name: Influship Support
    email: support@influship.com
  license:
    name: Proprietary
    url: https://influship.com/terms
components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
  schemas:
    Platform:
      type: string
      enum:
        - instagram
      description: Social media platform
      example: instagram
    IngestCreatorRequest:
      type: object
      properties:
        platform:
          description: Platform of the handle to ingest. Use `instagram`.
          $ref: '#/components/schemas/Platform'
        username:
          type: string
          minLength: 1
          maxLength: 50
          description: Handle to ingest. A leading `@` is stripped and the handle is lowercased before validation.
          example: fitness_coach_jane
        source_query:
          description: >-
            Optional free-text note describing why this creator is being ingested (e.g. the search that surfaced them).
            Stored for your own attribution; does not affect processing.
          example: vegan fitness coaches in Austin
          type: string
          maxLength: 500
      required:
        - platform
        - username
      description: On-demand creator ingest request
    LookalikeRequest:
      type: object
      properties:
        seeds:
          minItems: 1
          maxItems: 10
          type: array
          items:
            $ref: '#/components/schemas/LookalikeSeed'
          description: Seed creators to find similar creators for
        filters:
          description: Additional filters
          $ref: '#/components/schemas/CommonFilters'
        limit:
          default: 25
          description: Maximum results to return
          example: 25
          type: integer
          minimum: 1
          maximum: 100
        cursor:
          description: Pagination cursor for next page
          type: string
      required:
        - seeds
      description: Find similar creators request
      examples:
        - seeds:
            - platform: instagram
              username: fitness_coach_jane
          limit: 20
        - seeds:
            - creator_id: 123e4567-e89b-12d3-a456-426614174000
              weight: 1
            - platform: instagram
              username: wellness_guru
              weight: 0.5
          filters:
            followers:
              min: 25000
          limit: 25
    LookalikeSeed:
      type: object
      properties:
        creator_id:
          description: Creator ID (use this OR platform+username)
          example: 123e4567-e89b-12d3-a456-426614174000
          type: string
          format: uuid
          pattern: >-
            ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
        platform:
          description: Platform (required with username)
          $ref: '#/components/schemas/Platform'
        username:
          description: Username (required with platform)
          example: fitness_coach_jane
          type: string
          minLength: 1
          maxLength: 50
        weight:
          default: 1
          description: Weight for this seed (0-1)
          example: 1
          type: number
          minimum: 0
          maximum: 1
      description: Seed creator for lookalike search
    CommonFilters:
      type: object
      properties:
        followers:
          description: Filter by follower count
          $ref: '#/components/schemas/FollowersFilter'
        engagement_rate:
          description: Filter by engagement rate
          $ref: '#/components/schemas/EngagementRateFilter'
        verified:
          description: Filter by verified status
          example: true
          type: boolean
      description: Common filters for creator discovery
    FollowersFilter:
      type: object
      properties:
        min:
          description: Minimum follower count
          example: 10000
          type: number
          minimum: 0
        max:
          description: Maximum follower count
          example: 500000
          type: number
          minimum: 0
      description: Filter by follower count range
    EngagementRateFilter:
      type: object
      properties:
        min:
          description: Minimum engagement rate (%)
          example: 1.5
          type: number
          minimum: 0
          maximum: 100
        max:
          description: Maximum engagement rate (%)
          example: 10
          type: number
          minimum: 0
          maximum: 100
      description: Filter by engagement rate range
    MatchRequest:
      type: object
      properties:
        creators:
          minItems: 1
          maxItems: 100
          type: array
          items:
            $ref: '#/components/schemas/MatchCreatorInput'
          description: Creators to evaluate
        intent:
          $ref: '#/components/schemas/MatchIntent'
      required:
        - creators
        - intent
      description: Score campaign fit request
      examples:
        - creators:
            - platform: instagram
              username: fitness_coach_jane
            - creator_id: 123e4567-e89b-12d3-a456-426614174000
          intent:
            query: Promote our new plant-based protein powder
            context: Target audience is health-conscious millennials interested in sustainable fitness
    MatchCreatorInput:
      type: object
      properties:
        creator_id:
          description: Creator ID (use this OR platform+username)
          example: 123e4567-e89b-12d3-a456-426614174000
          type: string
          format: uuid
          pattern: >-
            ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
        platform:
          description: Platform (required with username)
          $ref: '#/components/schemas/Platform'
        username:
          description: Username (required with platform)
          example: fitness_coach_jane
          type: string
          minLength: 1
          maxLength: 50
      description: Creator identifier for match endpoint
    MatchIntent:
      type: object
      properties:
        query:
          type: string
          minLength: 1
          maxLength: 500
          description: Campaign description
          example: Looking for fitness influencers to promote our new protein bar
        context:
          description: Additional context about the campaign
          example: Target audience is health-conscious millennials
          type: string
          maxLength: 2000
      required:
        - query
      description: Campaign intent for creator matching
    CreatorEmailsLookupRequest:
      type: object
      properties:
        creators:
          minItems: 1
          maxItems: 100
          type: array
          items:
            $ref: '#/components/schemas/CreatorEmailLookupInput'
          description: Creator lookups to resolve. Response rows preserve this input order.
      required:
        - creators
      description: Creator email lookup request
    CreatorEmailLookupInput:
      anyOf:
        - $ref: '#/components/schemas/CreatorEmailLookupById'
        - $ref: '#/components/schemas/CreatorEmailLookupByHandle'
      description: Creator email lookup input by creator ID or social handle
    CreatorEmailLookupById:
      type: object
      properties:
        creator_id:
          type: string
          format: uuid
          pattern: >-
            ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
          description: Creator profile ID to look up directly
          example: 123e4567-e89b-12d3-a456-426614174000
      required:
        - creator_id
      description: Creator email lookup input by creator ID
    CreatorEmailLookupByHandle:
      type: object
      properties:
        platform:
          description: Social platform for handle-based lookup
          $ref: '#/components/schemas/Platform'
        username:
          type: string
          minLength: 1
          maxLength: 100
          description: Social username for handle-based lookup
          example: fitness_coach_jane
      required:
        - platform
        - username
      description: Creator email lookup input by social handle
    SearchFeedbackRequest:
      type: object
      properties:
        rating:
          type: string
          enum:
            - helpful
            - not_helpful
          description: Whether the search results were useful.
        reason:
          type: string
          enum:
            - irrelevant_creators
            - too_few_creators
            - missing_niche_or_creator
            - wrong_location
            - wrong_platform
            - other
        details:
          description: Optional explanation. Do not include sensitive or personal information.
          type: string
          maxLength: 1000
      required:
        - rating
      additionalProperties: false
    SearchRequest:
      type: object
      properties:
        query:
          type: string
          minLength: 1
          maxLength: 500
          description: Natural language search query
          example: fitness influencers with 100k+ followers who post workout videos
        platforms:
          description: Filter results to specific platforms
          example:
            - instagram
          type: array
          items:
            $ref: '#/components/schemas/Platform'
        filters:
          description: Additional filters
          $ref: '#/components/schemas/CommonFilters'
        limit:
          default: 25
          description: Maximum results to return. Start with 5 for a small trial; default is 25.
          example: 5
          type: integer
          minimum: 1
          maximum: 100
        creator_kinds:
          description: Restrict results to specific creator kinds (e.g. INFLUENCER vs THEME_PAGE). Omit for no filter.
          example:
            - INFLUENCER
          minItems: 1
          type: array
          items:
            type: string
            enum:
              - INFLUENCER
              - THEME_PAGE
      required:
        - query
      description: AI-powered semantic search request
      examples:
        - query: fitness influencers who post workout videos
          limit: 5
        - query: sustainable fashion creators
          platforms:
            - instagram
          filters:
            followers:
              min: 50000
              max: 500000
            engagement_rate:
              min: 2
            verified: true
          limit: 25
          creator_kinds:
            - INFLUENCER
    ProfilesLookupRequest:
      type: object
      properties:
        profiles:
          minItems: 1
          maxItems: 100
          type: array
          items:
            $ref: '#/components/schemas/ProfileLookupItem'
          description: Profiles to lookup
      required:
        - profiles
      description: Batch lookup profiles request
      examples:
        - profiles:
            - platform: instagram
              username: fitness_coach_jane
            - platform: instagram
              username: wellness_guru
            - platform: instagram
              username: healthy_eating_tips
    ProfileLookupItem:
      type: object
      properties:
        platform:
          $ref: '#/components/schemas/Platform'
        username:
          type: string
          minLength: 1
          maxLength: 50
          description: Username to lookup
          example: fitness_coach_jane
      required:
        - platform
        - username
    PostSort:
      type: string
      enum:
        - recent
        - top_engagement
        - most_likes
        - most_views
        - most_comments
      description: >-
        Stable post ordering. top_engagement uses (likes + comments) / views, with posts that have no measurable views
        sorted last.
      example: recent
    LiveInstagramPostBatchBody:
      type: object
      properties:
        shortcodes:
          minItems: 1
          maxItems: 20
          type: array
          items:
            type: string
            minLength: 1
          description: Instagram post shortcodes from /p/, /reel/, or /tv/ URLs
          example:
            - C0ABC123xyz
            - D1DEF456uvw
      required:
        - shortcodes
    LiveInstagramTranscriptBatchBody:
      type: object
      properties:
        shortcodes:
          minItems: 1
          maxItems: 10
          type: array
          items:
            type: string
            minLength: 1
          description: Instagram video post shortcodes from /p/, /reel/, or /tv/ URLs
          example:
            - C0ABC123xyz
            - D1DEF456uvw
        language:
          description: Optional language code for transcription. Omit to auto-detect.
          example: en
          type: string
      required:
        - shortcodes
    LiveTikTokVideoBatchBody:
      type: object
      properties:
        urls:
          minItems: 1
          maxItems: 20
          type: array
          items:
            $ref: '#/components/schemas/TikTokVideoUrl'
      required:
        - urls
    TikTokVideoUrl:
      type: string
      format: uri
      $ref: '#/components/schemas/TikTokUrl'
    TikTokUrl:
      type: string
      format: uri
    LiveTikTokTranscriptBatchBody:
      type: object
      properties:
        urls:
          minItems: 1
          maxItems: 10
          type: array
          items:
            $ref: '#/components/schemas/TikTokVideoUrl'
        mode:
          default: auto
          type: string
          enum:
            - auto
            - captions
      required:
        - urls
    HealthResponse:
      type: object
      properties:
        ok:
          type: boolean
          description: Service health status
          example: true
        timestamp:
          type: string
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$
          description: Current server timestamp
          example: '2024-01-15T14:30:00.000Z'
      required:
        - ok
        - timestamp
      additionalProperties: false
      description: Health check response
    Error500:
      description: Internal server error response
      examples:
        - error:
            code: internal_error
            message: An unexpected error occurred. Please try again later.
            request_id: 550e8400-e29b-41d4-a716-446655440000
      $ref: '#/components/schemas/Error'
    ErrorCode:
      type: string
      enum:
        - validation_error
        - invalid_parameter
        - missing_parameter
        - unauthorized
        - forbidden
        - payment_required
        - insufficient_credits
        - not_found
        - rate_limit_exceeded
        - quota_exceeded
        - internal_error
        - service_unavailable
        - upstream_contract_broken
        - database_error
        - seed_not_found
        - invalid_seeds
        - seed_resolution_failed
        - lookalike_failed
        - get_profiles_failed
        - post_analysis_failed
        - match_failed
        - scraping_failed
        - transcript_unavailable
        - transcript_not_available
        - transcription_limit_exceeded
        - transcription_unavailable
      description: Machine-readable error code for programmatic handling
      example: validation_error
    Error:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              description: Machine-readable error code
              $ref: '#/components/schemas/ErrorCode'
            message:
              type: string
              description: Human-readable error message
              example: Request validation failed
            status_code:
              description: HTTP status code repeated for clients that consume the error body
              example: 402
              type: integer
              minimum: -9007199254740991
              maximum: 9007199254740991
            param:
              description: Parameter that caused the error (if applicable)
              example: query
              type: string
            request_id:
              description: Optional request ID for debugging. Read the X-Request-Id response header when absent.
              example: 550e8400-e29b-41d4-a716-446655440000
              type: string
            details:
              description: Structured error context (e.g., field-level validation issues)
              type: object
              propertyNames:
                type: string
              additionalProperties: {}
          required:
            - code
            - message
          additionalProperties: false
      required:
        - error
      additionalProperties: false
    ReadinessResponse:
      type: object
      properties:
        ok:
          type: boolean
        timestamp:
          type: string
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$
        checks:
          type: object
          propertyNames:
            type: string
          additionalProperties:
            type: object
            properties:
              status:
                type: string
                enum:
                  - ok
                  - error
              latency_ms:
                type: number
                minimum: 0
            required:
              - status
              - latency_ms
            additionalProperties: false
      required:
        - ok
        - timestamp
        - checks
      additionalProperties: false
      description: Dependency-aware service readiness status
    AutocompleteResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/AutocompleteResultItem'
          description: Autocomplete results
      required:
        - data
      additionalProperties: false
    AutocompleteResultItem:
      type: object
      properties:
        id:
          type: string
          format: uuid
          pattern: >-
            ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
          description: Creator ID
          example: 123e4567-e89b-12d3-a456-426614174000
        name:
          type: string
          description: Creator name
          example: Jane Fitness
        avatar:
          description: Avatar URL
          example: https://cdn.example.com/avatars/jane.jpg
          type:
            - string
            - 'null'
        platforms:
          type: array
          items:
            $ref: '#/components/schemas/AutocompletePlatformMatch'
          description: Matching platforms
      required:
        - id
        - name
        - avatar
        - platforms
      additionalProperties: false
    AutocompletePlatformMatch:
      type: object
      properties:
        platform:
          $ref: '#/components/schemas/Platform'
        username:
          type: string
          example: fitness_coach_jane
        display_name:
          example: Jane Fitness
          type:
            - string
            - 'null'
        match_type:
          type: string
          enum:
            - name
            - username
            - display_name
          description: How the query matched this profile
          example: username
        match_field:
          type: string
          description: The field value that matched
          example: fitness_coach_jane
      required:
        - platform
        - username
        - display_name
        - match_type
        - match_field
      additionalProperties: false
    Error400:
      description: Validation error response
      examples:
        - error:
            code: validation_error
            message: 'Invalid value for parameter ''limit'': must be between 1 and 100'
            param: limit
            request_id: 550e8400-e29b-41d4-a716-446655440000
      $ref: '#/components/schemas/Error'
    Error401:
      description: Authentication error response
      examples:
        - error:
            code: unauthorized
            message: API key missing or invalid
            request_id: 550e8400-e29b-41d4-a716-446655440000
      $ref: '#/components/schemas/Error'
    ApiCreditError402:
      anyOf:
        - $ref: '#/components/schemas/Error402'
        - $ref: '#/components/schemas/ErrorInsufficientCredits'
      description: Account billing requires attention, or available credits cannot cover this request.
    Error402:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              const: payment_required
            message:
              type: string
            status_code:
              type: number
              const: 402
            reason_code:
              type: string
              enum:
                - BILLING_SUSPENDED
                - PAYMENT_FAILED
                - PAYMENT_ACTION_REQUIRED
                - DISPUTE_OPENED
                - NO_PAYMENT_METHOD
                - SUBSCRIPTION_REQUIRED
                - NO_BUNDLE_CONFIGURED
                - BUNDLE_EXHAUSTED
            next_step:
              type: string
              enum:
                - update_payment_method
                - complete_authentication
                - contact_support
                - add_payment_method
                - reconnect_connection
                - upgrade_plan
            request_id:
              type: string
            details:
              type: object
              propertyNames:
                type: string
              additionalProperties: {}
          required:
            - code
            - message
            - status_code
            - reason_code
            - next_step
          additionalProperties: false
      required:
        - error
      additionalProperties: false
      description: Payment required response. Returned when account billing or a subscription bundle requires attention.
      examples:
        - error:
            code: payment_required
            message: Payment authentication is required.
            status_code: 402
            reason_code: PAYMENT_ACTION_REQUIRED
            next_step: complete_authentication
            request_id: 550e8400-e29b-41d4-a716-446655440000
    ErrorInsufficientCredits:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              const: insufficient_credits
            message:
              type: string
            status_code:
              type: number
              const: 402
            request_id:
              type: string
            details:
              type: object
              propertyNames:
                type: string
              additionalProperties: {}
          required:
            - code
            - message
          additionalProperties: false
      required:
        - error
      additionalProperties: false
      description: Remaining credits cannot cover this request. Add a payment method to continue. Do not retry automatically.
      examples:
        - error:
            code: insufficient_credits
            message: Not enough credits remaining for this search. Add a payment method to continue.
            details:
              remaining: 10
              required: 75
              add_payment_method: true
    Error403:
      description: Permission error response
      examples:
        - error:
            code: forbidden
            message: Your plan does not include access to this endpoint
            request_id: 550e8400-e29b-41d4-a716-446655440000
      $ref: '#/components/schemas/Error'
    Error429:
      description: >-
        Rate limit exceeded response. Check Retry-After header for backoff timing. Also returned (without RateLimit-*
        headers) when an IP is temporarily blocked after repeated failed authentication attempts.
      examples:
        - error:
            code: rate_limit_exceeded
            message: Rate limit exceeded (per minute)
            request_id: 550e8400-e29b-41d4-a716-446655440000
        - error:
            code: rate_limit_exceeded
            message: Rate limit exceeded (per hour)
            request_id: 550e8400-e29b-41d4-a716-446655440001
        - error:
            code: rate_limit_exceeded
            message: Too many failed authentication attempts. Please try again later.
            request_id: 550e8400-e29b-41d4-a716-446655440002
      $ref: '#/components/schemas/Error'
    Error503:
      description: >-
        Service temporarily unavailable: a live data upstream, or a creator search, match or lookalike request that
        could not finish in time. Check Retry-After when present and retry with bounded backoff.
      examples:
        - error:
            code: service_unavailable
            message: Live Instagram data is temporarily unavailable. Please retry shortly.
            request_id: 550e8400-e29b-41d4-a716-446655440000
            details:
              retry_after_seconds: 60
              upstream_error: upstream_rate_limited
      $ref: '#/components/schemas/Error'
    IngestCreatorResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/IngestCreatorResponseData'
      required:
        - data
      additionalProperties: false
    IngestCreatorResponseData:
      type: object
      properties:
        status:
          $ref: '#/components/schemas/IngestStatus'
        creator:
          $ref: '#/components/schemas/IngestCreatorRef'
        status_url:
          type: string
          description: >-
            Relative URL of the pollable creator resource. Returns the creator once enrichment has produced data; may
            return 404 or sparse data while the profile is still building.
          example: /v1/creators/123e4567-e89b-12d3-a456-426614174000
      required:
        - status
        - creator
        - status_url
      additionalProperties: false
      description: On-demand creator ingest result
    IngestStatus:
      type: string
      enum:
        - ingesting
        - already_exists
      description: Ingest outcome
      example: ingesting
    IngestCreatorRef:
      type: object
      properties:
        id:
          type: string
          format: uuid
          pattern: >-
            ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
          description: Creator unique identifier. Poll `status_url` to retrieve the full profile.
          example: 123e4567-e89b-12d3-a456-426614174000
        username:
          type: string
          description: Normalized handle
          example: fitness_coach_jane
        platform:
          $ref: '#/components/schemas/Platform'
      required:
        - id
        - username
        - platform
      additionalProperties: false
    Error404:
      description: Not found error response
      examples:
        - error:
            code: not_found
            message: Creator with ID '123e4567-e89b-12d3-a456-426614174000' not found
            request_id: 550e8400-e29b-41d4-a716-446655440000
      $ref: '#/components/schemas/Error'
    Error422:
      description: >-
        Unprocessable entity response. The request was well-formed but a value failed a semantic rule (e.g. an invalid
        social handle format).
      examples:
        - error:
            code: validation_error
            message: Invalid Instagram username format
            param: username
            request_id: 550e8400-e29b-41d4-a716-446655440000
      $ref: '#/components/schemas/Error'
    CreatorResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/CreatorResponseData'
        warning:
          description: >-
            Present when partial results were returned because one or more linked profiles were skipped for data
            integrity reasons.
          type: string
      required:
        - data
      additionalProperties: false
    CreatorResponseData:
      type: object
      properties:
        id:
          type: string
          format: uuid
          pattern: >-
            ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
          description: Creator unique identifier
          example: 123e4567-e89b-12d3-a456-426614174000
        name:
          type: string
          description: Creator display name
          example: Jane Fitness
        bio:
          description: Creator bio
          example: Fitness coach & wellness advocate
          type:
            - string
            - 'null'
        avatar_url:
          description: Avatar URL
          example: https://cdn.example.com/avatars/jane.jpg
          type:
            - string
            - 'null'
        ai_summary:
          description: AI-generated summary of the creator
          example: A fitness influencer focused on home workouts and healthy eating
          type:
            - string
            - 'null'
        analysis_updated_at:
          type:
            - string
            - 'null'
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$
          description: When the creator analysis was last generated
          example: '2026-07-20T12:00:00.000+00:00'
        analysis_fact_count:
          type:
            - integer
            - 'null'
          minimum: 0
          maximum: 9007199254740991
          description: Number of stored creator facts available to the last synthesis run
          example: 12
        audience_demographics:
          description: Synthesized audience demographic summary
          example: Young adults interested in practical wellness routines and meal prep
          type:
            - string
            - 'null'
        brand_alignment:
          type: array
          items:
            type: string
          description: Brand categories this creator is likely to align with
          example:
            - fitness apparel
            - nutrition
            - wellness apps
        content_themes:
          type: array
          items:
            type: string
          description: Content themes/topics
          example:
            - fitness
            - nutrition
            - wellness
        key_facts:
          type: array
          items:
            type: string
          description: Synthesized facts and notable context about the creator
          example:
            - Runs weekly workout challenges
            - Often features meal prep content
        vibe_and_aesthetics:
          description: Synthesized description of visual style and tone
          example: Bright, practical, and encouraging with clean gym and kitchen visuals
          type:
            - string
            - 'null'
        profiles:
          description: Social profiles (only included when include=profiles)
          type: array
          items:
            $ref: '#/components/schemas/ProfileSummary'
      required:
        - id
        - name
        - bio
        - avatar_url
        - ai_summary
        - analysis_updated_at
        - analysis_fact_count
        - audience_demographics
        - brand_alignment
        - content_themes
        - key_facts
        - vibe_and_aesthetics
      additionalProperties: false
      description: Full creator details
    ProfileSummary:
      type: object
      properties:
        id:
          type: string
          format: uuid
          pattern: >-
            ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
          description: Profile unique identifier
          example: 123e4567-e89b-12d3-a456-426614174000
        platform:
          $ref: '#/components/schemas/Platform'
        username:
          type: string
          description: Profile username
          example: fitness_coach_jane
        url:
          type: string
          format: uri
          description: Profile URL
          example: https://www.instagram.com/fitness_coach_jane
        followers:
          type:
            - integer
            - 'null'
          minimum: 0
          maximum: 9007199254740991
          description: Follower count (null if unknown)
          example: 125000
        engagement_rate:
          type:
            - number
            - 'null'
          minimum: 0
          description: Engagement rate as a percentage, null if unknown (e.g. 3.5 means 3.5%)
          example: 3.5
        is_verified:
          type: boolean
          description: Whether the account is verified
          example: true
        data_updated_at:
          type:
            - string
            - 'null'
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$
          description: When the stored public profile data was last refreshed
          example: '2026-07-20T12:00:00.000+00:00'
      required:
        - id
        - platform
        - username
        - url
        - followers
        - engagement_rate
        - is_verified
        - data_updated_at
      additionalProperties: false
      description: Abbreviated profile information
    PendingCreatorResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            id:
              type: string
              format: uuid
              pattern: >-
                ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
            status:
              type: string
              const: pending
          required:
            - id
            - status
          additionalProperties: false
      required:
        - data
      additionalProperties: false
    LookalikeResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/LookalikeResponseData'
        has_more:
          type: boolean
          description: Whether more results are available
          example: true
        next_cursor:
          description: Cursor for the next page
          example: eyJvZmZzZXQiOjI1fQ==
          type:
            - string
            - 'null'
      required:
        - data
        - has_more
        - next_cursor
      additionalProperties: false
    LookalikeResponseData:
      type: array
      items:
        $ref: '#/components/schemas/LookalikeResultItem'
    LookalikeResultItem:
      type: object
      properties:
        creator:
          $ref: '#/components/schemas/CreatorBasic'
        primary_profile:
          anyOf:
            - $ref: '#/components/schemas/ProfileSummary'
            - type: 'null'
          description: Primary profile (largest audience, null if no profile data available)
        similarity:
          $ref: '#/components/schemas/SimilarityInfo'
      required:
        - creator
        - primary_profile
        - similarity
      additionalProperties: false
    CreatorBasic:
      type: object
      properties:
        id:
          type: string
          format: uuid
          pattern: >-
            ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
          description: Creator unique identifier
          example: 123e4567-e89b-12d3-a456-426614174000
        name:
          type: string
          description: Creator display name
          example: Jane Fitness
        bio:
          description: Creator bio
          example: Fitness coach & wellness advocate
          type:
            - string
            - 'null'
        avatar_url:
          description: Avatar URL
          example: https://cdn.example.com/avatars/jane.jpg
          type:
            - string
            - 'null'
      required:
        - id
        - name
        - bio
        - avatar_url
      additionalProperties: false
      description: Basic creator information
    SimilarityInfo:
      type: object
      properties:
        score:
          type: number
          minimum: 0
          maximum: 1
          description: Similarity score (0-1)
          example: 0.78
        shared_traits:
          type: array
          items:
            type: string
          description: Shared traits with seed creators
          example:
            - Similar content style
            - Same niche audience
      required:
        - score
        - shared_traits
      additionalProperties: false
      description: Similarity information for lookalike match
    AIServiceError502:
      description: The API could not complete the analysis for a valid request. The failure is reported automatically.
      examples:
        - error:
            code: service_unavailable
            message: The API could not complete the analysis
            request_id: 550e8400-e29b-41d4-a716-446655440000
      $ref: '#/components/schemas/Error'
    MatchResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/MatchResponseData'
      required:
        - data
      additionalProperties: false
    MatchResponseData:
      type: array
      items:
        $ref: '#/components/schemas/MatchResultItem'
    MatchResultItem:
      type: object
      properties:
        creator:
          type: object
          properties:
            id:
              type: string
              format: uuid
              pattern: >-
                ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
            name:
              type: string
            avatar_url:
              type:
                - string
                - 'null'
          required:
            - id
            - name
            - avatar_url
          additionalProperties: false
        input:
          type: object
          properties:
            creator_id:
              type: string
              format: uuid
              pattern: >-
                ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
            platform:
              $ref: '#/components/schemas/Platform'
            username:
              type: string
          additionalProperties: false
        match:
          $ref: '#/components/schemas/MatchResult'
      required:
        - creator
        - input
        - match
      additionalProperties: false
    MatchResult:
      type: object
      properties:
        score:
          type: number
          minimum: 0
          maximum: 1
          description: Match score (0-1)
          example: 0.85
        decision:
          $ref: '#/components/schemas/MatchDecision'
        reasons:
          type: array
          items:
            type: object
            properties:
              text:
                type: string
                description: Human-readable reason for the match
                example: Strong fit due to fitness content focus and engaged audience
              provenance:
                $ref: '#/components/schemas/ReasonProvenance'
              fact_id:
                description: ID of the supporting fact, if applicable
                type: string
              source_post_id:
                description: ID of the source post, if applicable
                type: string
              source_post_url:
                description: Public link to the source post identified by `source_post_id`, when one is available.
                example: https://www.instagram.com/p/C8xYz123AbC/
                type: string
                format: uri
              evidence_quote:
                description: >-
                  Supporting text copied verbatim from a source post. Present for `post_evidence` reasons when a
                  supporting quote is available.
                type: string
            required:
              - text
              - provenance
            additionalProperties: false
          description: Structured reasons supporting the decision
        analysis_unavailable:
          description: >-
            Present and `true` when this creator could not be analyzed for this request. The result is a placeholder:
            `score` is 0 and `decision` is `neutral` (score bands do not apply), and it is not charged API credits. x402
            payments are priced per requested creator before scoring, so they are not refunded. Retry the request to get
            a real decision. Omitted for analyzed creators.
          example: true
          type: boolean
      required:
        - score
        - decision
        - reasons
      additionalProperties: false
    MatchDecision:
      type: string
      enum:
        - good
        - neutral
        - avoid
      description: Match decision recommendation
      example: good
    ReasonProvenance:
      type: string
      enum:
        - post_evidence
        - profile_fact
        - inferred
      description: >-
        How grounded a match reason is, strongest first. `post_evidence`: backed by a specific source post, identified
        by `source_post_id` with supporting text in `evidence_quote`. `profile_fact`: backed by a profile fact without
        post evidence. `inferred`: model reasoning over the profile with no direct post evidence.
    CreatorEmailsLookupResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            results:
              type: array
              items:
                $ref: '#/components/schemas/CreatorEmailsLookupResult'
            billing:
              $ref: '#/components/schemas/CreatorEmailsBilling'
          required:
            - results
            - billing
          additionalProperties: false
      required:
        - data
      additionalProperties: false
      description: Creator email lookup response
    CreatorEmailsLookupResult:
      type: object
      properties:
        input:
          $ref: '#/components/schemas/CreatorEmailLookupInputOutput'
        creator_id:
          type:
            - string
            - 'null'
          format: uuid
          pattern: >-
            ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
          description: Resolved creator ID, or null when the input could not be resolved
          example: 123e4567-e89b-12d3-a456-426614174000
        resolved:
          type: boolean
          description: Whether the lookup resolved to a creator profile
          example: true
        emails:
          type: array
          items:
            $ref: '#/components/schemas/CreatorEmailItem'
          description: API-visible emails for the resolved creator. Empty results are not billable.
      required:
        - input
        - creator_id
        - resolved
        - emails
      additionalProperties: false
      description: Creator email lookup result
    CreatorEmailItem:
      type: object
      properties:
        email:
          type: string
          minLength: 1
          description: Email address as stored, preserving original casing
          example: hello@example.com
        status:
          $ref: '#/components/schemas/CreatorEmailStatus'
        confidence:
          type:
            - number
            - 'null'
          minimum: 0
          maximum: 1
          description: Nullable confidence score for the email
          example: 0.72
        is_primary:
          type: boolean
          description: Whether this is the primary email for the creator
          example: false
        validated_at:
          type:
            - string
            - 'null'
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$
          description: When the email was last validated, if known
          example: null
        first_seen_at:
          type: string
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$
          description: When Influship first observed this email
          example: '2026-05-01T00:00:00Z'
        last_seen_at:
          type: string
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$
          description: When Influship most recently observed this email
          example: '2026-05-02T00:00:00Z'
      required:
        - email
        - status
        - confidence
        - is_primary
        - validated_at
        - first_seen_at
        - last_seen_at
      additionalProperties: false
      description: API-visible creator email
    CreatorEmailStatus:
      type: string
      enum:
        - unvalidated
        - valid
        - risky
        - creator_verified
      description: API-visible email validation status
      example: unvalidated
    CreatorEmailsBilling:
      type: object
      properties:
        billable_results:
          type: integer
          minimum: 0
          maximum: 9007199254740991
          description: Unique resolved creators with at least one returned email
          example: 1
        credits_charged:
          type: number
          minimum: 0
          description: Preview of credits charged for this lookup
          example: 5
      required:
        - billable_results
        - credits_charged
      additionalProperties: false
      description: Creator email lookup billing summary
    SearchFeedbackResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            accepted:
              type: boolean
              const: true
          required:
            - accepted
          additionalProperties: false
      required:
        - data
      additionalProperties: false
    SearchResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/SearchResponseData'
        quality:
          description: >-
            How results were ranked: all with AI relevance scoring, a mix of AI and discovery ranking, or discovery
            ranking throughout. When omitted, treat the response as `reranked`. Use each `match.ranking_source` to
            interpret its score.
          oneOf:
            - type: object
              properties:
                mode:
                  type: string
                  const: reranked
                reason:
                  type: 'null'
              required:
                - mode
                - reason
              additionalProperties: false
            - type: object
              properties:
                mode:
                  type: string
                  const: partially_reranked
                reason:
                  type: string
                  enum:
                    - content_policy
                    - incomplete_rerank_output
                    - partial_batch_failure
                    - provider_error
                    - soft_timeout
              required:
                - mode
                - reason
              additionalProperties: false
            - type: object
              properties:
                mode:
                  type: string
                  const: retrieval_fallback
                reason:
                  type: string
                  enum:
                    - content_policy
                    - incomplete_rerank_output
                    - partial_batch_failure
                    - provider_error
                    - soft_timeout
              required:
                - mode
                - reason
              additionalProperties: false
          type: object
        search_id:
          type: string
          format: uuid
          pattern: >-
            ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
          description: Search ID. Use with GET /v1/search/{id} for free pagination.
          example: 123e4567-e89b-12d3-a456-426614174000
        total:
          type: integer
          minimum: -9007199254740991
          maximum: 9007199254740991
          description: Total number of results across all pages
          example: 1
        has_more:
          type: boolean
          description: Whether more results are available
          example: false
        next_cursor:
          description: Cursor for the next page
          example: null
          type:
            - string
            - 'null'
      required:
        - data
        - search_id
        - total
        - has_more
        - next_cursor
      additionalProperties: false
      example:
        data:
          - creator:
              id: 123e4567-e89b-12d3-a456-426614174000
              name: Jane Fitness
              bio: Fitness coach and home-workout creator
              avatar_url: null
            relevant_profile: null
            primary_profile: null
            location_unverified: null
            match:
              score: 0.85
              confidence: 0.85
              low_confidence: false
              ranking_source: reranked
              reasons:
                - Publishes practical home-workout tutorials.
              evidence:
                - text: Publishes practical home-workout tutorials.
                  provenance: post_evidence
                  fact_id: null
                  source_post_id: 23256c2e-51fa-4389-a4a1-945e461e951b
                  evidence_quote: Here are three bodyweight exercises for a quick home workout.
        quality:
          mode: reranked
          reason: null
        search_id: 987fcdeb-51a2-43d7-8b90-123456789abc
        total: 1
        has_more: false
        next_cursor: null
    SearchResponseData:
      type: array
      items:
        $ref: '#/components/schemas/SearchResultItem'
    SearchResultItem:
      type: object
      properties:
        creator:
          $ref: '#/components/schemas/CreatorBasic'
        relevant_profile:
          anyOf:
            - $ref: '#/components/schemas/ProfileSummary'
            - type: 'null'
          description: Most relevant profile based on search query (null if no profile data available)
        primary_profile:
          anyOf:
            - $ref: '#/components/schemas/ProfileSummary'
            - type: 'null'
          description: Primary profile (largest audience, null if no profile data available)
        match:
          $ref: '#/components/schemas/MatchInfo'
        location_unverified:
          description: >-
            True when the query required a country but this creator location is unverified; false when the known
            location satisfies it; null when the query set no geography requirement. Known mismatches are excluded from
            results.
          example: true
          type:
            - boolean
            - 'null'
      required:
        - creator
        - relevant_profile
        - primary_profile
        - match
        - location_unverified
      additionalProperties: false
    MatchInfo:
      type: object
      properties:
        score:
          type: number
          minimum: 0
          maximum: 1
          description: Match relevance score (0-1)
          example: 0.85
        confidence:
          type: number
          minimum: 0
          maximum: 1
          description: Relevance value from 0 to 1. Mirrors `score`; interpret it using `ranking_source`.
          example: 0.85
        low_confidence:
          type: boolean
          description: >-
            True when `confidence` is at or below the low-confidence threshold. Use this flag to group candidates for
            additional review. It does not change which results are returned.
          example: false
        ranking_source:
          description: >-
            How this result was ranked: `reranked` uses AI relevance scoring; `retrieval_fallback` uses discovery
            ranking. When omitted, treat the result as `reranked`. Retrieval scores describe discovery relevance rather
            than campaign fit.
          example: reranked
          type: string
          enum:
            - reranked
            - retrieval_fallback
        reasons:
          type: array
          items:
            type: string
          description: Human-readable match reasons (plain text).
          example:
            - Publishes practical home-workout tutorials.
        evidence:
          type: array
          items:
            $ref: '#/components/schemas/MatchReasonEvidence'
          description: >-
            Evidence-grounded version of `reasons`, in the same order: each reason has a provenance label and, where it
            rests on a post, the backing `source_post_id` and a verbatim `evidence_quote`.
      required:
        - score
        - confidence
        - low_confidence
        - reasons
        - evidence
      additionalProperties: false
      description: Search match information
    MatchReasonEvidence:
      type: object
      properties:
        text:
          type: string
          description: Human-readable reason this creator matched.
          example: Publishes practical home-workout tutorials.
        provenance:
          $ref: '#/components/schemas/ReasonProvenance'
        fact_id:
          description: Stored profile fact backing this reason, or null.
          type:
            - string
            - 'null'
        source_post_id:
          description: >-
            Identifier of the source post supporting this reason, or null for non-post-backed reasons. This identifier
            is not a public post URL.
          type:
            - string
            - 'null'
        evidence_quote:
          description: >-
            Supporting text copied verbatim from a source post caption or transcript. Present for `post_evidence`
            reasons when a supporting quote is available; otherwise null.
          example: Here are three bodyweight exercises for a quick home workout.
          type:
            - string
            - 'null'
      required:
        - text
        - provenance
        - fact_id
        - source_post_id
        - evidence_quote
      additionalProperties: false
      description: A single evidence-grounded match reason.
    SearchError402:
      description: Account billing requires attention, or remaining credits cannot cover this search.
      $ref: '#/components/schemas/ApiCreditError402'
    ProfileResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/ProfileResponseData'
        warning:
          description: >-
            Present when partial results were returned because profile metrics/data were skipped due to integrity
            issues.
          type: string
      required:
        - data
      additionalProperties: false
    ProfileResponseData:
      type: object
      properties:
        id:
          type: string
          format: uuid
          pattern: >-
            ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
          description: Profile unique identifier
          example: 123e4567-e89b-12d3-a456-426614174000
        creator_id:
          type: string
          format: uuid
          pattern: >-
            ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
          description: Creator unique identifier
          example: 123e4567-e89b-12d3-a456-426614174001
        platform:
          $ref: '#/components/schemas/Platform'
        username:
          type: string
          description: Profile username
          example: fitness_coach_jane
        display_name:
          description: Display name
          example: Jane Fitness
          type:
            - string
            - 'null'
        bio:
          description: Profile bio
          example: Fitness coach & wellness advocate
          type:
            - string
            - 'null'
        avatar_url:
          description: Avatar URL
          example: https://cdn.example.com/avatars/jane.jpg
          type:
            - string
            - 'null'
        url:
          type: string
          format: uri
          description: Profile URL
          example: https://www.instagram.com/fitness_coach_jane
        external_url:
          description: External website URL from bio
          example: https://janefitness.com
          type:
            - string
            - 'null'
        is_verified:
          type: boolean
          description: Whether the account is verified
          example: true
        is_business:
          type: boolean
          description: Whether this is a business account
          example: true
        is_private:
          type: boolean
          description: Whether the account is private
          example: false
        category:
          description: Account category
          example: Health/Beauty
          type:
            - string
            - 'null'
        pronouns:
          type:
            - array
            - 'null'
          items:
            type: string
          description: Listed pronouns
          example:
            - she
            - her
        metrics:
          $ref: '#/components/schemas/ProfileMetrics'
        growth:
          $ref: '#/components/schemas/ProfileGrowth'
        activity:
          $ref: '#/components/schemas/ProfileActivity'
        data_updated_at:
          type:
            - string
            - 'null'
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$
          description: Last data refresh timestamp
          example: '2024-01-15T14:30:00Z'
      required:
        - id
        - creator_id
        - platform
        - username
        - display_name
        - bio
        - avatar_url
        - url
        - external_url
        - is_verified
        - is_business
        - is_private
        - category
        - pronouns
        - metrics
        - growth
        - activity
        - data_updated_at
      additionalProperties: false
      description: Full profile details
    ProfileMetrics:
      type: object
      properties:
        followers:
          type: integer
          minimum: 0
          maximum: 9007199254740991
          description: Follower count
          example: 125000
        following:
          type: integer
          minimum: 0
          maximum: 9007199254740991
          description: Following count
          example: 1200
        posts:
          type: integer
          minimum: 0
          maximum: 9007199254740991
          description: Total post count
          example: 450
        posts_last_30d:
          type: integer
          minimum: 0
          maximum: 9007199254740991
          description: Posts in the last 30 days
          example: 12
        engagement_rate:
          type:
            - number
            - 'null'
          minimum: 0
          description: Engagement rate as a percentage, null if unknown (e.g. 3.5 means 3.5%)
          example: 3.5
        avg_likes_recent:
          type: number
          minimum: 0
          description: Average likes on recent posts
          example: 4500
        avg_comments_recent:
          type: number
          minimum: 0
          description: Average comments on recent posts
          example: 120
        avg_views_recent:
          type:
            - number
            - 'null'
          minimum: 0
          description: Average views on recent posts (for video content)
          example: 15000
        posts_per_week:
          type: number
          minimum: 0
          description: Average posts per week
          example: 2.5
      required:
        - followers
        - following
        - posts
        - posts_last_30d
        - engagement_rate
        - avg_likes_recent
        - avg_comments_recent
        - avg_views_recent
        - posts_per_week
      additionalProperties: false
      description: Profile performance metrics
    ProfileGrowth:
      type: object
      properties:
        followers_30d_pct:
          type: number
          description: Follower growth percentage over 30 days (e.g. 2.5 means +2.5%)
          example: 2.5
      required:
        - followers_30d_pct
      additionalProperties: false
      description: Profile growth statistics
    ProfileActivity:
      type: object
      properties:
        last_post_at:
          type:
            - string
            - 'null'
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$
          description: Timestamp of last post
          example: '2024-01-15T14:30:00Z'
      required:
        - last_post_at
      additionalProperties: false
      description: Profile activity information
    ProfilesLookupResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/ProfileResponseData'
          description: Profiles that were found
        not_found:
          type: array
          items:
            $ref: '#/components/schemas/ProfileNotFoundItem'
          description: Profiles that were not found
      required:
        - data
        - not_found
      additionalProperties: false
    ProfileNotFoundItem:
      type: object
      properties:
        platform:
          $ref: '#/components/schemas/Platform'
        username:
          type: string
          example: unknown_user
      required:
        - platform
        - username
      additionalProperties: false
    PostsResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/PostsResponseData'
        has_more:
          type: boolean
          description: Whether more results are available
          example: true
        next_cursor:
          description: Opaque keyset cursor for the next page. Reuse it with the same sort value that produced it.
          example: >-
            eyJzb3J0IjoicmVjZW50IiwiaWQiOiIxMjNlNDU2Ny1lODliLTEyZDMtYTQ1Ni00MjY2MTQxNzQwMDAiLCJ2YWx1ZSI6IjIwMjYtMDctMDlUMTI6MDA6MDAuMDAwWiJ9
          type:
            - string
            - 'null'
      required:
        - data
        - has_more
        - next_cursor
      additionalProperties: false
    PostsResponseData:
      type: array
      items:
        $ref: '#/components/schemas/PostResponseData'
    PostResponseData:
      type: object
      properties:
        id:
          type: string
          format: uuid
          pattern: >-
            ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
          description: Post unique identifier
          example: 123e4567-e89b-12d3-a456-426614174000
        profile_id:
          type: string
          format: uuid
          pattern: >-
            ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
          description: Profile unique identifier
          example: 123e4567-e89b-12d3-a456-426614174001
        platform:
          $ref: '#/components/schemas/Platform'
        platform_id:
          type: string
          description: Platform-specific post ID
          example: CxYz123ABC
        url:
          type: string
          format: uri
          description: Post URL
          example: https://www.instagram.com/p/CxYz123ABC
        posted_at:
          type: string
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$
          description: Post timestamp
          example: '2024-01-15T14:30:00Z'
        type:
          $ref: '#/components/schemas/PostType'
        caption:
          description: Post caption
          example: Starting the week with a killer workout! 💪
          type:
            - string
            - 'null'
        media:
          $ref: '#/components/schemas/PostMedia'
        metrics:
          $ref: '#/components/schemas/PostMetrics'
        hashtags:
          type: array
          items:
            type: string
          description: Hashtags used in the post
          example:
            - fitness
            - workout
            - motivation
        mentions:
          type: array
          items:
            type: string
          description: Usernames mentioned in the post
          example:
            - nike
            - gymshark
        location:
          anyOf:
            - $ref: '#/components/schemas/PostLocation'
            - type: 'null'
          description: Post location (if tagged)
      required:
        - id
        - profile_id
        - platform
        - platform_id
        - url
        - posted_at
        - type
        - caption
        - media
        - metrics
        - hashtags
        - mentions
        - location
      additionalProperties: false
      description: Full post details
    PostType:
      type: string
      enum:
        - image
        - video
        - carousel
        - reel
        - story
      description: Type of post
      example: image
    PostMedia:
      type: object
      properties:
        url:
          description: >-
            Cover/primary image URL for image and carousel posts. A durable hosted image URL when one is available;
            otherwise the platform image URL, which expires, so download it promptly. Null for video posts — call GET
            /v1/raw/instagram/post/{shortcode} for a fresh, downloadable video URL.
          example: https://cdn.example.com/media/post123.jpg
          type:
            - string
            - 'null'
        thumbnail_url:
          description: >-
            Thumbnail URL. For videos, this is the cover frame. A durable hosted image URL when one is available;
            otherwise the platform thumbnail URL, which expires. If a video has no hosted cover and its platform cover
            has expired, this is a hosted frame from the video.
          example: https://cdn.example.com/thumbnails/post123.jpg
          type:
            - string
            - 'null'
        duration_seconds:
          description: Video duration in seconds. Null for non-video posts.
          example: 45
          type:
            - number
            - 'null'
        carousel_items:
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/PostMediaCarouselItem'
          description: >-
            Per-item structure for carousel posts. Null for non-carousel posts. Per-item video_url is intentionally
            omitted (would be stale). For fresh video URLs, call GET /v1/raw/instagram/post/{shortcode}.
      required:
        - url
        - thumbnail_url
        - duration_seconds
        - carousel_items
      additionalProperties: false
      description: Post media information
    PostMediaCarouselItem:
      type: object
      properties:
        index:
          type: integer
          minimum: 0
          maximum: 9007199254740991
          description: Zero-based position in the carousel.
          example: 0
        is_video:
          type: boolean
          description: True if this item is a video.
          example: false
        thumbnail_url:
          description: >-
            Thumbnail URL for this item. Cover frame for videos. A durable hosted image URL when one is available;
            otherwise the platform thumbnail URL, which expires.
          example: https://cdn.example.com/thumbnails/carousel_0.jpg
          type:
            - string
            - 'null'
      required:
        - index
        - is_video
        - thumbnail_url
      additionalProperties: false
    PostMetrics:
      type: object
      properties:
        likes:
          type:
            - integer
            - 'null'
          minimum: 0
          maximum: 9007199254740991
          description: Like count
          example: 4500
        comments:
          type:
            - integer
            - 'null'
          minimum: 0
          maximum: 9007199254740991
          description: Comment count
          example: 120
        views:
          type:
            - integer
            - 'null'
          minimum: 0
          maximum: 9007199254740991
          description: View count (for video content)
          example: 15000
        shares:
          type:
            - integer
            - 'null'
          minimum: 0
          maximum: 9007199254740991
          description: Share count
          example: 50
        engagement_rate:
          description: Engagement rate for this post as a percentage (e.g. 3.8 means 3.8%)
          example: 3.8
          type:
            - number
            - 'null'
      required:
        - likes
        - comments
        - views
        - shares
        - engagement_rate
      additionalProperties: false
      description: Post engagement metrics
    PostLocation:
      type: object
      properties:
        name:
          description: Location name
          example: Los Angeles, California
          type:
            - string
            - 'null'
      required:
        - name
      additionalProperties: false
      description: Post location information
    LiveProfileResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            username:
              type: string
            user_id:
              type: string
            full_name:
              type: string
            biography:
              type: string
            follower_count:
              type: number
            following_count:
              type: number
            media_count:
              description: >-
                Total profile media count, or null when unavailable. Zero means an observed empty profile; this is not
                the number of posts returned.
              type:
                - number
                - 'null'
            is_verified:
              type: boolean
            is_private:
              type: boolean
            profile_pic_url:
              type: string
              format: uri
            profile_pic_url_hd:
              type: string
              format: uri
            external_url:
              type:
                - string
                - 'null'
              format: uri
            bio_links:
              type: array
              items:
                type: object
                properties:
                  title:
                    type: string
                  url:
                    type: string
                    format: uri
                  link_type:
                    type: string
                required:
                  - title
                  - url
                additionalProperties: false
            pronouns:
              type: array
              items:
                type: string
            category_name:
              type:
                - string
                - 'null'
            engagement_rate:
              description: Observed engagement rate, or null without a measurable sample.
              type:
                - number
                - 'null'
            posts:
              type: array
              items:
                type: object
                properties:
                  id:
                    type: string
                  shortcode:
                    type: string
                  owner_username:
                    type: string
                  owner_id:
                    type: string
                    pattern: ^[1-9][0-9]{0,255}$
                  display_url:
                    type: string
                    format: uri
                  is_video:
                    type: boolean
                  post_type:
                    type: string
                    enum:
                      - image
                      - video
                      - carousel
                  share_count:
                    type: integer
                    minimum: 0
                    maximum: 9007199254740991
                  save_count:
                    type: integer
                    minimum: 0
                    maximum: 9007199254740991
                  like_count:
                    type:
                      - integer
                      - 'null'
                    minimum: 0
                    maximum: 9007199254740991
                    description: Observed likes, or null when hidden.
                  comment_count:
                    type: integer
                    minimum: 0
                    maximum: 9007199254740991
                  caption:
                    type:
                      - string
                      - 'null'
                  taken_at:
                    type:
                      - number
                      - 'null'
                  accessibility_caption:
                    type:
                      - string
                      - 'null'
                  video_url:
                    type: string
                    format: uri
                  thumbnail_url:
                    type: string
                    format: uri
                  view_count:
                    type: number
                  carousel_items:
                    type: array
                    items:
                      type: object
                      properties:
                        platform_media_id:
                          type: string
                          minLength: 1
                        index:
                          type: number
                        display_url:
                          type: string
                          format: uri
                        is_video:
                          type: boolean
                        video_url:
                          type: string
                          format: uri
                        thumbnail_url:
                          type: string
                          format: uri
                      required:
                        - index
                        - display_url
                        - is_video
                      additionalProperties: false
                  carousel_manifest:
                    description: >-
                      Observed carousel child positions, identities and media types, including children whose media URLs
                      are unavailable.
                    maxItems: 100
                    type: array
                    items:
                      type: object
                      properties:
                        index:
                          type: integer
                          minimum: 0
                          maximum: 99
                        platform_media_id:
                          type: string
                          minLength: 1
                        is_video:
                          type: boolean
                      required:
                        - index
                        - is_video
                      additionalProperties: false
                  carousel_media_count:
                    description: >-
                      Total carousel media count when available. Some children may be absent from carousel_items if
                      unavailable.
                    type: integer
                    minimum: 0
                    maximum: 100
                  coauthor_usernames:
                    type: array
                    items:
                      type: string
                  is_paid_partnership:
                    type:
                      - boolean
                      - 'null'
                  sponsor_usernames:
                    type: array
                    items:
                      type: string
                  tagged_usernames:
                    type: array
                    items:
                      type: string
                  product_mentions:
                    type: array
                    items:
                      type: object
                      properties:
                        product_id:
                          type:
                            - string
                            - 'null'
                        product_name:
                          type:
                            - string
                            - 'null'
                        merchant_username:
                          type:
                            - string
                            - 'null'
                      additionalProperties: false
                  display_resources:
                    type: array
                    items:
                      type: object
                      properties:
                        src:
                          type: string
                          format: uri
                        config_width:
                          type: number
                        config_height:
                          type: number
                      required:
                        - src
                        - config_width
                        - config_height
                      additionalProperties: false
                  video_versions:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: string
                        type:
                          type: number
                        url:
                          type: string
                          format: uri
                        width:
                          type: number
                        height:
                          type: number
                      required:
                        - url
                      additionalProperties: false
                  music_attribution:
                    type:
                      - object
                      - 'null'
                    properties:
                      artist_name:
                        type:
                          - string
                          - 'null'
                      song_name:
                        type:
                          - string
                          - 'null'
                      audio_id:
                        type:
                          - string
                          - 'null'
                      uses_original_audio:
                        type:
                          - boolean
                          - 'null'
                      should_mute_audio:
                        type:
                          - boolean
                          - 'null'
                    additionalProperties: false
                  location:
                    type:
                      - object
                      - 'null'
                    properties:
                      id:
                        type:
                          - string
                          - 'null'
                      name:
                        type:
                          - string
                          - 'null'
                      slug:
                        type:
                          - string
                          - 'null'
                      has_public_page:
                        type:
                          - boolean
                          - 'null'
                      lat:
                        type:
                          - number
                          - 'null'
                      lng:
                        type:
                          - number
                          - 'null'
                      address_json:
                        type:
                          - object
                          - 'null'
                        properties: {}
                        additionalProperties:
                          x-stainless-any: true
                    additionalProperties: false
                  is_pinned:
                    type:
                      - boolean
                      - 'null'
                  engagement_visibility:
                    type:
                      - object
                      - 'null'
                    properties:
                      viewer_can_reshare:
                        type:
                          - boolean
                          - 'null'
                      comments_disabled:
                        type:
                          - boolean
                          - 'null'
                      like_and_view_counts_disabled:
                        type:
                          - boolean
                          - 'null'
                    additionalProperties: false
                required:
                  - id
                  - shortcode
                  - display_url
                  - is_video
                  - post_type
                  - like_count
                  - comment_count
                  - caption
                  - taken_at
                additionalProperties: false
            related_profiles:
              type: array
              items:
                type: object
                properties:
                  username:
                    type: string
                  full_name:
                    type:
                      - string
                      - 'null'
                  profile_pic_url:
                    type:
                      - string
                      - 'null'
                    format: uri
                  is_verified:
                    type: boolean
                  is_private:
                    type: boolean
                required:
                  - username
                  - full_name
                  - profile_pic_url
                  - is_verified
                  - is_private
                additionalProperties: false
            scraped_at:
              type: string
              format: date-time
              pattern: >-
                ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z))$
          required:
            - username
            - user_id
            - full_name
            - biography
            - follower_count
            - following_count
            - media_count
            - is_verified
            - is_private
            - profile_pic_url
            - external_url
            - bio_links
            - pronouns
            - category_name
            - engagement_rate
            - posts
            - related_profiles
            - scraped_at
          additionalProperties: false
      required:
        - data
      additionalProperties: false
    Error502:
      description: >-
        The upstream source answered, but with data this endpoint cannot process — for example a response schema the
        source has retired. Unlike 503 this is deterministic: the same request will keep failing until a fix ships, so
        it never carries Retry-After and retrying only burns credits. These are alerted on automatically.
      examples:
        - error:
            code: upstream_contract_broken
            message: >-
              The upstream source returned data this endpoint cannot process. This is not retryable; it has been
              reported.
            request_id: 550e8400-e29b-41d4-a716-446655440000
            details:
              upstream_error: upstream_contract_broken
              retryable: false
      $ref: '#/components/schemas/Error'
    LiveInstagramPostResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/InstagramSinglePostResponse'
      required:
        - data
      additionalProperties: false
      description: >-
        A validated Instagram post with available media and observed engagement. Unavailable or gated media returns a
        temporary failure rather than an empty post or proof of deletion. Hidden or unavailable video views are omitted.
    InstagramSinglePostResponse:
      type: object
      properties:
        post:
          type: object
          properties:
            id:
              type: string
            shortcode:
              type: string
            owner_username:
              type: string
            owner_id:
              type: string
              pattern: ^[1-9][0-9]{0,255}$
            display_url:
              type: string
              format: uri
            is_video:
              type: boolean
            post_type:
              type: string
              enum:
                - image
                - video
                - carousel
            share_count:
              type: integer
              minimum: 0
              maximum: 9007199254740991
            save_count:
              type: integer
              minimum: 0
              maximum: 9007199254740991
            like_count:
              type:
                - integer
                - 'null'
              minimum: 0
              maximum: 9007199254740991
              description: Observed likes, or null when hidden.
            comment_count:
              type: integer
              minimum: 0
              maximum: 9007199254740991
            caption:
              type:
                - string
                - 'null'
            taken_at:
              type:
                - number
                - 'null'
            accessibility_caption:
              type:
                - string
                - 'null'
            video_url:
              type: string
              format: uri
            thumbnail_url:
              type: string
              format: uri
            view_count:
              type: number
            carousel_items:
              type: array
              items:
                type: object
                properties:
                  platform_media_id:
                    type: string
                    minLength: 1
                  index:
                    type: number
                  display_url:
                    type: string
                    format: uri
                  is_video:
                    type: boolean
                  video_url:
                    type: string
                    format: uri
                  thumbnail_url:
                    type: string
                    format: uri
                required:
                  - index
                  - display_url
                  - is_video
                additionalProperties: false
            carousel_manifest:
              description: >-
                Observed carousel child positions, identities and media types, including children whose media URLs are
                unavailable.
              maxItems: 100
              type: array
              items:
                type: object
                properties:
                  index:
                    type: integer
                    minimum: 0
                    maximum: 99
                  platform_media_id:
                    type: string
                    minLength: 1
                  is_video:
                    type: boolean
                required:
                  - index
                  - is_video
                additionalProperties: false
            carousel_media_count:
              description: >-
                Total carousel media count when available. Some children may be absent from carousel_items if
                unavailable.
              type: integer
              minimum: 0
              maximum: 100
            coauthor_usernames:
              type: array
              items:
                type: string
            is_paid_partnership:
              type:
                - boolean
                - 'null'
            sponsor_usernames:
              type: array
              items:
                type: string
            tagged_usernames:
              type: array
              items:
                type: string
            product_mentions:
              type: array
              items:
                type: object
                properties:
                  product_id:
                    type:
                      - string
                      - 'null'
                  product_name:
                    type:
                      - string
                      - 'null'
                  merchant_username:
                    type:
                      - string
                      - 'null'
                additionalProperties: false
            display_resources:
              type: array
              items:
                type: object
                properties:
                  src:
                    type: string
                    format: uri
                  config_width:
                    type: number
                  config_height:
                    type: number
                required:
                  - src
                  - config_width
                  - config_height
                additionalProperties: false
            video_versions:
              type: array
              items:
                type: object
                properties:
                  id:
                    type: string
                  type:
                    type: number
                  url:
                    type: string
                    format: uri
                  width:
                    type: number
                  height:
                    type: number
                required:
                  - url
                additionalProperties: false
            music_attribution:
              type:
                - object
                - 'null'
              properties:
                artist_name:
                  type:
                    - string
                    - 'null'
                song_name:
                  type:
                    - string
                    - 'null'
                audio_id:
                  type:
                    - string
                    - 'null'
                uses_original_audio:
                  type:
                    - boolean
                    - 'null'
                should_mute_audio:
                  type:
                    - boolean
                    - 'null'
              additionalProperties: false
            location:
              type:
                - object
                - 'null'
              properties:
                id:
                  type:
                    - string
                    - 'null'
                name:
                  type:
                    - string
                    - 'null'
                slug:
                  type:
                    - string
                    - 'null'
                has_public_page:
                  type:
                    - boolean
                    - 'null'
                lat:
                  type:
                    - number
                    - 'null'
                lng:
                  type:
                    - number
                    - 'null'
                address_json:
                  type:
                    - object
                    - 'null'
                  properties: {}
                  additionalProperties:
                    x-stainless-any: true
              additionalProperties: false
            is_pinned:
              type:
                - boolean
                - 'null'
            engagement_visibility:
              type:
                - object
                - 'null'
              properties:
                viewer_can_reshare:
                  type:
                    - boolean
                    - 'null'
                comments_disabled:
                  type:
                    - boolean
                    - 'null'
                like_and_view_counts_disabled:
                  type:
                    - boolean
                    - 'null'
              additionalProperties: false
          required:
            - id
            - shortcode
            - display_url
            - is_video
            - post_type
            - like_count
            - comment_count
            - caption
            - taken_at
          additionalProperties: false
        scraped_at:
          type: string
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z))$
      required:
        - post
        - scraped_at
      additionalProperties: false
    LiveInstagramPostBatchResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/InstagramPostBatchResponse'
      required:
        - data
      additionalProperties: false
    InstagramPostBatchResponse:
      type: object
      properties:
        requested:
          type: number
        succeeded:
          type: number
        failed:
          type: number
        items:
          type: array
          items:
            $ref: '#/components/schemas/InstagramPostBatchItem'
        scraped_at:
          type: string
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z))$
      required:
        - requested
        - succeeded
        - failed
        - items
        - scraped_at
      additionalProperties: false
    InstagramPostBatchItem:
      oneOf:
        - $ref: '#/components/schemas/InstagramPostBatchSuccessItem'
        - $ref: '#/components/schemas/InstagramPostBatchErrorItem'
      type: object
      discriminator:
        propertyName: success
        mapping:
          'true': '#/components/schemas/InstagramPostBatchSuccessItem'
          'false': '#/components/schemas/InstagramPostBatchErrorItem'
    InstagramPostBatchSuccessItem:
      type: object
      properties:
        success:
          type: boolean
          const: true
        shortcode:
          type: string
        data:
          $ref: '#/components/schemas/InstagramSinglePostResponse'
      required:
        - success
        - shortcode
        - data
      additionalProperties: false
    InstagramPostBatchErrorItem:
      type: object
      properties:
        success:
          type: boolean
          const: false
        shortcode:
          type: string
        status:
          type: number
        error:
          $ref: '#/components/schemas/RawScraperError'
      required:
        - success
        - shortcode
        - status
        - error
      additionalProperties: false
    RawScraperError:
      type: object
      properties:
        error:
          type: string
          enum:
            - not_found
            - private
            - rate_limited
            - blocked
            - invalid_input
            - timeout
            - upstream_unavailable
            - upstream_contract_broken
            - unknown
        message:
          type: string
        username:
          type: string
        retry_after:
          type: number
      required:
        - error
        - message
      additionalProperties: false
    LiveInstagramTranscriptResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/InstagramTranscriptResponse'
      required:
        - data
      additionalProperties: false
    InstagramTranscriptResponse:
      type: object
      properties:
        shortcode:
          type: string
        post:
          type: object
          properties:
            id:
              type: string
            shortcode:
              type: string
            owner_username:
              type: string
            owner_id:
              type: string
              pattern: ^[1-9][0-9]{0,255}$
            display_url:
              type: string
              format: uri
            is_video:
              type: boolean
            post_type:
              type: string
              enum:
                - image
                - video
                - carousel
            share_count:
              type: integer
              minimum: 0
              maximum: 9007199254740991
            save_count:
              type: integer
              minimum: 0
              maximum: 9007199254740991
            like_count:
              type:
                - integer
                - 'null'
              minimum: 0
              maximum: 9007199254740991
              description: Observed likes, or null when hidden.
            comment_count:
              type: integer
              minimum: 0
              maximum: 9007199254740991
            caption:
              type:
                - string
                - 'null'
            taken_at:
              type:
                - number
                - 'null'
            accessibility_caption:
              type:
                - string
                - 'null'
            video_url:
              type: string
              format: uri
            thumbnail_url:
              type: string
              format: uri
            view_count:
              type: number
            carousel_items:
              type: array
              items:
                type: object
                properties:
                  platform_media_id:
                    type: string
                    minLength: 1
                  index:
                    type: number
                  display_url:
                    type: string
                    format: uri
                  is_video:
                    type: boolean
                  video_url:
                    type: string
                    format: uri
                  thumbnail_url:
                    type: string
                    format: uri
                required:
                  - index
                  - display_url
                  - is_video
                additionalProperties: false
            carousel_manifest:
              description: >-
                Observed carousel child positions, identities and media types, including children whose media URLs are
                unavailable.
              maxItems: 100
              type: array
              items:
                type: object
                properties:
                  index:
                    type: integer
                    minimum: 0
                    maximum: 99
                  platform_media_id:
                    type: string
                    minLength: 1
                  is_video:
                    type: boolean
                required:
                  - index
                  - is_video
                additionalProperties: false
            carousel_media_count:
              description: >-
                Total carousel media count when available. Some children may be absent from carousel_items if
                unavailable.
              type: integer
              minimum: 0
              maximum: 100
            coauthor_usernames:
              type: array
              items:
                type: string
            is_paid_partnership:
              type:
                - boolean
                - 'null'
            sponsor_usernames:
              type: array
              items:
                type: string
            tagged_usernames:
              type: array
              items:
                type: string
            product_mentions:
              type: array
              items:
                type: object
                properties:
                  product_id:
                    type:
                      - string
                      - 'null'
                  product_name:
                    type:
                      - string
                      - 'null'
                  merchant_username:
                    type:
                      - string
                      - 'null'
                additionalProperties: false
            display_resources:
              type: array
              items:
                type: object
                properties:
                  src:
                    type: string
                    format: uri
                  config_width:
                    type: number
                  config_height:
                    type: number
                required:
                  - src
                  - config_width
                  - config_height
                additionalProperties: false
            video_versions:
              type: array
              items:
                type: object
                properties:
                  id:
                    type: string
                  type:
                    type: number
                  url:
                    type: string
                    format: uri
                  width:
                    type: number
                  height:
                    type: number
                required:
                  - url
                additionalProperties: false
            music_attribution:
              type:
                - object
                - 'null'
              properties:
                artist_name:
                  type:
                    - string
                    - 'null'
                song_name:
                  type:
                    - string
                    - 'null'
                audio_id:
                  type:
                    - string
                    - 'null'
                uses_original_audio:
                  type:
                    - boolean
                    - 'null'
                should_mute_audio:
                  type:
                    - boolean
                    - 'null'
              additionalProperties: false
            location:
              type:
                - object
                - 'null'
              properties:
                id:
                  type:
                    - string
                    - 'null'
                name:
                  type:
                    - string
                    - 'null'
                slug:
                  type:
                    - string
                    - 'null'
                has_public_page:
                  type:
                    - boolean
                    - 'null'
                lat:
                  type:
                    - number
                    - 'null'
                lng:
                  type:
                    - number
                    - 'null'
                address_json:
                  type:
                    - object
                    - 'null'
                  properties: {}
                  additionalProperties:
                    x-stainless-any: true
              additionalProperties: false
            is_pinned:
              type:
                - boolean
                - 'null'
            engagement_visibility:
              type:
                - object
                - 'null'
              properties:
                viewer_can_reshare:
                  type:
                    - boolean
                    - 'null'
                comments_disabled:
                  type:
                    - boolean
                    - 'null'
                like_and_view_counts_disabled:
                  type:
                    - boolean
                    - 'null'
              additionalProperties: false
          required:
            - id
            - shortcode
            - display_url
            - is_video
            - post_type
            - like_count
            - comment_count
            - caption
            - taken_at
          additionalProperties: false
        transcript:
          type: string
        full_text:
          type: string
        word_count:
          type: number
        language:
          type: string
        duration_seconds:
          type: number
        scraped_at:
          type: string
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z))$
      required:
        - shortcode
        - transcript
        - full_text
        - word_count
        - language
        - scraped_at
      additionalProperties: false
    LiveInstagramTranscriptBatchResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/InstagramTranscriptBatchResponse'
      required:
        - data
      additionalProperties: false
    InstagramTranscriptBatchResponse:
      type: object
      properties:
        requested:
          type: number
        succeeded:
          type: number
        failed:
          type: number
        items:
          type: array
          items:
            $ref: '#/components/schemas/InstagramTranscriptBatchItem'
        scraped_at:
          type: string
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z))$
      required:
        - requested
        - succeeded
        - failed
        - items
        - scraped_at
      additionalProperties: false
    InstagramTranscriptBatchItem:
      oneOf:
        - $ref: '#/components/schemas/InstagramTranscriptBatchSuccessItem'
        - $ref: '#/components/schemas/InstagramTranscriptBatchErrorItem'
      type: object
      discriminator:
        propertyName: success
        mapping:
          'true': '#/components/schemas/InstagramTranscriptBatchSuccessItem'
          'false': '#/components/schemas/InstagramTranscriptBatchErrorItem'
    InstagramTranscriptBatchSuccessItem:
      type: object
      properties:
        success:
          type: boolean
          const: true
        shortcode:
          type: string
        data:
          $ref: '#/components/schemas/InstagramTranscriptResponse'
      required:
        - success
        - shortcode
        - data
      additionalProperties: false
    InstagramTranscriptBatchErrorItem:
      type: object
      properties:
        success:
          type: boolean
          const: false
        shortcode:
          type: string
        status:
          type: number
        error:
          $ref: '#/components/schemas/RawScraperError'
      required:
        - success
        - shortcode
        - status
        - error
      additionalProperties: false
    LiveYouTubeChannelResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/LiveYouTubeChannelResponseData'
      required:
        - data
      additionalProperties: false
    LiveYouTubeChannelResponseData:
      type: object
      properties:
        channel_id:
          type: string
          description: YouTube channel ID
          example: UCBJycsmduvYEL83R_U4JriQ
        handle:
          description: Channel handle (without @)
          example: mkbhd
          type:
            - string
            - 'null'
        name:
          type: string
          description: Channel name
          example: Marques Brownlee
        description:
          type: string
          description: Channel description
        avatar_url:
          description: Channel avatar URL
          type:
            - string
            - 'null'
        banner_url:
          description: Channel banner image URL
          type:
            - string
            - 'null'
        country:
          description: Channel country code
          example: US
          type:
            - string
            - 'null'
        keywords:
          type: array
          items:
            type: string
          description: Channel keywords / tags
        subscribers:
          type:
            - integer
            - 'null'
          minimum: 0
          maximum: 9007199254740991
          description: Subscriber count
          example: 20900000
        subscribers_text:
          description: Subscriber count text as displayed by YouTube
          example: 20.9M subscribers
          type:
            - string
            - 'null'
        videos_count:
          type:
            - integer
            - 'null'
          minimum: 0
          maximum: 9007199254740991
          description: Total video count
          example: 1500
        views_total:
          type:
            - integer
            - 'null'
          minimum: 0
          maximum: 9007199254740991
          description: Total view count across all videos
          example: 4500000000
        videos:
          type: array
          items:
            $ref: '#/components/schemas/YouTubeVideo'
          description: Recent videos (empty when include_videos=false)
        scraped_at:
          type: string
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$
          description: When this data was scraped
          example: '2024-01-15T14:30:00Z'
      required:
        - channel_id
        - handle
        - name
        - description
        - avatar_url
        - banner_url
        - country
        - keywords
        - subscribers
        - subscribers_text
        - videos_count
        - views_total
        - videos
        - scraped_at
      additionalProperties: false
    YouTubeVideo:
      type: object
      properties:
        video_id:
          type: string
          description: YouTube video ID
          example: dQw4w9WgXcQ
        title:
          type: string
          description: Video title
          example: Full Body Workout | 30 Minutes
        url:
          type: string
          description: Video URL
          example: https://www.youtube.com/watch?v=dQw4w9WgXcQ
        thumbnail_url:
          description: Thumbnail URL
          type:
            - string
            - 'null'
        published_text:
          description: Relative publish time as displayed by YouTube
          example: 2 weeks ago
          type:
            - string
            - 'null'
        duration_seconds:
          type:
            - integer
            - 'null'
          minimum: 0
          maximum: 9007199254740991
          description: Video duration in seconds
          example: 1845
        duration_text:
          description: Video duration text (e.g., "30:45")
          example: '30:45'
          type:
            - string
            - 'null'
        view_count:
          type:
            - integer
            - 'null'
          minimum: 0
          maximum: 9007199254740991
          description: View count
          example: 125000
        view_count_text:
          description: View count text as displayed by YouTube
          example: 125K views
          type:
            - string
            - 'null'
      required:
        - video_id
        - title
        - url
        - thumbnail_url
        - published_text
        - duration_seconds
        - duration_text
        - view_count
        - view_count_text
      additionalProperties: false
    YouTubeVideoDetailsResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/YouTubeVideoDetailsResponseData'
      required:
        - data
      additionalProperties: false
    YouTubeVideoDetailsResponseData:
      type: object
      properties:
        video_id:
          type: string
        url:
          type: string
        title:
          type: string
        description:
          type: string
        channel_id:
          type:
            - string
            - 'null'
        channel_name:
          type:
            - string
            - 'null'
        channel_handle:
          type:
            - string
            - 'null'
        thumbnail_url:
          type:
            - string
            - 'null'
        duration_seconds:
          type:
            - number
            - 'null'
          minimum: 0
        view_count:
          type:
            - integer
            - 'null'
          minimum: 0
          maximum: 9007199254740991
        like_count:
          type:
            - integer
            - 'null'
          minimum: 0
          maximum: 9007199254740991
        comment_count:
          type:
            - integer
            - 'null'
          minimum: 0
          maximum: 9007199254740991
        published_at:
          type:
            - string
            - 'null'
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$
          description: Exact publish timestamp when supplied by YouTube, otherwise null
        published_date:
          description: Publish date in YYYY-MM-DD format when available
          type:
            - string
            - 'null'
        tags:
          type: array
          items:
            type: string
        categories:
          type: array
          items:
            type: string
        availability:
          type:
            - string
            - 'null'
        live_status:
          type:
            - string
            - 'null'
        scraped_at:
          type: string
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$
      required:
        - video_id
        - url
        - title
        - description
        - channel_id
        - channel_name
        - channel_handle
        - thumbnail_url
        - duration_seconds
        - view_count
        - like_count
        - comment_count
        - published_at
        - published_date
        - tags
        - categories
        - availability
        - live_status
        - scraped_at
      additionalProperties: false
    LiveTranscriptResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/YouTubeTranscriptResponseData'
      required:
        - data
      additionalProperties: false
    YouTubeTranscriptResponseData:
      type: object
      properties:
        video_id:
          type: string
          description: Video ID
          example: dQw4w9WgXcQ
        url:
          type: string
          description: Video URL
          example: https://www.youtube.com/watch?v=dQw4w9WgXcQ
        title:
          type: string
          description: Video title
          example: Full Body Workout | 30 Minutes
        language:
          type: string
          description: Transcript language code
          example: en
        source:
          type: string
          enum:
            - manual
            - auto_generated
          description: Caption source — manual subtitles or auto-generated
          example: manual
        transcript:
          type: array
          items:
            $ref: '#/components/schemas/TranscriptSegment'
          description: Transcript segments
        full_text:
          type: string
          description: Full transcript as plain text
        word_count:
          type: integer
          minimum: 0
          maximum: 9007199254740991
          description: Total word count
          example: 1245
        available_languages:
          type: array
          items:
            $ref: '#/components/schemas/TranscriptAvailableLanguage'
          description: All caption tracks available on this video
        scraped_at:
          type: string
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$
          description: When this data was scraped
          example: '2024-01-15T14:30:00Z'
      required:
        - video_id
        - url
        - title
        - language
        - source
        - transcript
        - full_text
        - word_count
        - available_languages
        - scraped_at
      additionalProperties: false
    TranscriptSegment:
      type: object
      properties:
        text:
          type: string
          description: Segment text
          example: Welcome to my channel!
        start:
          type: number
          minimum: 0
          description: Start time in seconds
          example: 0.5
        duration:
          type: number
          minimum: 0
          description: Duration in seconds
          example: 2.3
      required:
        - text
        - start
        - duration
      additionalProperties: false
    TranscriptAvailableLanguage:
      type: object
      properties:
        code:
          type: string
          description: Language code (e.g., "en", "es", "en-orig")
          example: en
        name:
          type: string
          description: Human-readable language name
          example: English
        is_auto:
          type: boolean
          description: Whether this track is auto-generated
          example: false
      required:
        - code
        - name
        - is_auto
      additionalProperties: false
    LiveChannelTranscriptsResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/LiveChannelTranscriptsResponseData'
      required:
        - data
      additionalProperties: false
    LiveChannelTranscriptsResponseData:
      type: object
      properties:
        channel_id:
          type: string
          description: YouTube channel ID
        handle:
          type: string
          description: Channel handle
          example: mkbhd
        channel_name:
          type: string
          description: Channel name
        videos_found:
          type: integer
          minimum: 0
          maximum: 9007199254740991
          description: Total videos found on channel
        transcripts_fetched:
          type: integer
          minimum: 0
          maximum: 9007199254740991
          description: Number of transcripts successfully fetched
        transcripts_failed:
          type: integer
          minimum: 0
          maximum: 9007199254740991
          description: Number of transcripts that failed to fetch
        items:
          type: array
          items:
            $ref: '#/components/schemas/ChannelTranscriptItem'
          description: Per-video transcript results
        scraped_at:
          type: string
          description: When this data was scraped
      required:
        - channel_id
        - handle
        - channel_name
        - videos_found
        - transcripts_fetched
        - transcripts_failed
        - items
        - scraped_at
      additionalProperties: false
    ChannelTranscriptItem:
      type: object
      properties:
        video_id:
          type: string
          description: YouTube video ID
          example: dQw4w9WgXcQ
        url:
          type: string
          description: Video URL
          example: https://www.youtube.com/watch?v=dQw4w9WgXcQ
        title:
          type: string
          description: Video title
        view_count:
          type:
            - number
            - 'null'
          minimum: 0
          description: View count
        published_text:
          description: Relative publish time
          type:
            - string
            - 'null'
        language:
          description: Transcript language code
          type:
            - string
            - 'null'
        source:
          type:
            - string
            - 'null'
          enum:
            - manual
            - auto_generated
          description: Caption source type
        full_text:
          description: Full transcript as plain text
          type:
            - string
            - 'null'
        word_count:
          type:
            - number
            - 'null'
          minimum: 0
          description: Word count of transcript
        transcript:
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/TranscriptSegment'
          description: Timestamped segments (only if include_segments=true)
        error:
          description: Error message if transcript fetch failed for this video
          type:
            - string
            - 'null'
      required:
        - video_id
        - url
        - title
        - view_count
        - published_text
        - language
        - source
        - full_text
        - word_count
        - transcript
        - error
      additionalProperties: false
    YouTubeSearchResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/YouTubeSearchResponseData'
      required:
        - data
      additionalProperties: false
    YouTubeSearchResponseData:
      type: object
      properties:
        query:
          type: string
          description: The search query
        estimated_results:
          type:
            - number
            - 'null'
          minimum: 0
          description: Estimated total results count
        results:
          type: array
          items:
            anyOf:
              - $ref: '#/components/schemas/YouTubeSearchVideoResult'
              - $ref: '#/components/schemas/YouTubeSearchChannelResult'
          description: Search results (videos and channels)
        next_cursor:
          description: Opaque cursor for the next page, or null when no next page is available
          type:
            - string
            - 'null'
        scraped_at:
          type: string
          description: When this search was performed
      required:
        - query
        - estimated_results
        - results
        - next_cursor
        - scraped_at
      additionalProperties: false
    YouTubeSearchVideoResult:
      type: object
      properties:
        type:
          type: string
          const: video
        video_id:
          type: string
          description: YouTube video ID
          example: dQw4w9WgXcQ
        url:
          type: string
          description: Full YouTube video URL
          example: https://www.youtube.com/watch?v=dQw4w9WgXcQ
        title:
          type: string
          description: Video title
        description:
          description: Video description snippet
          type:
            - string
            - 'null'
        channel_id:
          description: Channel ID
          type:
            - string
            - 'null'
        channel_name:
          description: Channel name
          type:
            - string
            - 'null'
        channel_handle:
          description: Channel handle (e.g., @username)
          type:
            - string
            - 'null'
        channel_verified:
          description: Whether channel is verified
          type:
            - boolean
            - 'null'
        thumbnail_url:
          description: Video thumbnail URL
          type:
            - string
            - 'null'
        duration_seconds:
          type:
            - number
            - 'null'
          minimum: 0
          description: Video duration in seconds
        duration_text:
          description: Video duration text (e.g., "12:34")
          type:
            - string
            - 'null'
        view_count:
          type:
            - number
            - 'null'
          minimum: 0
          description: Number of views
        view_count_text:
          description: View count text (e.g., "1.2M views")
          type:
            - string
            - 'null'
        published_text:
          description: Relative publish time (e.g., "2 days ago")
          type:
            - string
            - 'null'
        published_at:
          description: Approximate publish timestamp
          type:
            - string
            - 'null'
      required:
        - type
        - video_id
        - url
        - title
        - description
        - channel_id
        - channel_name
        - channel_handle
        - channel_verified
        - thumbnail_url
        - duration_seconds
        - duration_text
        - view_count
        - view_count_text
        - published_text
        - published_at
      additionalProperties: false
    YouTubeSearchChannelResult:
      type: object
      properties:
        type:
          type: string
          const: channel
        channel_id:
          type: string
          description: Channel ID
        url:
          type: string
          description: Full YouTube channel URL
          example: https://www.youtube.com/@channelhandle
        channel_name:
          type: string
          description: Channel name
        channel_handle:
          description: Channel handle (e.g., @username)
          type:
            - string
            - 'null'
        channel_verified:
          type: boolean
          description: Whether channel is verified
        description:
          description: Channel description snippet
          type:
            - string
            - 'null'
        thumbnail_url:
          description: Channel avatar URL
          type:
            - string
            - 'null'
        subscriber_count:
          type:
            - number
            - 'null'
          minimum: 0
          description: Subscriber count
        video_count:
          type:
            - integer
            - 'null'
          minimum: 0
          maximum: 9007199254740991
          description: Number of videos on the channel
      required:
        - type
        - channel_id
        - url
        - channel_name
        - channel_handle
        - channel_verified
        - description
        - thumbnail_url
        - subscriber_count
        - video_count
      additionalProperties: false
    YouTubeTypeaheadResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/YouTubeTypeaheadResponseData'
      required:
        - data
      additionalProperties: false
    YouTubeTypeaheadResponseData:
      type: object
      properties:
        query:
          type: string
        suggestions:
          type: array
          items:
            type: string
        scraped_at:
          type: string
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$
      required:
        - query
        - suggestions
        - scraped_at
      additionalProperties: false
    LiveTikTokVideoBatchResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/TikTokVideoBatchResponse'
      required:
        - data
      additionalProperties: false
    TikTokVideoBatchResponse:
      type: object
      properties:
        requested:
          type: integer
          minimum: 0
          maximum: 9007199254740991
        succeeded:
          type: integer
          minimum: 0
          maximum: 9007199254740991
        failed:
          type: integer
          minimum: 0
          maximum: 9007199254740991
        items:
          type: array
          items:
            anyOf:
              - $ref: '#/components/schemas/TikTokVideoBatchSuccess'
              - $ref: '#/components/schemas/TikTokBatchFailure'
        scraped_at:
          type: string
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z))$
      required:
        - requested
        - succeeded
        - failed
        - items
        - scraped_at
      additionalProperties: false
    TikTokVideoBatchSuccess:
      type: object
      properties:
        success:
          type: boolean
          const: true
        url:
          $ref: '#/components/schemas/TikTokVideoUrl'
        data:
          $ref: '#/components/schemas/TikTokVideoResponse'
      required:
        - success
        - url
        - data
      additionalProperties: false
    TikTokVideoResponse:
      type: object
      properties:
        video:
          $ref: '#/components/schemas/TikTokVideo'
        scraped_at:
          type: string
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z))$
      required:
        - video
        - scraped_at
      additionalProperties: false
    TikTokVideo:
      type: object
      properties:
        video_id:
          type: string
          minLength: 1
        url:
          $ref: '#/components/schemas/TikTokVideoUrl'
        author:
          type: object
          properties:
            user_id:
              type: string
              minLength: 1
            username:
              type: string
              minLength: 1
            display_name:
              type: string
            avatar_url:
              type:
                - string
                - 'null'
              format: uri
            is_verified:
              type: boolean
          required:
            - user_id
            - username
            - display_name
            - avatar_url
            - is_verified
          additionalProperties: false
        description:
          type: string
        created_at:
          type:
            - string
            - 'null'
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z))$
        duration_seconds:
          type:
            - number
            - 'null'
          minimum: 0
        media_type:
          type: string
          enum:
            - video
            - slideshow
        thumbnail_url:
          type:
            - string
            - 'null'
          format: uri
        video_url:
          type:
            - string
            - 'null'
          format: uri
        has_watermark:
          type:
            - boolean
            - 'null'
        images:
          type: array
          items:
            type: string
            format: uri
        view_count:
          type:
            - integer
            - 'null'
          minimum: 0
          maximum: 9007199254740991
          description: Observed count; null when unavailable or invalid
        like_count:
          type:
            - integer
            - 'null'
          minimum: 0
          maximum: 9007199254740991
          description: Observed count; null when unavailable or invalid
        comment_count:
          type:
            - integer
            - 'null'
          minimum: 0
          maximum: 9007199254740991
          description: Observed count; null when unavailable or invalid
        share_count:
          type:
            - integer
            - 'null'
          minimum: 0
          maximum: 9007199254740991
          description: Observed count; null when unavailable or invalid
        save_count:
          type:
            - integer
            - 'null'
          minimum: 0
          maximum: 9007199254740991
          description: Observed count; null when unavailable or invalid
        hashtags:
          type: array
          items:
            type: string
        music:
          type:
            - object
            - 'null'
          properties:
            music_id:
              type:
                - string
                - 'null'
            title:
              type:
                - string
                - 'null'
            author:
              type:
                - string
                - 'null'
            duration_seconds:
              type:
                - number
                - 'null'
              minimum: 0
          required:
            - music_id
            - title
            - author
            - duration_seconds
          additionalProperties: false
        is_pinned:
          type: boolean
      required:
        - video_id
        - url
        - author
        - description
        - created_at
        - duration_seconds
        - media_type
        - thumbnail_url
        - video_url
        - has_watermark
        - images
        - view_count
        - like_count
        - comment_count
        - share_count
        - save_count
        - hashtags
        - music
        - is_pinned
      additionalProperties: false
    TikTokBatchFailure:
      type: object
      properties:
        success:
          type: boolean
          const: false
        url:
          $ref: '#/components/schemas/TikTokVideoUrl'
        status:
          type: integer
          minimum: 400
          maximum: 599
        error:
          type: object
          properties:
            code:
              type: string
              minLength: 1
            message:
              type: string
          required:
            - code
            - message
          additionalProperties: false
      required:
        - success
        - url
        - status
        - error
      additionalProperties: false
    LiveTikTokTranscriptBatchResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/TikTokTranscriptBatchResponse'
      required:
        - data
      additionalProperties: false
    TikTokTranscriptBatchResponse:
      type: object
      properties:
        requested:
          type: integer
          minimum: 0
          maximum: 9007199254740991
        succeeded:
          type: integer
          minimum: 0
          maximum: 9007199254740991
        failed:
          type: integer
          minimum: 0
          maximum: 9007199254740991
        items:
          type: array
          items:
            anyOf:
              - $ref: '#/components/schemas/TikTokTranscriptBatchSuccess'
              - $ref: '#/components/schemas/TikTokBatchFailure'
        scraped_at:
          type: string
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z))$
        mode:
          type: string
          enum:
            - auto
            - captions
      required:
        - requested
        - succeeded
        - failed
        - items
        - scraped_at
        - mode
      additionalProperties: false
    TikTokTranscriptBatchSuccess:
      type: object
      properties:
        success:
          type: boolean
          const: true
        url:
          $ref: '#/components/schemas/TikTokVideoUrl'
        data:
          $ref: '#/components/schemas/TikTokTranscriptResponse'
      required:
        - success
        - url
        - data
      additionalProperties: false
    TikTokTranscriptResponse:
      type: object
      properties:
        video_id:
          type: string
          minLength: 1
        url:
          $ref: '#/components/schemas/TikTokVideoUrl'
        transcript:
          type: string
        full_text:
          type: string
        segments:
          type: array
          items:
            type: object
            properties:
              start_ms:
                type: integer
                minimum: 0
                maximum: 9007199254740991
              end_ms:
                type: integer
                minimum: 0
                maximum: 9007199254740991
              text:
                type: string
            required:
              - start_ms
              - end_ms
              - text
            additionalProperties: false
        word_count:
          type: integer
          minimum: 0
          maximum: 9007199254740991
        language:
          type: string
        source:
          type: string
          enum:
            - captions
            - generated
        duration_seconds:
          type:
            - number
            - 'null'
          minimum: 0
        scraped_at:
          type: string
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z))$
      required:
        - video_id
        - url
        - transcript
        - full_text
        - segments
        - word_count
        - language
        - source
        - duration_seconds
        - scraped_at
      additionalProperties: false
    LiveTikTokProfileResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/TikTokProfileResponse'
      required:
        - data
      additionalProperties: false
    TikTokProfileResponse:
      type: object
      properties:
        user_id:
          type: string
          minLength: 1
        username:
          type: string
          minLength: 1
        display_name:
          type: string
        biography:
          type: string
        profile_url:
          $ref: '#/components/schemas/TikTokUrl'
        avatar_url:
          type:
            - string
            - 'null'
          format: uri
        external_url:
          type:
            - string
            - 'null'
          format: uri
        follower_count:
          type:
            - integer
            - 'null'
          minimum: 0
          maximum: 9007199254740991
          description: Observed count; null when unavailable or invalid
        following_count:
          type:
            - integer
            - 'null'
          minimum: 0
          maximum: 9007199254740991
          description: Observed count; null when unavailable or invalid
        video_count:
          type:
            - integer
            - 'null'
          minimum: 0
          maximum: 9007199254740991
          description: Observed count; null when unavailable or invalid
        like_count:
          type:
            - integer
            - 'null'
          minimum: 0
          maximum: 9007199254740991
          description: Observed count; null when unavailable or invalid
        is_verified:
          type: boolean
        is_private:
          type: boolean
        is_business:
          type: boolean
        scraped_at:
          type: string
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z))$
      required:
        - user_id
        - username
        - display_name
        - biography
        - profile_url
        - avatar_url
        - external_url
        - follower_count
        - following_count
        - video_count
        - like_count
        - is_verified
        - is_private
        - is_business
        - scraped_at
      additionalProperties: false
    LiveTikTokProfileVideosResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/TikTokProfileVideosResponse'
      required:
        - data
      additionalProperties: false
    TikTokProfileVideosResponse:
      type: object
      properties:
        username:
          type: string
          minLength: 1
        videos:
          type: array
          items:
            $ref: '#/components/schemas/TikTokVideo'
        has_more:
          type: boolean
        next_cursor:
          type:
            - string
            - 'null'
        scraped_at:
          type: string
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z))$
      required:
        - username
        - videos
        - has_more
        - next_cursor
        - scraped_at
      additionalProperties: false
    LiveTikTokVideoResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/TikTokVideoResponse'
      required:
        - data
      additionalProperties: false
    LiveTikTokCommentsResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/TikTokCommentsResponse'
      required:
        - data
      additionalProperties: false
    TikTokCommentsResponse:
      type: object
      properties:
        video_id:
          type:
            - string
            - 'null'
          minLength: 1
        comments:
          type: array
          items:
            type: object
            properties:
              comment_id:
                type: string
                minLength: 1
              video_id:
                type: string
                minLength: 1
              text:
                type: string
              created_at:
                type:
                  - string
                  - 'null'
                format: date-time
                pattern: >-
                  ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z))$
              like_count:
                type:
                  - integer
                  - 'null'
                minimum: 0
                maximum: 9007199254740991
                description: Observed count; null when unavailable or invalid
              reply_count:
                type:
                  - integer
                  - 'null'
                minimum: 0
                maximum: 9007199254740991
                description: Observed count; null when unavailable or invalid
              is_pinned:
                type: boolean
              author:
                type: object
                properties:
                  user_id:
                    type: string
                    minLength: 1
                  username:
                    type: string
                    minLength: 1
                  display_name:
                    type: string
                  avatar_url:
                    type:
                      - string
                      - 'null'
                    format: uri
                  is_verified:
                    type: boolean
                required:
                  - user_id
                  - username
                  - display_name
                  - avatar_url
                  - is_verified
                additionalProperties: false
            required:
              - comment_id
              - video_id
              - text
              - created_at
              - like_count
              - reply_count
              - is_pinned
              - author
            additionalProperties: false
        total:
          type:
            - integer
            - 'null'
          minimum: 0
          maximum: 9007199254740991
        has_more:
          type: boolean
        next_cursor:
          type:
            - string
            - 'null'
        scraped_at:
          type: string
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z))$
      required:
        - video_id
        - comments
        - total
        - has_more
        - next_cursor
        - scraped_at
      additionalProperties: false
    LiveTikTokCommentRepliesResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/TikTokCommentRepliesResponse'
      required:
        - data
      additionalProperties: false
    TikTokCommentRepliesResponse:
      type: object
      properties:
        video_id:
          type: string
          pattern: ^[1-9][0-9]{0,24}$
        comments:
          type: array
          items:
            type: object
            properties:
              comment_id:
                type: string
                minLength: 1
              video_id:
                type: string
                minLength: 1
              text:
                type: string
              created_at:
                type:
                  - string
                  - 'null'
                format: date-time
                pattern: >-
                  ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z))$
              like_count:
                type:
                  - integer
                  - 'null'
                minimum: 0
                maximum: 9007199254740991
                description: Observed count; null when unavailable or invalid
              reply_count:
                type:
                  - integer
                  - 'null'
                minimum: 0
                maximum: 9007199254740991
                description: Observed count; null when unavailable or invalid
              is_pinned:
                type: boolean
              author:
                type: object
                properties:
                  user_id:
                    type: string
                    minLength: 1
                  username:
                    type: string
                    minLength: 1
                  display_name:
                    type: string
                  avatar_url:
                    type:
                      - string
                      - 'null'
                    format: uri
                  is_verified:
                    type: boolean
                required:
                  - user_id
                  - username
                  - display_name
                  - avatar_url
                  - is_verified
                additionalProperties: false
            required:
              - comment_id
              - video_id
              - text
              - created_at
              - like_count
              - reply_count
              - is_pinned
              - author
            additionalProperties: false
        total:
          type:
            - integer
            - 'null'
          minimum: 0
          maximum: 9007199254740991
        has_more:
          type: boolean
        next_cursor:
          type:
            - string
            - 'null'
        scraped_at:
          type: string
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z))$
        parent_comment_id:
          type: string
          pattern: ^[1-9][0-9]{0,24}$
      required:
        - video_id
        - comments
        - total
        - has_more
        - next_cursor
        - scraped_at
        - parent_comment_id
      additionalProperties: false
    LiveTikTokCaptionsResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/TikTokCaptionsResponse'
      required:
        - data
      additionalProperties: false
    TikTokCaptionsResponse:
      type: object
      properties:
        video_id:
          type: string
          minLength: 1
        url:
          $ref: '#/components/schemas/TikTokVideoUrl'
        transcript:
          type: string
        full_text:
          type: string
        segments:
          type: array
          items:
            type: object
            properties:
              start_ms:
                type: integer
                minimum: 0
                maximum: 9007199254740991
              end_ms:
                type: integer
                minimum: 0
                maximum: 9007199254740991
              text:
                type: string
            required:
              - start_ms
              - end_ms
              - text
            additionalProperties: false
        word_count:
          type: integer
          minimum: 0
          maximum: 9007199254740991
        language:
          type: string
        source:
          type: string
          const: captions
        duration_seconds:
          type:
            - number
            - 'null'
          minimum: 0
        scraped_at:
          type: string
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z))$
      required:
        - video_id
        - url
        - transcript
        - full_text
        - segments
        - word_count
        - language
        - source
        - duration_seconds
        - scraped_at
      additionalProperties: false
    LiveTikTokMusicResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/TikTokMusicResponse'
      required:
        - data
      additionalProperties: false
    TikTokMusicResponse:
      type: object
      properties:
        music_id:
          type: string
          pattern: ^[1-9][0-9]{0,24}$
        title:
          type:
            - string
            - 'null'
        author:
          type:
            - string
            - 'null'
        album:
          type:
            - string
            - 'null'
        duration_seconds:
          type:
            - integer
            - 'null'
          minimum: 0
          maximum: 9007199254740991
        video_count:
          type:
            - integer
            - 'null'
          minimum: 0
          maximum: 9007199254740991
          description: Observed number of videos using this sound; null when unavailable
        cover_url:
          type:
            - string
            - 'null'
          format: uri
          description: Temporary upstream cover URL; availability and expiry are not guaranteed
        play_url:
          type:
            - string
            - 'null'
          format: uri
          description: Temporary upstream audio URL; not a durable download or a usage licence
        scraped_at:
          type: string
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$
      required:
        - music_id
        - title
        - author
        - album
        - duration_seconds
        - video_count
        - cover_url
        - play_url
        - scraped_at
      additionalProperties: false
    LiveTikTokUserSearchResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/TikTokUserSearchResponse'
      required:
        - data
      additionalProperties: false
    TikTokUserSearchResponse:
      type: object
      properties:
        query:
          type: string
          minLength: 1
          maxLength: 100
        users:
          type: array
          items:
            type: object
            properties:
              user_id:
                type: string
                minLength: 1
              username:
                type: string
                minLength: 1
              display_name:
                type:
                  - string
                  - 'null'
              biography:
                type:
                  - string
                  - 'null'
              avatar_url:
                type:
                  - string
                  - 'null'
                format: uri
              follower_count:
                type:
                  - integer
                  - 'null'
                minimum: 0
                maximum: 9007199254740991
              following_count:
                type:
                  - integer
                  - 'null'
                minimum: 0
                maximum: 9007199254740991
              video_count:
                type:
                  - integer
                  - 'null'
                minimum: 0
                maximum: 9007199254740991
              is_verified:
                type:
                  - boolean
                  - 'null'
            required:
              - user_id
              - username
              - display_name
              - biography
              - avatar_url
              - follower_count
              - following_count
              - video_count
              - is_verified
            additionalProperties: false
        has_more:
          type: boolean
        next_cursor:
          type:
            - string
            - 'null'
        scraped_at:
          type: string
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z))$
      required:
        - query
        - users
        - has_more
        - next_cursor
        - scraped_at
      additionalProperties: false
    LiveTikTokVideoSearchResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/TikTokVideoSearchResponse'
      required:
        - data
      additionalProperties: false
    TikTokVideoSearchResponse:
      type: object
      properties:
        query:
          type: string
          minLength: 1
          maxLength: 100
        videos:
          type: array
          items:
            $ref: '#/components/schemas/TikTokVideo'
        has_more:
          type: boolean
        next_cursor:
          type:
            - string
            - 'null'
        scraped_at:
          type: string
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z))$
      required:
        - query
        - videos
        - has_more
        - next_cursor
        - scraped_at
      additionalProperties: false
    LiveTikTokHashtagVideosResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/TikTokHashtagVideosResponse'
      required:
        - data
      additionalProperties: false
    TikTokHashtagVideosResponse:
      type: object
      properties:
        videos:
          type: array
          items:
            $ref: '#/components/schemas/TikTokVideo'
        has_more:
          type: boolean
        next_cursor:
          type:
            - string
            - 'null'
        scraped_at:
          type: string
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z))$
        hashtag:
          type: string
          minLength: 1
          maxLength: 100
      required:
        - videos
        - has_more
        - next_cursor
        - scraped_at
        - hashtag
      additionalProperties: false
    LiveTikTokMusicVideosResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/TikTokMusicVideosResponse'
      required:
        - data
      additionalProperties: false
    TikTokMusicVideosResponse:
      type: object
      properties:
        videos:
          type: array
          items:
            $ref: '#/components/schemas/TikTokVideo'
        has_more:
          type: boolean
        next_cursor:
          type:
            - string
            - 'null'
        scraped_at:
          type: string
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z))$
        music_id:
          type: string
          pattern: ^[1-9][0-9]{0,24}$
      required:
        - videos
        - has_more
        - next_cursor
        - scraped_at
        - music_id
      additionalProperties: false
    LiveTikTokTranscriptResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/TikTokTranscriptResponse'
      required:
        - data
      additionalProperties: false
    CreatorEmailLookupInputOutput:
      anyOf:
        - $ref: '#/components/schemas/CreatorEmailLookupByIdOutput'
        - $ref: '#/components/schemas/CreatorEmailLookupByHandleOutput'
      description: Creator email lookup input by creator ID or social handle
    CreatorEmailLookupByIdOutput:
      type: object
      properties:
        creator_id:
          type: string
          format: uuid
          pattern: >-
            ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
          description: Creator profile ID to look up directly
          example: 123e4567-e89b-12d3-a456-426614174000
      required:
        - creator_id
      additionalProperties: false
      description: Creator email lookup input by creator ID
    CreatorEmailLookupByHandleOutput:
      type: object
      properties:
        platform:
          description: Social platform for handle-based lookup
          $ref: '#/components/schemas/Platform'
        username:
          type: string
          minLength: 1
          maxLength: 100
          description: Social username for handle-based lookup
          example: fitness_coach_jane
      required:
        - platform
        - username
      additionalProperties: false
      description: Creator email lookup input by social handle
paths:
  /.well-known/oauth-protected-resource:
    get:
      operationId: getOAuthProtectedResourceMetadata
      summary: Get OAuth Protected Resource Metadata
      tags:
        - OAuth
      description: OAuth 2.0 protected resource metadata for MCP and partner clients.
      security: []
      responses:
        '200':
          description: Successful response
  /health:
    get:
      operationId: healthCheck
      summary: Health Check
      tags:
        - Health
      description: Check API health status. No authentication required.
      security: []
      responses:
        '200':
          description: Health check response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HealthResponse'
        '500':
          description: Internal server error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
  /ready:
    get:
      operationId: readinessCheck
      summary: Check service dependency readiness
      description: Checks whether the API is ready to serve requests. Use /health for process liveness.
      security: []
      responses:
        '200':
          description: Dependency-aware service readiness status
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReadinessResponse'
        '503':
          description: Dependency-aware service readiness status
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReadinessResponse'
  /v1/creators/autocomplete:
    get:
      operationId: autocompleteCreators
      summary: Autocomplete Search
      tags:
        - Creators
      description: >-
        Find creators by name or username as a user types. Results identify the matching field and value.


        **Matching behavior:**

        - Matches against creator name, username, and display name

        - Results include which field matched and the matching value

        - Prefix matching (e.g., "fit" matches "fitness_coach")


        **Scope options:**

        - `creator_only`: Return only the creator entity

        - `matched_platforms`: Return only profiles that matched the query

        - `all_platforms`: Return all linked profiles on supported API platforms (currently Instagram; default)


        Also callable as the `autocomplete_creators` MCP tool — see [the MCP server guide](/guides/mcp-server) for
        setup.


        **Pricing**: 0.05 credits per request ($0.0005)
      parameters:
        - schema:
            type: string
            minLength: 2
            maxLength: 100
            description: Search query (min 2 characters)
            example: fitness
          in: query
          name: q
          required: true
          description: Search query (min 2 characters)
        - schema:
            description: Filter by platform
            $ref: '#/components/schemas/Platform'
          in: query
          name: platform
          description: Filter by platform
        - schema:
            default: 5
            description: Maximum results to return
            example: 5
            type: integer
            minimum: 1
            maximum: 50
          in: query
          name: limit
          description: Maximum results to return
        - schema:
            default: all_platforms
            description: Which platforms to include in results
            example: all_platforms
            type: string
            enum:
              - creator_only
              - matched_platforms
              - all_platforms
          in: query
          name: scope
          description: Which platforms to include in results
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AutocompleteResponse'
        '400':
          description: Validation error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '402':
          description: Account billing requires attention, or available credits cannot cover this request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiCreditError402'
        '403':
          description: Permission error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '429':
          description: >-
            Rate limit exceeded response. Check Retry-After header for backoff timing. Also returned (without
            RateLimit-* headers) when an IP is temporarily blocked after repeated failed authentication attempts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error429'
        '500':
          description: Internal server error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
        '503':
          description: >-
            Service temporarily unavailable: a live data upstream, or a creator search, match or lookalike request that
            could not finish in time. Check Retry-After when present and retry with bounded backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error503'
  /v1/creators/ingest:
    post:
      operationId: ingestCreator
      summary: Ingest a Creator On Demand
      tags:
        - Creators
      description: >-
        Add a public Instagram creator by handle for discovery and campaign research. The API checks the handle, then
        enriches new profiles asynchronously.


        **How it works:**

        1. The handle is normalized and validated live to confirm it exists

        2. For an existing creator, you get `200` with `status: already_exists` at no charge

        3. For a new creator, you get `202` with `status: ingesting` as enrichment begins


        **Polling for results:**

        Poll the returned `status_url` (`GET /v1/creators/{id}`) with an attempt limit and a deadline. Pending reads
        return `202` at zero credits; completed creator reads return `200` and cost 0.1 credits. Profile details and
        creator analysis become available at different times. Stop polling if the creator is unavailable (`404`). See
        [on-demand ingestion](/guides/ingest-creators-on-demand) for a bounded polling example.


        **Limits:**

        - Submit `instagram` handles

        - Each account has a daily ingest quota; exceeding it returns `429` with `quota_exceeded` and a `Retry-After`
        header

        - Handles that do not exist return `404` and are not charged

        - If the handle cannot be validated right now you get `503` with `service_unavailable`; retry shortly

        - The daily ingest quota is only consumed when a request is accepted. `404`, `422`, and `503` outcomes do not
        use a slot


        **Pricing**: 5 credits per creator ingested ($0.05). Charged when a new creator is accepted for enrichment.
        Existing, not-found, and invalid handles are free.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/IngestCreatorRequest'
        description: On-demand creator ingest request
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IngestCreatorResponse'
        '202':
          description: 202 response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IngestCreatorResponse'
        '400':
          description: Validation error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '402':
          description: Account billing requires attention, or available credits cannot cover this request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiCreditError402'
        '404':
          description: Not found error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '422':
          description: >-
            Unprocessable entity response. The request was well-formed but a value failed a semantic rule (e.g. an
            invalid social handle format).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error422'
        '429':
          description: >-
            Rate limit exceeded response. Check Retry-After header for backoff timing. Also returned (without
            RateLimit-* headers) when an IP is temporarily blocked after repeated failed authentication attempts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error429'
        '503':
          description: >-
            Service temporarily unavailable: a live data upstream, or a creator search, match or lookalike request that
            could not finish in time. Check Retry-After when present and retry with bounded backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error503'
  /v1/creators/{id}:
    get:
      operationId: getCreatorById
      summary: Get Creator by ID
      tags:
        - Creators
      description: >-
        Retrieve a creator's profile including AI-generated summary, content themes, and optionally their linked social
        profiles.


        **What is a Creator?**

        A creator represents a person or brand. Use `include=profiles` to retrieve their linked Instagram accounts
        alongside the creator's summary and content themes.


        **Include options:**

        - `profiles`: Include linked accounts on supported API platforms (currently Instagram) with metrics. Other
        linked platforms are omitted; the list can be empty.


        Also callable as the `get_creator` MCP tool — see [the MCP server guide](/guides/mcp-server) for setup.


        A creator awaiting its first successful acquisition returns HTTP 202 with only its ID and `status: "pending"`.
        Retry after the `Retry-After` interval. Pending responses cost zero credits, including when using account
        credits. A completed HTTP 200 creator read costs 0.1 credits. Hidden or unavailable creators return 404.


        **Pricing**: 0.1 credits per request ($0.001)
      parameters:
        - schema:
            description: Additional data to include in response
            example:
              - profiles
            type: array
            items:
              type: string
              enum:
                - profiles
          in: query
          name: include
          description: Additional data to include in response
        - schema:
            type: string
            format: uuid
            pattern: >-
              ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
            description: Creator unique identifier
            example: 123e4567-e89b-12d3-a456-426614174000
          in: path
          name: id
          required: true
          description: Creator unique identifier
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreatorResponse'
        '202':
          description: 202 response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PendingCreatorResponse'
        '400':
          description: Validation error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '402':
          description: Account billing requires attention, or available credits cannot cover this request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiCreditError402'
        '403':
          description: Permission error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '429':
          description: >-
            Rate limit exceeded response. Check Retry-After header for backoff timing. Also returned (without
            RateLimit-* headers) when an IP is temporarily blocked after repeated failed authentication attempts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error429'
        '500':
          description: Internal server error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
        '503':
          description: >-
            Service temporarily unavailable: a live data upstream, or a creator search, match or lookalike request that
            could not finish in time. Check Retry-After when present and retry with bounded backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error503'
  /v1/creators/lookalike:
    post:
      operationId: findLookalikeCreators
      summary: Find Similar Creators
      tags:
        - Creators
      description: >-
        Find creators similar to provided seed creators using AI-powered similarity matching. Analyzes content themes,
        audience overlap, posting style, and engagement patterns.


        **Use cases:**

        - Expand campaigns with creators similar to proven performers

        - Find alternatives when preferred creators are unavailable

        - Discover emerging creators in the same niche


        **How it works:**

        1. Provide 1-10 seed creators (by ID or platform/username)

        2. Optionally weight seeds to prioritize certain creators

        3. Get ranked results with similarity scores and shared traits


        If none of the supplied seeds is available for similarity matching, the endpoint returns `404 seed_not_found`.
        Choose another seed instead of retrying the same request.


        Also callable as the `find_lookalike_creators` MCP tool — see [the MCP server guide](/guides/mcp-server) for
        setup.


        **Pricing**: 1.5 credits per creator returned ($0.015)
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LookalikeRequest'
        description: Find similar creators request
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LookalikeResponse'
        '400':
          description: Validation error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '402':
          description: Account billing requires attention, or available credits cannot cover this request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiCreditError402'
        '403':
          description: Permission error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '429':
          description: >-
            Rate limit exceeded response. Check Retry-After header for backoff timing. Also returned (without
            RateLimit-* headers) when an IP is temporarily blocked after repeated failed authentication attempts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error429'
        '500':
          description: Internal server error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
        '502':
          description: The API could not complete the analysis for a valid request. The failure is reported automatically.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AIServiceError502'
        '503':
          description: >-
            Service temporarily unavailable: a live data upstream, or a creator search, match or lookalike request that
            could not finish in time. Check Retry-After when present and retry with bounded backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error503'
  /v1/creators/match:
    post:
      operationId: matchCreators
      summary: Score Campaign Fit
      tags:
        - Creators
      description: >-
        Evaluate how well creators match a specific campaign using AI analysis. Returns a fit score (0-1), decision
        recommendation (good/neutral/avoid), and evidence-based explanations.


        **Use cases:**

        - Vet shortlisted creators before outreach

        - Rank candidates for a specific campaign

        - Get AI-generated talking points for why a creator fits


        **How it works:**

        1. Describe your campaign intent and target audience

        2. Provide up to 100 creators to evaluate

        3. Get detailed scores with explanations and evidence


        Also callable as the `match_creators` MCP tool — see [the MCP server guide](/guides/mcp-server) for setup.


        **Pricing**: 1 credit per creator scored ($0.01)
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MatchRequest'
        description: Score campaign fit request
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MatchResponse'
        '400':
          description: Validation error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '402':
          description: Account billing requires attention, or available credits cannot cover this request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiCreditError402'
        '403':
          description: Permission error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '429':
          description: >-
            Rate limit exceeded response. Check Retry-After header for backoff timing. Also returned (without
            RateLimit-* headers) when an IP is temporarily blocked after repeated failed authentication attempts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error429'
        '500':
          description: Internal server error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
        '502':
          description: The API could not complete the analysis for a valid request. The failure is reported automatically.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AIServiceError502'
        '503':
          description: >-
            Service temporarily unavailable: a live data upstream, or a creator search, match or lookalike request that
            could not finish in time. Check Retry-After when present and retry with bounded backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error503'
  /v1/shortlists/{id}/delete:
    post:
      operationId: deleteShortlist
      summary: Delete your saved creator shortlist
      tags:
        - Shortlists
      description: >-
        Permanently remove a saved shortlist and its brief and notes. Requires its current version. Creator profiles are
        not deleted.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                expected_version:
                  type: integer
                  exclusiveMinimum: 0
                  maximum: 2147483647
              required:
                - expected_version
              additionalProperties: false
      parameters:
        - schema:
            type: string
            format: uuid
            pattern: >-
              ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
          in: path
          name: id
          required: true
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      deleted:
                        type: boolean
                        const: true
                      id:
                        type: string
                        format: uuid
                        pattern: >-
                          ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
                    required:
                      - deleted
                      - id
                    additionalProperties: false
                required:
                  - data
                additionalProperties: false
        '400':
          description: Validation error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '402':
          description: Authenticated payment required response with a machine-readable billing classification and recovery action.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error402'
        '403':
          description: Permission error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '422':
          description: >-
            Unprocessable entity response. The request was well-formed but a value failed a semantic rule (e.g. an
            invalid social handle format).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error422'
        '429':
          description: >-
            Rate limit exceeded response. Check Retry-After header for backoff timing. Also returned (without
            RateLimit-* headers) when an IP is temporarily blocked after repeated failed authentication attempts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error429'
        '500':
          description: Internal server error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
        '503':
          description: >-
            Service temporarily unavailable: a live data upstream, or a creator search, match or lookalike request that
            could not finish in time. Check Retry-After when present and retry with bounded backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error503'
  /v1/shortlists:
    get:
      operationId: listShortlists
      summary: List your saved creator shortlists
      tags:
        - Shortlists
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: string
                          format: uuid
                          pattern: >-
                            ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
                        name:
                          type: string
                        brief:
                          type: string
                        profiles:
                          minItems: 1
                          maxItems: 8
                          type: array
                          items:
                            type: object
                            properties:
                              platform:
                                $ref: '#/components/schemas/Platform'
                              username:
                                type: string
                                minLength: 1
                                maxLength: 50
                            required:
                              - platform
                              - username
                            additionalProperties: false
                        notes:
                          type: string
                        version:
                          type: integer
                          exclusiveMinimum: 0
                          maximum: 2147483647
                        created_at:
                          type: string
                        updated_at:
                          type: string
                      required:
                        - id
                        - name
                        - brief
                        - profiles
                        - notes
                        - version
                        - created_at
                        - updated_at
                      additionalProperties: false
                required:
                  - data
                additionalProperties: false
        '400':
          description: Validation error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '402':
          description: Authenticated payment required response with a machine-readable billing classification and recovery action.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error402'
        '403':
          description: Permission error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '422':
          description: >-
            Unprocessable entity response. The request was well-formed but a value failed a semantic rule (e.g. an
            invalid social handle format).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error422'
        '429':
          description: >-
            Rate limit exceeded response. Check Retry-After header for backoff timing. Also returned (without
            RateLimit-* headers) when an IP is temporarily blocked after repeated failed authentication attempts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error429'
        '500':
          description: Internal server error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
        '503':
          description: >-
            Service temporarily unavailable: a live data upstream, or a creator search, match or lookalike request that
            could not finish in time. Check Retry-After when present and retry with bounded backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error503'
    post:
      operationId: saveShortlist
      summary: Save or update your creator shortlist
      tags:
        - Shortlists
      description: >-
        Save up to eight Instagram profiles with a campaign brief and notes. Updating requires the current saved
        version. Reopen the selected profiles to retrieve their latest stored metrics and evidence.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                id:
                  type: string
                  format: uuid
                  pattern: >-
                    ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
                expected_version:
                  type: integer
                  exclusiveMinimum: 0
                  maximum: 2147483647
                name:
                  type: string
                  minLength: 1
                  maxLength: 80
                brief:
                  type: string
                  minLength: 1
                  maxLength: 500
                profiles:
                  minItems: 1
                  maxItems: 8
                  type: array
                  items:
                    type: object
                    properties:
                      platform:
                        $ref: '#/components/schemas/Platform'
                      username:
                        type: string
                        minLength: 1
                        maxLength: 50
                        pattern: ^[\p{L}\p{N}_.-]+$
                    required:
                      - platform
                      - username
                    additionalProperties: false
                notes:
                  default: ''
                  type: string
                  maxLength: 2000
              required:
                - name
                - brief
                - profiles
              additionalProperties: false
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      id:
                        type: string
                        format: uuid
                        pattern: >-
                          ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
                      name:
                        type: string
                      brief:
                        type: string
                      profiles:
                        minItems: 1
                        maxItems: 8
                        type: array
                        items:
                          type: object
                          properties:
                            platform:
                              $ref: '#/components/schemas/Platform'
                            username:
                              type: string
                              minLength: 1
                              maxLength: 50
                          required:
                            - platform
                            - username
                          additionalProperties: false
                      notes:
                        type: string
                      version:
                        type: integer
                        exclusiveMinimum: 0
                        maximum: 2147483647
                      created_at:
                        type: string
                      updated_at:
                        type: string
                    required:
                      - id
                      - name
                      - brief
                      - profiles
                      - notes
                      - version
                      - created_at
                      - updated_at
                    additionalProperties: false
                required:
                  - data
                additionalProperties: false
        '400':
          description: Validation error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '402':
          description: Authenticated payment required response with a machine-readable billing classification and recovery action.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error402'
        '403':
          description: Permission error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '422':
          description: >-
            Unprocessable entity response. The request was well-formed but a value failed a semantic rule (e.g. an
            invalid social handle format).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error422'
        '429':
          description: >-
            Rate limit exceeded response. Check Retry-After header for backoff timing. Also returned (without
            RateLimit-* headers) when an IP is temporarily blocked after repeated failed authentication attempts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error429'
        '500':
          description: Internal server error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
        '503':
          description: >-
            Service temporarily unavailable: a live data upstream, or a creator search, match or lookalike request that
            could not finish in time. Check Retry-After when present and retry with bounded backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error503'
  /v1/shortlists/{id}:
    get:
      operationId: getShortlist
      summary: Open your saved creator shortlist
      tags:
        - Shortlists
      parameters:
        - schema:
            type: string
            format: uuid
            pattern: >-
              ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
          in: path
          name: id
          required: true
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      id:
                        type: string
                        format: uuid
                        pattern: >-
                          ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
                      name:
                        type: string
                      brief:
                        type: string
                      profiles:
                        minItems: 1
                        maxItems: 8
                        type: array
                        items:
                          type: object
                          properties:
                            platform:
                              $ref: '#/components/schemas/Platform'
                            username:
                              type: string
                              minLength: 1
                              maxLength: 50
                          required:
                            - platform
                            - username
                          additionalProperties: false
                      notes:
                        type: string
                      version:
                        type: integer
                        exclusiveMinimum: 0
                        maximum: 2147483647
                      created_at:
                        type: string
                      updated_at:
                        type: string
                    required:
                      - id
                      - name
                      - brief
                      - profiles
                      - notes
                      - version
                      - created_at
                      - updated_at
                    additionalProperties: false
                required:
                  - data
                additionalProperties: false
        '400':
          description: Validation error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '402':
          description: Authenticated payment required response with a machine-readable billing classification and recovery action.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error402'
        '403':
          description: Permission error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '422':
          description: >-
            Unprocessable entity response. The request was well-formed but a value failed a semantic rule (e.g. an
            invalid social handle format).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error422'
        '429':
          description: >-
            Rate limit exceeded response. Check Retry-After header for backoff timing. Also returned (without
            RateLimit-* headers) when an IP is temporarily blocked after repeated failed authentication attempts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error429'
        '500':
          description: Internal server error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
        '503':
          description: >-
            Service temporarily unavailable: a live data upstream, or a creator search, match or lookalike request that
            could not finish in time. Check Retry-After when present and retry with bounded backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error503'
  /v1/creator-emails/lookup:
    post:
      operationId: lookupCreatorEmails
      summary: Lookup Creator Emails
      tags:
        - Creator Emails
      description: |-
        Look up known email addresses for creators by creator ID or social username.

        **Billing behavior:**
        - Charged only for unique resolved creators with at least one returned email
        - Empty and unresolved results are not billable
        - Returns validation status so unvalidated emails are explicit

        **Pricing**: 5 credits per creator with at least one returned email ($0.05)
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreatorEmailsLookupRequest'
        description: Creator email lookup request
      responses:
        '200':
          description: Creator email lookup response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreatorEmailsLookupResponse'
        '400':
          description: Validation error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '402':
          description: Account billing requires attention, or available credits cannot cover this request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiCreditError402'
        '403':
          description: Permission error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '429':
          description: >-
            Rate limit exceeded response. Check Retry-After header for backoff timing. Also returned (without
            RateLimit-* headers) when an IP is temporarily blocked after repeated failed authentication attempts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error429'
        '500':
          description: Internal server error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
        '503':
          description: >-
            Service temporarily unavailable: a live data upstream, or a creator search, match or lookalike request that
            could not finish in time. Check Retry-After when present and retry with bounded backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error503'
  /v1/search/{id}/feedback:
    post:
      operationId: submitSearchFeedback
      summary: Submit search feedback
      tags:
        - Search
      description: >-
        Report whether a saved search was helpful. Only the account that owns the search can submit feedback. This
        endpoint does not consume search credits.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SearchFeedbackRequest'
      parameters:
        - schema:
            type: string
            format: uuid
            pattern: >-
              ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
            description: Search ID returned from POST /v1/search
            example: 123e4567-e89b-12d3-a456-426614174000
          in: path
          name: id
          required: true
          description: Search ID returned from POST /v1/search
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SearchFeedbackResponse'
        '400':
          description: Validation error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '402':
          description: Authenticated payment required response with a machine-readable billing classification and recovery action.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error402'
        '403':
          description: Permission error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '429':
          description: >-
            Rate limit exceeded response. Check Retry-After header for backoff timing. Also returned (without
            RateLimit-* headers) when an IP is temporarily blocked after repeated failed authentication attempts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error429'
        '503':
          description: >-
            Service temporarily unavailable: a live data upstream, or a creator search, match or lookalike request that
            could not finish in time. Check Retry-After when present and retry with bounded backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error503'
  /v1/search:
    post:
      operationId: searchCreators
      summary: AI-Powered Creator Search
      tags:
        - Search
      description: >-
        Find Instagram creators from a natural-language brief. Each result includes ranking, reasons, and available
        evidence.


        **Small trial:** Set `limit: 5` for a maximum API-key/OAuth search cost of 35 credits (\$0.35). Changing the
        limit changes the billing cap; omitting it uses 25. Payment-protocol requests follow their separate quote rules.


        **Before sending:** Expand optional fields to inspect and change the limit. Playground calls use real credits.


        The POST delivers its visible results together. Use the returned `search_id` to reread saved results for free;
        inspect [search quality](/concepts/semantic-search#search-quality) before displaying scores.


        **Pricing**: 25 credits base + 2 credits per creator returned
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SearchRequest'
        description: AI-powered semantic search request
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SearchResponse'
        '400':
          description: Validation error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '402':
          description: Account billing requires attention, or remaining credits cannot cover this search.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SearchError402'
        '403':
          description: Permission error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '429':
          description: >-
            Rate limit exceeded response. Check Retry-After header for backoff timing. Also returned (without
            RateLimit-* headers) when an IP is temporarily blocked after repeated failed authentication attempts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error429'
        '500':
          description: Internal server error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
        '502':
          description: The API could not complete the analysis for a valid request. The failure is reported automatically.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AIServiceError502'
        '503':
          description: >-
            Service temporarily unavailable: a live data upstream, or a creator search, match or lookalike request that
            could not finish in time. Check Retry-After when present and retry with bounded backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error503'
  /v1/search/{id}:
    get:
      operationId: getSearchResults
      summary: Get Search Results Page
      tags:
        - Search
      description: >-
        Paginate through results from a previous search. Use the `search_id` returned by `POST /v1/search` to fetch
        additional pages.


        Search sessions expire after 1 hour. After expiry, a new search must be run.


        **Pricing**: 0 credits (included with initial search)
      parameters:
        - schema:
            default: 25
            description: Maximum results to return
            example: 25
            type: integer
            minimum: 1
            maximum: 100
          in: query
          name: limit
          description: Maximum results to return
        - schema:
            description: Pagination cursor for next page
            type: string
          in: query
          name: cursor
          description: Pagination cursor for next page
        - schema:
            type: string
            format: uuid
            pattern: >-
              ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
            description: Search ID returned from POST /v1/search
            example: 123e4567-e89b-12d3-a456-426614174000
          in: path
          name: id
          required: true
          description: Search ID returned from POST /v1/search
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SearchResponse'
        '400':
          description: Validation error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '402':
          description: Account billing requires attention, or available credits cannot cover this request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiCreditError402'
        '403':
          description: Permission error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '429':
          description: >-
            Rate limit exceeded response. Check Retry-After header for backoff timing. Also returned (without
            RateLimit-* headers) when an IP is temporarily blocked after repeated failed authentication attempts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error429'
        '500':
          description: Internal server error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
        '503':
          description: >-
            Service temporarily unavailable: a live data upstream, or a creator search, match or lookalike request that
            could not finish in time. Check Retry-After when present and retry with bounded backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error503'
  /v1/profiles/{platform}/{username}:
    get:
      operationId: getProfileByPlatformUsername
      summary: Get Profile by Platform and Username
      tags:
        - Profiles
      description: |-
        Retrieve an Instagram profile's identity, metrics, growth statistics, and activity information.

        **Response includes:**
        - Basic info (bio, avatar, verification status)
        - Performance metrics (followers, engagement rate, avg likes/comments)
        - Growth data (30-day follower growth, monthly rate)
        - Activity data (last post date, posting frequency)

        Also callable as the `get_profile` MCP tool — see [the MCP server guide](/guides/mcp-server) for setup.

        **Pricing**: 0.1 credits per request ($0.001)
      parameters:
        - schema:
            type: string
            minLength: 1
            description: Platform name
            example: instagram
          in: path
          name: platform
          required: true
          description: Platform name
        - schema:
            type: string
            minLength: 1
            maxLength: 50
            description: Username on the platform
            example: fitness_coach_jane
          in: path
          name: username
          required: true
          description: Username on the platform
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProfileResponse'
        '400':
          description: Validation error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '402':
          description: Account billing requires attention, or available credits cannot cover this request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiCreditError402'
        '403':
          description: Permission error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '429':
          description: >-
            Rate limit exceeded response. Check Retry-After header for backoff timing. Also returned (without
            RateLimit-* headers) when an IP is temporarily blocked after repeated failed authentication attempts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error429'
        '500':
          description: Internal server error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
        '503':
          description: >-
            Service temporarily unavailable: a live data upstream, or a creator search, match or lookalike request that
            could not finish in time. Check Retry-After when present and retry with bounded backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error503'
  /v1/profiles/lookup:
    post:
      operationId: lookupProfiles
      summary: Batch Lookup Profiles
      tags:
        - Profiles
      description: >-
        Look up multiple profiles in a single request. Efficiently retrieve data for up to 100 profiles at once.


        **Response includes:**

        - `data`: Array of resolved profiles

        - `not_found`: Array of profiles that weren't found. Use [on-demand
        ingestion](/guides/ingest-creators-on-demand) to add a public Instagram handle


        Also callable as the `lookup_profiles` MCP tool — see [the MCP server guide](/guides/mcp-server) for setup.


        **Pricing**: 0.1 credits per profile ($0.001)
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ProfilesLookupRequest'
        description: Batch lookup profiles request
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProfilesLookupResponse'
        '400':
          description: Validation error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '402':
          description: Account billing requires attention, or available credits cannot cover this request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiCreditError402'
        '403':
          description: Permission error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '429':
          description: >-
            Rate limit exceeded response. Check Retry-After header for backoff timing. Also returned (without
            RateLimit-* headers) when an IP is temporarily blocked after repeated failed authentication attempts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error429'
        '500':
          description: Internal server error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
        '503':
          description: >-
            Service temporarily unavailable: a live data upstream, or a creator search, match or lookalike request that
            could not finish in time. Check Retry-After when present and retry with bounded backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error503'
  /v1/posts:
    get:
      operationId: getPosts
      summary: Get Posts
      tags:
        - Posts
      description: >-
        Retrieve Instagram posts for a creator or profile with engagement metrics and media data. Only Instagram posts
        are returned.


        **Query options:**

        - By creator: Use `creator_id` to get posts across all of their Instagram profiles. Creators without an
        Instagram profile return an empty page

        - By profile: Use `platform` + `username` for a specific profile's posts. Usernames are matched
        case-insensitively


        **Sort options:**

        - `recent`: Most recent posts first (default)

        - `top_engagement`: Highest view-based engagement rate first, calculated as (likes + comments) / views. Posts
        without measurable views sort last

        - `most_likes`: Most likes first

        - `most_views`: Most views first (video content)

        - `most_comments`: Most comments first


        Pagination uses an opaque keyset cursor. Pass `next_cursor` back with the same `sort` value; cursors cannot be
        reused across sort orders.


        Also callable as the `get_posts` MCP tool — see [the MCP server guide](/guides/mcp-server) for setup.


        **Pricing**: 0.05 credits per post returned ($0.0005)
      parameters:
        - schema:
            description: Platform (required with username)
            $ref: '#/components/schemas/Platform'
          in: query
          name: platform
          description: Platform (required with username)
        - schema:
            description: Username (required with platform)
            example: fitness_coach_jane
            type: string
            minLength: 1
            maxLength: 50
          in: query
          name: username
          description: Username (required with platform)
        - schema:
            description: Creator ID (use this OR platform+username)
            example: 123e4567-e89b-12d3-a456-426614174000
            type: string
            format: uuid
            pattern: >-
              ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
          in: query
          name: creator_id
          description: Creator ID (use this OR platform+username)
        - schema:
            default: 12
            description: Maximum posts to return
            example: 12
            type: integer
            minimum: 1
            maximum: 50
          in: query
          name: limit
          description: Maximum posts to return
        - schema:
            default: recent
            description: Sort order
            $ref: '#/components/schemas/PostSort'
          in: query
          name: sort
          description: Sort order
        - schema:
            description: >-
              Opaque keyset cursor from next_cursor. A cursor is bound to the sort order that produced it; using it with
              another sort returns 400.
            type: string
          in: query
          name: cursor
          description: >-
            Opaque keyset cursor from next_cursor. A cursor is bound to the sort order that produced it; using it with
            another sort returns 400.
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PostsResponse'
        '400':
          description: Validation error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '402':
          description: Account billing requires attention, or available credits cannot cover this request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiCreditError402'
        '403':
          description: Permission error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '429':
          description: >-
            Rate limit exceeded response. Check Retry-After header for backoff timing. Also returned (without
            RateLimit-* headers) when an IP is temporarily blocked after repeated failed authentication attempts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error429'
        '500':
          description: Internal server error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
        '503':
          description: >-
            Service temporarily unavailable: a live data upstream, or a creator search, match or lookalike request that
            could not finish in time. Check Retry-After when present and retry with bounded backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error503'
  /v1/raw/instagram/profile/{username}:
    get:
      operationId: getLiveInstagramProfile
      summary: Get Live Instagram Profile
      tags:
        - Live Scraping
      description: >-
        Retrieve Instagram profile details, follower counts, bio, and recent activity.


        **Use this endpoint to:**

        - Research a known Instagram account

        - Retrieve profile metrics and recent posts

        - Review a profile before a campaign


        For creator summaries and campaign research, use [profile
        lookup](/api-reference/profiles/get-profile-by-platform-and-username). See [data
        freshness](/guides/data-freshness) to choose the data you need.


        If a complete requested profile cannot be recovered within the request deadline, this endpoint returns `503`
        with `service_unavailable`. Preserve any cached profile and retry with bounded backoff; an unavailable source
        response is not evidence of an empty or inactive profile.


        A changed or invalid source response returns `502 upstream_contract_broken`. Do not automatically retry this
        response. Neither an ambiguous empty response nor a query execution error confirms that an account was deleted.


        The profile response returns an empty `posts[]` array unless `include_posts=true`. When posts are included,
        `post_limit` accepts 1-50 and defaults to 12. The array contains the recent posts available in Instagram's
        source response, up to that limit. Video posts include a fresh `video_url`. Profile requests and individual post
        lookups each cost 0.18 credits ($0.0018).


        Available recent posts include photos, carousels, and videos. An unavailable total profile media count is
        returned as `media_count: null`; an unavailable video view count is omitted. Preserve previously known metrics
        rather than substituting zero. `posts.length` counts this response, not the profile total.


        **Availability:** When live data is temporarily unavailable this endpoint returns `503` with `error.code:
        service_unavailable` in the standard error envelope. Honor `Retry-After` when present and retry with bounded
        backoff; API-key/OAuth usage billing and x402 do not charge these failures. MPP may already be settled before a
        later service error; retain its payment receipt and do not assume a `503` reverses that payment.


        Incomplete required identity, engagement, or selected media produces an acquisition error. Missing optional bio
        links, pronouns, captions, tags, location, or music do not invalidate usable profile content. Treat missing
        optional metadata as unknown rather than proof of its absence.


        **Pricing**: 0.18 credits per profile scraped ($0.0018)
      parameters:
        - schema:
            description: Include recent posts in response
            example: true
            type: boolean
          in: query
          name: include_posts
          description: Include recent posts in response
        - schema:
            default: 12
            description: Number of posts to include
            example: 12
            type: integer
            minimum: 1
            maximum: 50
          in: query
          name: post_limit
          description: Number of posts to include
        - schema:
            type: string
            minLength: 1
            maxLength: 50
            description: Username on the platform
            example: fitness_coach_jane
          in: path
          name: username
          required: true
          description: Username on the platform
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LiveProfileResponse'
        '400':
          description: Validation error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '402':
          description: Account billing requires attention, or available credits cannot cover this request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiCreditError402'
        '403':
          description: Permission error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '429':
          description: >-
            Rate limit exceeded response. Check Retry-After header for backoff timing. Also returned (without
            RateLimit-* headers) when an IP is temporarily blocked after repeated failed authentication attempts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error429'
        '500':
          description: Internal server error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
        '502':
          description: >-
            The upstream source answered, but with data this endpoint cannot process — for example a response schema the
            source has retired. Unlike 503 this is deterministic: the same request will keep failing until a fix ships,
            so it never carries Retry-After and retrying only burns credits. These are alerted on automatically.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error502'
        '503':
          description: >-
            Service temporarily unavailable: a live data upstream, or a creator search, match or lookalike request that
            could not finish in time. Check Retry-After when present and retry with bounded backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error503'
  /v1/raw/instagram/post/{shortcode}:
    get:
      operationId: getLiveInstagramPost
      summary: Get Live Instagram Post
      tags:
        - Live Scraping
      description: >-
        Fetch fresh Instagram post-page data by shortcode. This raw endpoint includes rich post-page fields like
        coauthors, tagged users, paid partnership metadata, product mentions, music attribution, location, display
        resources, and video versions.


        Unavailable optional captions, tags, location, music, or display variants are omitted or returned as null
        without invalidating usable media. Missing optional metadata does not establish that a post has no tags,
        location, music, or paid partnership. Required identity, engagement counts, timestamps, and media remain
        validated.


        Post-page fields are returned when available. An omitted `view_count` means the video view count is unavailable;
        preserve previously known metrics rather than substituting zero. Cached post-list responses expose their
        documented subset of fields.


        Returns fresh `video_url` (single best stream) and `video_versions[]` (multi-bitrate). These are signed
        Instagram CDN URLs valid for ~24h — download promptly. For carousels with embedded videos, see
        `carousel_items[].video_url`.


        **Availability:** When live data is temporarily unavailable this endpoint returns `503` with `error.code:
        service_unavailable` in the standard error envelope. Honor `Retry-After` when present and retry with bounded
        backoff; API-key/OAuth usage billing and x402 do not charge these failures. MPP may already be settled before a
        later service error; retain its payment receipt and do not assume a `503` reverses that payment.


        **Pricing**: 0.18 credits per post scraped ($0.0018)
      parameters:
        - schema:
            type: string
            minLength: 1
            description: Instagram post shortcode from a /p/, /reel/, or /tv/ URL
            example: C0ABC123xyz
          in: path
          name: shortcode
          required: true
          description: Instagram post shortcode from a /p/, /reel/, or /tv/ URL
      responses:
        '200':
          description: >-
            A validated Instagram post with available media and observed engagement. Unavailable or gated media returns
            a temporary failure rather than an empty post or proof of deletion. Hidden or unavailable video views are
            omitted.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LiveInstagramPostResponse'
        '400':
          description: Validation error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '402':
          description: Account billing requires attention, or available credits cannot cover this request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiCreditError402'
        '403':
          description: Permission error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '429':
          description: >-
            Rate limit exceeded response. Check Retry-After header for backoff timing. Also returned (without
            RateLimit-* headers) when an IP is temporarily blocked after repeated failed authentication attempts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error429'
        '500':
          description: Internal server error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
        '502':
          description: >-
            The upstream source answered, but with data this endpoint cannot process — for example a response schema the
            source has retired. Unlike 503 this is deterministic: the same request will keep failing until a fix ships,
            so it never carries Retry-After and retrying only burns credits. These are alerted on automatically.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error502'
        '503':
          description: >-
            Service temporarily unavailable: a live data upstream, or a creator search, match or lookalike request that
            could not finish in time. Check Retry-After when present and retry with bounded backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error503'
  /v1/raw/instagram/posts:
    post:
      operationId: getLiveInstagramPosts
      summary: Get Live Instagram Posts
      tags:
        - Live Scraping
      description: >-
        Fetch fresh Instagram post-page data for a bounded list of shortcodes. This returns one item per requested
        shortcode with per-item success or error details. Transient upstream recovery is handled automatically within
        the request deadline.


        **Note:** Batch post lookup is capped at 20 shortcodes per request. API-key and OAuth calls are charged only for
        successful items; x402 and MPP use the advertised request price.


        Returns fresh `video_url` and `video_versions[]` per post (signed IG CDN URLs, ~24h validity). Batch up to 20
        posts at 0.18 credits ($0.0018) each.


        **Availability:** When live data is temporarily unavailable this endpoint returns `503` with `error.code:
        service_unavailable` in the standard error envelope. Honor `Retry-After` when present and retry with bounded
        backoff; API-key/OAuth usage billing and x402 do not charge these failures. MPP may already be settled before a
        later service error; retain its payment receipt and do not assume a `503` reverses that payment.


        **Pricing**: 0.18 credits per post scraped ($0.0018)
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LiveInstagramPostBatchBody'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LiveInstagramPostBatchResponse'
        '400':
          description: Validation error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '402':
          description: Account billing requires attention, or available credits cannot cover this request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiCreditError402'
        '403':
          description: Permission error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '429':
          description: >-
            Rate limit exceeded response. Check Retry-After header for backoff timing. Also returned (without
            RateLimit-* headers) when an IP is temporarily blocked after repeated failed authentication attempts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error429'
        '500':
          description: Internal server error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
        '502':
          description: >-
            The upstream source answered, but with data this endpoint cannot process — for example a response schema the
            source has retired. Unlike 503 this is deterministic: the same request will keep failing until a fix ships,
            so it never carries Retry-After and retrying only burns credits. These are alerted on automatically.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error502'
        '503':
          description: >-
            Service temporarily unavailable: a live data upstream, or a creator search, match or lookalike request that
            could not finish in time. Check Retry-After when present and retry with bounded backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error503'
  /v1/raw/instagram/transcript/{shortcode}:
    get:
      operationId: getLiveInstagramTranscript
      summary: Get Instagram Post Transcript
      tags:
        - Live Scraping
      description: >-
        Transcribe an Instagram video post by shortcode and return the raw post-page data used for transcription.


        **Availability:** When live data is temporarily unavailable this endpoint returns `503` with `error.code:
        service_unavailable` in the standard error envelope. Honor `Retry-After` when present and retry with bounded
        backoff; API-key/OAuth usage billing and x402 do not charge these failures. MPP may already be settled before a
        later service error; retain its payment receipt and do not assume a `503` reverses that payment.


        **Pricing**: 5 credits per transcript ($0.05)
      parameters:
        - schema:
            description: Optional language code for transcription. Omit to auto-detect.
            example: en
            type: string
          in: query
          name: language
          description: Optional language code for transcription. Omit to auto-detect.
        - schema:
            type: string
            minLength: 1
            description: Instagram post shortcode from a /p/, /reel/, or /tv/ URL
            example: C0ABC123xyz
          in: path
          name: shortcode
          required: true
          description: Instagram post shortcode from a /p/, /reel/, or /tv/ URL
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LiveInstagramTranscriptResponse'
        '400':
          description: Validation error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '402':
          description: Account billing requires attention, or available credits cannot cover this request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiCreditError402'
        '403':
          description: Permission error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '429':
          description: >-
            Rate limit exceeded response. Check Retry-After header for backoff timing. Also returned (without
            RateLimit-* headers) when an IP is temporarily blocked after repeated failed authentication attempts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error429'
        '500':
          description: Internal server error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
        '502':
          description: >-
            The upstream source answered, but with data this endpoint cannot process — for example a response schema the
            source has retired. Unlike 503 this is deterministic: the same request will keep failing until a fix ships,
            so it never carries Retry-After and retrying only burns credits. These are alerted on automatically.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error502'
        '503':
          description: >-
            Service temporarily unavailable: a live data upstream, or a creator search, match or lookalike request that
            could not finish in time. Check Retry-After when present and retry with bounded backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error503'
  /v1/raw/instagram/transcripts:
    post:
      operationId: getLiveInstagramTranscripts
      summary: Get Instagram Post Transcripts
      tags:
        - Live Scraping
      description: >-
        Transcribe a bounded list of Instagram video posts by shortcode and return one item per requested shortcode with
        per-item success or error details. Successful items include the raw post-page data used for transcription.


        **Note:** Batch transcription is capped at 10 shortcodes per request. API-key and OAuth calls are charged only
        for successful items; x402 and MPP use the advertised request price.


        **Availability:** When live data is temporarily unavailable this endpoint returns `503` with `error.code:
        service_unavailable` in the standard error envelope. Honor `Retry-After` when present and retry with bounded
        backoff; API-key/OAuth usage billing and x402 do not charge these failures. MPP may already be settled before a
        later service error; retain its payment receipt and do not assume a `503` reverses that payment.


        **Pricing**: 5 credits per transcript ($0.05)
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LiveInstagramTranscriptBatchBody'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LiveInstagramTranscriptBatchResponse'
        '400':
          description: Validation error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '402':
          description: Account billing requires attention, or available credits cannot cover this request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiCreditError402'
        '403':
          description: Permission error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '429':
          description: >-
            Rate limit exceeded response. Check Retry-After header for backoff timing. Also returned (without
            RateLimit-* headers) when an IP is temporarily blocked after repeated failed authentication attempts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error429'
        '500':
          description: Internal server error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
        '502':
          description: >-
            The upstream source answered, but with data this endpoint cannot process — for example a response schema the
            source has retired. Unlike 503 this is deterministic: the same request will keep failing until a fix ships,
            so it never carries Retry-After and retrying only burns credits. These are alerted on automatically.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error502'
        '503':
          description: >-
            Service temporarily unavailable: a live data upstream, or a creator search, match or lookalike request that
            could not finish in time. Check Retry-After when present and retry with bounded backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error503'
  /v1/raw/youtube/channel/{handle}:
    get:
      operationId: getLiveYouTubeChannel
      summary: Get Live YouTube Channel
      tags:
        - Live Scraping
      description: >-
        Fetch fresh YouTube channel data including subscriber count, video count, and total views.


        **Availability:** When live data is temporarily unavailable this endpoint returns `503` with `error.code:
        service_unavailable` in the standard error envelope. Honor `Retry-After` when present and retry with bounded
        backoff; API-key/OAuth usage billing and x402 do not charge these failures. MPP may already be settled before a
        later service error; retain its payment receipt and do not assume a `503` reverses that payment.


        **Pricing**: 0.18 credits per channel scraped ($0.0018)
      parameters:
        - schema:
            description: Include recent videos in response
            example: true
            type: boolean
          in: query
          name: include_videos
          description: Include recent videos in response
        - schema:
            default: 12
            description: Number of videos to include
            example: 12
            type: integer
            minimum: 1
            maximum: 50
          in: query
          name: video_limit
          description: Number of videos to include
        - schema:
            type: string
            minLength: 1
            description: >-
              YouTube channel handle or channel ID. Accepts a bare handle, an @handle, a UC-prefixed channel ID, or the
              corresponding full channel URL.
            example: '@techreviews'
          in: path
          name: handle
          required: true
          description: >-
            YouTube channel handle or channel ID. Accepts a bare handle, an @handle, a UC-prefixed channel ID, or the
            corresponding full channel URL.
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LiveYouTubeChannelResponse'
        '400':
          description: Validation error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '402':
          description: Account billing requires attention, or available credits cannot cover this request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiCreditError402'
        '403':
          description: Permission error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '429':
          description: >-
            Rate limit exceeded response. Check Retry-After header for backoff timing. Also returned (without
            RateLimit-* headers) when an IP is temporarily blocked after repeated failed authentication attempts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error429'
        '500':
          description: Internal server error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
        '502':
          description: >-
            The upstream source answered, but with data this endpoint cannot process — for example a response schema the
            source has retired. Unlike 503 this is deterministic: the same request will keep failing until a fix ships,
            so it never carries Retry-After and retrying only burns credits. These are alerted on automatically.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error502'
        '503':
          description: >-
            Service temporarily unavailable: a live data upstream, or a creator search, match or lookalike request that
            could not finish in time. Check Retry-After when present and retry with bounded backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error503'
  /v1/raw/youtube/video/{video_id}:
    get:
      operationId: getLiveYouTubeVideo
      summary: Get YouTube Video Details
      tags:
        - Live Scraping
      description: >-
        Fetch fresh video metadata including description, exact publish timestamp when available, views, likes,
        comments, tags, categories, and channel identity.


        **Availability:** When live data is temporarily unavailable this endpoint returns `503` with `error.code:
        service_unavailable` in the standard error envelope. Honor `Retry-After` when present and retry with bounded
        backoff; API-key/OAuth usage billing and x402 do not charge these failures. MPP may already be settled before a
        later service error; retain its payment receipt and do not assume a `503` reverses that payment.


        **Pricing**: 0.18 credits per video fetched ($0.0018)
      parameters:
        - schema:
            type: string
            pattern: ^[A-Za-z0-9_-]{11}$
            description: YouTube video ID
            example: dQw4w9WgXcQ
          in: path
          name: video_id
          required: true
          description: YouTube video ID
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/YouTubeVideoDetailsResponse'
        '400':
          description: Validation error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '402':
          description: Account billing requires attention, or available credits cannot cover this request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiCreditError402'
        '403':
          description: Permission error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '429':
          description: >-
            Rate limit exceeded response. Check Retry-After header for backoff timing. Also returned (without
            RateLimit-* headers) when an IP is temporarily blocked after repeated failed authentication attempts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error429'
        '500':
          description: Internal server error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
        '503':
          description: >-
            Service temporarily unavailable: a live data upstream, or a creator search, match or lookalike request that
            could not finish in time. Check Retry-After when present and retry with bounded backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error503'
  /v1/raw/youtube/transcript/{video_id}:
    get:
      operationId: getLiveYouTubeTranscript
      summary: Get YouTube Video Transcript
      tags:
        - Live Scraping
      description: >-
        Fetch YouTube video transcript/captions. Returns timestamped segments and full text. Useful for content
        analysis.


        **Supported sources:**

        - Manual captions (highest quality)

        - Auto-generated captions

        - Multiple language tracks


        **Caption availability:** A `403 scraping_failed` response with `error.details.upstream_error:
        content_unavailable` means YouTube did not make the video available to this request; it does not confirm
        deletion. Do not automatically repeat that request. A scheduled video whose captions are not ready returns `503
        service_unavailable` with `error.details.upstream_error: content_not_ready` and `Retry-After: 300`. Wait for
        that interval and keep later attempts bounded. Missing captions and private or removed videos return `404`.


        **Availability:** When live data is temporarily unavailable this endpoint returns `503` with `error.code:
        service_unavailable` in the standard error envelope. Honor `Retry-After` when present and retry with bounded
        backoff; API-key/OAuth usage billing and x402 do not charge these failures. MPP may already be settled before a
        later service error; retain its payment receipt and do not assume a `503` reverses that payment.


        **Pricing**: 0.18 credits per transcript ($0.0018)
      parameters:
        - schema:
            default: auto
            description: Language code or "auto" for automatic detection
            example: en
            type: string
          in: query
          name: language
          description: Language code or "auto" for automatic detection
        - schema:
            type: string
            pattern: ^[A-Za-z0-9_-]{11}$
            description: YouTube video ID
            example: dQw4w9WgXcQ
          in: path
          name: video_id
          required: true
          description: YouTube video ID
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LiveTranscriptResponse'
        '400':
          description: Validation error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '402':
          description: Account billing requires attention, or available credits cannot cover this request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiCreditError402'
        '403':
          description: Permission error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '429':
          description: >-
            Rate limit exceeded response. Check Retry-After header for backoff timing. Also returned (without
            RateLimit-* headers) when an IP is temporarily blocked after repeated failed authentication attempts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error429'
        '500':
          description: Internal server error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
        '502':
          description: >-
            The upstream source answered, but with data this endpoint cannot process — for example a response schema the
            source has retired. Unlike 503 this is deterministic: the same request will keep failing until a fix ships,
            so it never carries Retry-After and retrying only burns credits. These are alerted on automatically.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error502'
        '503':
          description: >-
            Service temporarily unavailable: a live data upstream, or a creator search, match or lookalike request that
            could not finish in time. Check Retry-After when present and retry with bounded backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error503'
  /v1/raw/youtube/channel-transcripts/{handle}:
    get:
      operationId: getLiveYouTubeChannelTranscripts
      summary: Get YouTube Channel Transcripts
      tags:
        - Live Scraping
      description: >-
        Fetch transcripts for multiple videos from a YouTube channel. Videos can be sorted by popularity, newest, or
        oldest before selection.


        **Features:**

        - Fetches up to 20 video transcripts per request

        - Sort by popular (most views), newest, or oldest

        - Partial success — individual video failures don't block the response

        - Optional timestamped segments for each transcript


        **Availability:** When live data is temporarily unavailable this endpoint returns `503` with `error.code:
        service_unavailable` in the standard error envelope. Honor `Retry-After` when present and retry with bounded
        backoff; API-key/OAuth usage billing and x402 do not charge these failures. MPP may already be settled before a
        later service error; retain its payment receipt and do not assume a `503` reverses that payment.


        **Pricing**: 0.18 credits per transcript fetched ($0.0018)
      parameters:
        - schema:
            default: 5
            description: Number of videos to fetch transcripts for (max 20)
            example: 5
            type: integer
            minimum: 1
            maximum: 20
          in: query
          name: video_limit
          description: Number of videos to fetch transcripts for (max 20)
        - schema:
            default: en
            description: Language code for transcripts
            example: en
            type: string
          in: query
          name: language
          description: Language code for transcripts
        - schema:
            default: newest
            description: How to sort channel videos before selecting
            example: newest
            type: string
            enum:
              - popular
              - newest
              - oldest
          in: query
          name: sort_by
          description: How to sort channel videos before selecting
        - schema:
            description: Include timestamped transcript segments in response
            example: false
            type: boolean
          in: query
          name: include_segments
          description: Include timestamped transcript segments in response
        - schema:
            type: string
            minLength: 1
            description: >-
              YouTube channel handle or channel ID. Accepts a bare handle, an @handle, a UC-prefixed channel ID, or the
              corresponding full channel URL.
            example: '@techreviews'
          in: path
          name: handle
          required: true
          description: >-
            YouTube channel handle or channel ID. Accepts a bare handle, an @handle, a UC-prefixed channel ID, or the
            corresponding full channel URL.
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LiveChannelTranscriptsResponse'
        '400':
          description: Validation error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '402':
          description: Account billing requires attention, or available credits cannot cover this request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiCreditError402'
        '403':
          description: Permission error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '429':
          description: >-
            Rate limit exceeded response. Check Retry-After header for backoff timing. Also returned (without
            RateLimit-* headers) when an IP is temporarily blocked after repeated failed authentication attempts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error429'
        '500':
          description: Internal server error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
        '502':
          description: >-
            The upstream source answered, but with data this endpoint cannot process — for example a response schema the
            source has retired. Unlike 503 this is deterministic: the same request will keep failing until a fix ships,
            so it never carries Retry-After and retrying only burns credits. These are alerted on automatically.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error502'
        '503':
          description: >-
            Service temporarily unavailable: a live data upstream, or a creator search, match or lookalike request that
            could not finish in time. Check Retry-After when present and retry with bounded backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error503'
  /v1/raw/youtube/search:
    get:
      operationId: searchYouTube
      summary: Search YouTube
      tags:
        - Live Scraping
      description: >-
        Search YouTube videos and channels.


        Each request fetches one page. Pass `next_cursor` back as `cursor` to fetch and bill the next page.


        Only a successful response with `next_cursor: null` marks completion. Invalid result pages return `502
        upstream_contract_broken`. Preserve collected results on failure. Stop automatic retries for `502
        upstream_contract_broken`; use bounded backoff with the same cursor for temporary `503` pagination failures.


        **Availability:** When live data is temporarily unavailable this endpoint returns `503` with `error.code:
        service_unavailable` in the standard error envelope. Honor `Retry-After` when present and retry with bounded
        backoff; API-key/OAuth usage billing and x402 do not charge these failures. MPP may already be settled before a
        later service error; retain its payment receipt and do not assume a `503` reverses that payment.


        **Pricing**: 0.18 credits per fetched page ($0.0018)
      parameters:
        - schema:
            type: string
            minLength: 1
            maxLength: 500
            description: Search query
            example: fitness workout
          in: query
          name: q
          required: true
          description: Search query
        - schema:
            default: 20
            description: Maximum number of results to return
            example: 20
            type: integer
            minimum: 1
            maximum: 50
          in: query
          name: limit
          description: Maximum number of results to return
        - schema:
            default: US
            description: Country code for localized results (ISO 3166-1 alpha-2)
            example: US
            type: string
            minLength: 2
            maxLength: 2
          in: query
          name: country_code
          description: Country code for localized results (ISO 3166-1 alpha-2)
        - schema:
            default: en
            description: Language code for results
            example: en
            type: string
            minLength: 2
            maxLength: 5
          in: query
          name: language_code
          description: Language code for results
        - schema:
            default: any
            description: Only return results uploaded within the selected window
            example: this_week
            type: string
            enum:
              - any
              - last_hour
              - today
              - this_week
              - this_month
              - this_year
          in: query
          name: upload_date
          description: Only return results uploaded within the selected window
        - schema:
            default: relevance
            description: Order results by relevance or view popularity
            example: popular
            type: string
            enum:
              - relevance
              - popular
          in: query
          name: sort_by
          description: Order results by relevance or view popularity
        - schema:
            default: all
            description: Return all result types or only videos
            example: videos
            type: string
            enum:
              - all
              - videos
          in: query
          name: content_type
          description: Return all result types or only videos
        - schema:
            default: any
            description: Filter videos by YouTube duration band
            example: long
            type: string
            enum:
              - any
              - short
              - medium
              - long
          in: query
          name: duration
          description: Filter videos by YouTube duration band
        - schema:
            description: >-
              Opaque cursor from next_cursor. Pass unchanged with the original query and filters. Invalid or expired
              cursors return 400; temporary pagination unavailability returns 503.
            type: string
            minLength: 1
            maxLength: 16000
          in: query
          name: cursor
          description: >-
            Opaque cursor from next_cursor. Pass unchanged with the original query and filters. Invalid or expired
            cursors return 400; temporary pagination unavailability returns 503.
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/YouTubeSearchResponse'
        '400':
          description: Validation error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '402':
          description: Account billing requires attention, or available credits cannot cover this request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiCreditError402'
        '403':
          description: Permission error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '429':
          description: >-
            Rate limit exceeded response. Check Retry-After header for backoff timing. Also returned (without
            RateLimit-* headers) when an IP is temporarily blocked after repeated failed authentication attempts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error429'
        '500':
          description: Internal server error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
        '502':
          description: >-
            The upstream source answered, but with data this endpoint cannot process — for example a response schema the
            source has retired. Unlike 503 this is deterministic: the same request will keep failing until a fix ships,
            so it never carries Retry-After and retrying only burns credits. These are alerted on automatically.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error502'
        '503':
          description: >-
            Service temporarily unavailable: a live data upstream, or a creator search, match or lookalike request that
            could not finish in time. Check Retry-After when present and retry with bounded backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error503'
  /v1/raw/youtube/typeahead:
    get:
      operationId: getYouTubeTypeahead
      summary: Get YouTube Search Suggestions
      tags:
        - Live Scraping
      description: >-
        Get localized YouTube search suggestions for a partial query.


        **Availability:** When live data is temporarily unavailable this endpoint returns `503` with `error.code:
        service_unavailable` in the standard error envelope. Honor `Retry-After` when present and retry with bounded
        backoff; API-key/OAuth usage billing and x402 do not charge these failures. MPP may already be settled before a
        later service error; retain its payment receipt and do not assume a `503` reverses that payment.


        **Pricing**: 0.18 credits per request ($0.0018)
      parameters:
        - schema:
            type: string
            minLength: 1
            maxLength: 200
            description: Partial search query
          in: query
          name: q
          required: true
          description: Partial search query
        - schema:
            default: US
            type: string
            minLength: 2
            maxLength: 2
          in: query
          name: country_code
        - schema:
            default: en
            type: string
            minLength: 2
            maxLength: 5
          in: query
          name: language_code
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/YouTubeTypeaheadResponse'
        '400':
          description: Validation error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '402':
          description: Account billing requires attention, or available credits cannot cover this request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiCreditError402'
        '403':
          description: Permission error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '429':
          description: >-
            Rate limit exceeded response. Check Retry-After header for backoff timing. Also returned (without
            RateLimit-* headers) when an IP is temporarily blocked after repeated failed authentication attempts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error429'
        '500':
          description: Internal server error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
        '503':
          description: >-
            Service temporarily unavailable: a live data upstream, or a creator search, match or lookalike request that
            could not finish in time. Check Retry-After when present and retry with bounded backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error503'
  /v1/raw/tiktok/videos:
    post:
      operationId: getLiveTikTokVideoBatch
      summary: Get TikTok Videos in a Batch
      tags:
        - Live Scraping
      description: >-
        Fetch up to 20 video URLs with ordered per-item results. Duplicate entries remain distinct requested items.
        Account credits charge successful items only at $0.0018 each. Premium payments quote all requested items and are
        nonrefundable once settled, including partial or failed items in a completed batch.


        **Availability:** When live data is temporarily unavailable this endpoint returns `503` with `error.code:
        service_unavailable` in the standard error envelope. Honor `Retry-After` when present and retry with bounded
        backoff; API-key/OAuth usage billing and x402 do not charge these failures. MPP may already be settled before a
        later service error; retain its payment receipt and do not assume a `503` reverses that payment.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LiveTikTokVideoBatchBody'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LiveTikTokVideoBatchResponse'
        '400':
          description: Validation error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '402':
          description: Account billing requires attention, or available credits cannot cover this request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiCreditError402'
        '403':
          description: Permission error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '422':
          description: >-
            Unprocessable entity response. The request was well-formed but a value failed a semantic rule (e.g. an
            invalid social handle format).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error422'
        '429':
          description: >-
            Rate limit exceeded response. Check Retry-After header for backoff timing. Also returned (without
            RateLimit-* headers) when an IP is temporarily blocked after repeated failed authentication attempts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error429'
        '500':
          description: Internal server error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
        '502':
          description: >-
            The upstream source answered, but with data this endpoint cannot process — for example a response schema the
            source has retired. Unlike 503 this is deterministic: the same request will keep failing until a fix ships,
            so it never carries Retry-After and retrying only burns credits. These are alerted on automatically.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error502'
        '503':
          description: >-
            Service temporarily unavailable: a live data upstream, or a creator search, match or lookalike request that
            could not finish in time. Check Retry-After when present and retry with bounded backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error503'
  /v1/raw/tiktok/video/transcripts:
    post:
      operationId: getLiveTikTokTranscriptBatch
      summary: Get TikTok Transcripts in a Batch
      tags:
        - Live Scraping
      description: >-
        Process up to 10 video URLs with ordered per-item results. Choose auto (default, $0.025 per item) or captions
        ($0.0018 per item, never generates). Account credits charge successful items only. Premium payments quote all
        requested items and are nonrefundable once settled, including partial or failed items in a completed batch.


        **Availability:** When live data is temporarily unavailable this endpoint returns `503` with `error.code:
        service_unavailable` in the standard error envelope. Honor `Retry-After` when present and retry with bounded
        backoff; API-key/OAuth usage billing and x402 do not charge these failures. MPP may already be settled before a
        later service error; retain its payment receipt and do not assume a `503` reverses that payment.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LiveTikTokTranscriptBatchBody'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LiveTikTokTranscriptBatchResponse'
        '400':
          description: Validation error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '402':
          description: Account billing requires attention, or available credits cannot cover this request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiCreditError402'
        '403':
          description: Permission error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '422':
          description: >-
            Unprocessable entity response. The request was well-formed but a value failed a semantic rule (e.g. an
            invalid social handle format).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error422'
        '429':
          description: >-
            Rate limit exceeded response. Check Retry-After header for backoff timing. Also returned (without
            RateLimit-* headers) when an IP is temporarily blocked after repeated failed authentication attempts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error429'
        '500':
          description: Internal server error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
        '502':
          description: >-
            The upstream source answered, but with data this endpoint cannot process — for example a response schema the
            source has retired. Unlike 503 this is deterministic: the same request will keep failing until a fix ships,
            so it never carries Retry-After and retrying only burns credits. These are alerted on automatically.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error502'
        '503':
          description: >-
            Service temporarily unavailable: a live data upstream, or a creator search, match or lookalike request that
            could not finish in time. Check Retry-After when present and retry with bounded backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error503'
  /v1/raw/tiktok/profile/{username}:
    get:
      operationId: getLiveTikTokProfile
      summary: Get Live TikTok Profile
      tags:
        - Live Scraping
      description: >-
        Fetch a normalized TikTok profile with current identity, biography, verification, and audience metrics.


        **Availability:** When live data is temporarily unavailable this endpoint returns `503` with `error.code:
        service_unavailable` in the standard error envelope. Honor `Retry-After` when present and retry with bounded
        backoff; API-key/OAuth usage billing and x402 do not charge these failures. MPP may already be settled before a
        later service error; retain its payment receipt and do not assume a `503` reverses that payment.


        **Pricing**: 0.18 credits per profile scraped ($0.0018)
      parameters:
        - schema:
            description: TikTok username, with or without a leading @
            example: creator
            type: string
          in: path
          name: username
          required: true
          description: TikTok username, with or without a leading @
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LiveTikTokProfileResponse'
        '400':
          description: Validation error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '402':
          description: Account billing requires attention, or available credits cannot cover this request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiCreditError402'
        '403':
          description: Permission error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '422':
          description: >-
            Unprocessable entity response. The request was well-formed but a value failed a semantic rule (e.g. an
            invalid social handle format).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error422'
        '429':
          description: >-
            Rate limit exceeded response. Check Retry-After header for backoff timing. Also returned (without
            RateLimit-* headers) when an IP is temporarily blocked after repeated failed authentication attempts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error429'
        '500':
          description: Internal server error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
        '502':
          description: >-
            The upstream source answered, but with data this endpoint cannot process — for example a response schema the
            source has retired. Unlike 503 this is deterministic: the same request will keep failing until a fix ships,
            so it never carries Retry-After and retrying only burns credits. These are alerted on automatically.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error502'
        '503':
          description: >-
            Service temporarily unavailable: a live data upstream, or a creator search, match or lookalike request that
            could not finish in time. Check Retry-After when present and retry with bounded backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error503'
  /v1/raw/tiktok/profile/{username}/videos:
    get:
      operationId: listLiveTikTokProfileVideos
      summary: List Live TikTok Profile Videos
      tags:
        - Live Scraping
      description: >-
        Fetch one cursor-paginated page of normalized TikTok videos. Signed media URLs are temporary and should be
        downloaded promptly.


        **Availability:** When live data is temporarily unavailable this endpoint returns `503` with `error.code:
        service_unavailable` in the standard error envelope. Honor `Retry-After` when present and retry with bounded
        backoff; API-key/OAuth usage billing and x402 do not charge these failures. MPP may already be settled before a
        later service error; retain its payment receipt and do not assume a `503` reverses that payment.


        **Pricing**: 0.18 credits per video page scraped ($0.0018)
      parameters:
        - schema:
            description: Opaque cursor from the previous response
            type: string
            minLength: 1
            maxLength: 2048
          in: query
          name: cursor
          description: Opaque cursor from the previous response
        - schema:
            default: latest
            description: Video ordering
            example: latest
            type: string
            enum:
              - latest
              - popular
          in: query
          name: sort_by
          description: Video ordering
        - schema:
            default: US
            description: TikTok resolution region (US only)
            example: US
            type: string
            const: US
          in: query
          name: region
          description: TikTok resolution region (US only)
        - schema:
            description: TikTok username, with or without a leading @
            example: creator
            type: string
          in: path
          name: username
          required: true
          description: TikTok username, with or without a leading @
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LiveTikTokProfileVideosResponse'
        '400':
          description: Validation error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '402':
          description: Account billing requires attention, or available credits cannot cover this request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiCreditError402'
        '403':
          description: Permission error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '422':
          description: >-
            Unprocessable entity response. The request was well-formed but a value failed a semantic rule (e.g. an
            invalid social handle format).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error422'
        '429':
          description: >-
            Rate limit exceeded response. Check Retry-After header for backoff timing. Also returned (without
            RateLimit-* headers) when an IP is temporarily blocked after repeated failed authentication attempts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error429'
        '500':
          description: Internal server error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
        '502':
          description: >-
            The upstream source answered, but with data this endpoint cannot process — for example a response schema the
            source has retired. Unlike 503 this is deterministic: the same request will keep failing until a fix ships,
            so it never carries Retry-After and retrying only burns credits. These are alerted on automatically.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error502'
        '503':
          description: >-
            Service temporarily unavailable: a live data upstream, or a creator search, match or lookalike request that
            could not finish in time. Check Retry-After when present and retry with bounded backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error503'
  /v1/raw/tiktok/video:
    get:
      operationId: getLiveTikTokVideo
      summary: Get Live TikTok Video
      tags:
        - Live Scraping
      description: >-
        Fetch normalized details and current engagement metrics for a TikTok video URL. Malformed URL inputs return HTTP
        400; correct the input before retrying. Signed media URLs are temporary and should be downloaded promptly.


        **Availability:** When live data is temporarily unavailable this endpoint returns `503` with `error.code:
        service_unavailable` in the standard error envelope. Honor `Retry-After` when present and retry with bounded
        backoff; API-key/OAuth usage billing and x402 do not charge these failures. MPP may already be settled before a
        later service error; retain its payment receipt and do not assume a `503` reverses that payment.


        **Pricing**: 0.18 credits per video scraped ($0.0018)
      parameters:
        - schema:
            description: HTTPS TikTok video or share URL
            example: https://www.tiktok.com/@creator/video/7517114944362499342
            $ref: '#/components/schemas/TikTokVideoUrl'
          in: query
          name: url
          required: true
          description: HTTPS TikTok video or share URL
        - schema:
            default: US
            description: TikTok resolution region (US only)
            example: US
            type: string
            const: US
          in: query
          name: region
          description: TikTok resolution region (US only)
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LiveTikTokVideoResponse'
        '400':
          description: Validation error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '402':
          description: Account billing requires attention, or available credits cannot cover this request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiCreditError402'
        '403':
          description: Permission error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '422':
          description: >-
            Unprocessable entity response. The request was well-formed but a value failed a semantic rule (e.g. an
            invalid social handle format).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error422'
        '429':
          description: >-
            Rate limit exceeded response. Check Retry-After header for backoff timing. Also returned (without
            RateLimit-* headers) when an IP is temporarily blocked after repeated failed authentication attempts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error429'
        '500':
          description: Internal server error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
        '502':
          description: >-
            The upstream source answered, but with data this endpoint cannot process — for example a response schema the
            source has retired. Unlike 503 this is deterministic: the same request will keep failing until a fix ships,
            so it never carries Retry-After and retrying only burns credits. These are alerted on automatically.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error502'
        '503':
          description: >-
            Service temporarily unavailable: a live data upstream, or a creator search, match or lookalike request that
            could not finish in time. Check Retry-After when present and retry with bounded backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error503'
  /v1/raw/tiktok/video/comments:
    get:
      operationId: listLiveTikTokVideoComments
      summary: List Live TikTok Video Comments
      tags:
        - Live Scraping
      description: >-
        Fetch one cursor-paginated page of normalized comments for a TikTok video URL.


        **Availability:** When live data is temporarily unavailable this endpoint returns `503` with `error.code:
        service_unavailable` in the standard error envelope. Honor `Retry-After` when present and retry with bounded
        backoff; API-key/OAuth usage billing and x402 do not charge these failures. MPP may already be settled before a
        later service error; retain its payment receipt and do not assume a `503` reverses that payment.


        **Pricing**: 0.18 credits per comment page scraped ($0.0018)
      parameters:
        - schema:
            description: HTTPS TikTok video or share URL
            example: https://www.tiktok.com/@creator/video/7517114944362499342
            $ref: '#/components/schemas/TikTokVideoUrl'
          in: query
          name: url
          required: true
          description: HTTPS TikTok video or share URL
        - schema:
            description: Opaque cursor from the previous response
            type: string
            minLength: 1
            maxLength: 2048
          in: query
          name: cursor
          description: Opaque cursor from the previous response
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LiveTikTokCommentsResponse'
        '400':
          description: Validation error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '402':
          description: Account billing requires attention, or available credits cannot cover this request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiCreditError402'
        '403':
          description: Permission error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '422':
          description: >-
            Unprocessable entity response. The request was well-formed but a value failed a semantic rule (e.g. an
            invalid social handle format).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error422'
        '429':
          description: >-
            Rate limit exceeded response. Check Retry-After header for backoff timing. Also returned (without
            RateLimit-* headers) when an IP is temporarily blocked after repeated failed authentication attempts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error429'
        '500':
          description: Internal server error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
        '502':
          description: >-
            The upstream source answered, but with data this endpoint cannot process — for example a response schema the
            source has retired. Unlike 503 this is deterministic: the same request will keep failing until a fix ships,
            so it never carries Retry-After and retrying only burns credits. These are alerted on automatically.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error502'
        '503':
          description: >-
            Service temporarily unavailable: a live data upstream, or a creator search, match or lookalike request that
            could not finish in time. Check Retry-After when present and retry with bounded backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error503'
  /v1/raw/tiktok/video/comment/replies:
    get:
      operationId: listLiveTikTokCommentReplies
      summary: List Live TikTok Comment Replies
      tags:
        - Live Scraping
      description: >-
        Fetch one cursor-paginated page of replies to a numeric parent comment ID. Keep the same video URL and parent
        comment ID when continuing with next_cursor.


        **Availability:** When live data is temporarily unavailable this endpoint returns `503` with `error.code:
        service_unavailable` in the standard error envelope. Honor `Retry-After` when present and retry with bounded
        backoff; API-key/OAuth usage billing and x402 do not charge these failures. MPP may already be settled before a
        later service error; retain its payment receipt and do not assume a `503` reverses that payment.


        **Pricing**: 0.18 credits per reply page scraped ($0.0018)
      parameters:
        - schema:
            description: HTTPS TikTok video or share URL
            example: https://www.tiktok.com/@creator/video/7517114944362499342
            $ref: '#/components/schemas/TikTokVideoUrl'
          in: query
          name: url
          required: true
          description: HTTPS TikTok video or share URL
        - schema:
            description: Opaque cursor from the previous response
            type: string
            minLength: 1
            maxLength: 2048
          in: query
          name: cursor
          description: Opaque cursor from the previous response
        - schema:
            type: string
            pattern: ^[1-9][0-9]{0,24}$
            description: Numeric ID of the parent comment
            example: '7517114944362499343'
          in: query
          name: comment_id
          required: true
          description: Numeric ID of the parent comment
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LiveTikTokCommentRepliesResponse'
        '400':
          description: Validation error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '402':
          description: Account billing requires attention, or available credits cannot cover this request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiCreditError402'
        '403':
          description: Permission error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '422':
          description: >-
            Unprocessable entity response. The request was well-formed but a value failed a semantic rule (e.g. an
            invalid social handle format).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error422'
        '429':
          description: >-
            Rate limit exceeded response. Check Retry-After header for backoff timing. Also returned (without
            RateLimit-* headers) when an IP is temporarily blocked after repeated failed authentication attempts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error429'
        '500':
          description: Internal server error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
        '502':
          description: >-
            The upstream source answered, but with data this endpoint cannot process — for example a response schema the
            source has retired. Unlike 503 this is deterministic: the same request will keep failing until a fix ships,
            so it never carries Retry-After and retrying only burns credits. These are alerted on automatically.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error502'
        '503':
          description: >-
            Service temporarily unavailable: a live data upstream, or a creator search, match or lookalike request that
            could not finish in time. Check Retry-After when present and retry with bounded backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error503'
  /v1/raw/tiktok/video/captions:
    get:
      operationId: getLiveTikTokVideoCaptions
      summary: Get TikTok Video Captions
      tags:
        - Live Scraping
      description: >-
        Return available TikTok captions without generating a transcript. Returns transcript_not_available when captions
        are unavailable. Successful cached results are charged at the ordinary rate.


        **Availability:** When live data is temporarily unavailable this endpoint returns `503` with `error.code:
        service_unavailable` in the standard error envelope. Honor `Retry-After` when present and retry with bounded
        backoff; API-key/OAuth usage billing and x402 do not charge these failures. MPP may already be settled before a
        later service error; retain its payment receipt and do not assume a `503` reverses that payment.


        **Pricing**: 0.18 credits per successful caption response ($0.0018)
      parameters:
        - schema:
            $ref: '#/components/schemas/TikTokVideoUrl'
          in: query
          name: url
          required: true
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LiveTikTokCaptionsResponse'
        '400':
          description: Validation error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '402':
          description: Account billing requires attention, or available credits cannot cover this request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiCreditError402'
        '403':
          description: Permission error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '422':
          description: >-
            Unprocessable entity response. The request was well-formed but a value failed a semantic rule (e.g. an
            invalid social handle format).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error422'
        '429':
          description: >-
            Rate limit exceeded response. Check Retry-After header for backoff timing. Also returned (without
            RateLimit-* headers) when an IP is temporarily blocked after repeated failed authentication attempts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error429'
        '500':
          description: Internal server error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
        '502':
          description: >-
            The upstream source answered, but with data this endpoint cannot process — for example a response schema the
            source has retired. Unlike 503 this is deterministic: the same request will keep failing until a fix ships,
            so it never carries Retry-After and retrying only burns credits. These are alerted on automatically.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error502'
        '503':
          description: >-
            Service temporarily unavailable: a live data upstream, or a creator search, match or lookalike request that
            could not finish in time. Check Retry-After when present and retry with bounded backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error503'
  /v1/raw/tiktok/music:
    get:
      operationId: getLiveTikTokMusic
      summary: Get TikTok Sound Details
      tags:
        - Live Scraping
      description: >-
        Fetch metadata for a TikTok sound clip by music_id. Unknown fields are null. Audio and cover URLs are temporary
        upstream links, not durable downloads.


        **Availability:** When live data is temporarily unavailable this endpoint returns `503` with `error.code:
        service_unavailable` in the standard error envelope. Honor `Retry-After` when present and retry with bounded
        backoff; API-key/OAuth usage billing and x402 do not charge these failures. MPP may already be settled before a
        later service error; retain its payment receipt and do not assume a `503` reverses that payment.


        **Pricing**: 0.18 credits per sound lookup ($0.0018)
      parameters:
        - schema:
            type: string
            pattern: ^[1-9][0-9]{0,24}$
            description: TikTok sound clip ID, not a recording or album ID
          in: query
          name: music_id
          required: true
          description: TikTok sound clip ID, not a recording or album ID
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LiveTikTokMusicResponse'
        '400':
          description: Validation error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '402':
          description: Account billing requires attention, or available credits cannot cover this request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiCreditError402'
        '403':
          description: Permission error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '422':
          description: >-
            Unprocessable entity response. The request was well-formed but a value failed a semantic rule (e.g. an
            invalid social handle format).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error422'
        '429':
          description: >-
            Rate limit exceeded response. Check Retry-After header for backoff timing. Also returned (without
            RateLimit-* headers) when an IP is temporarily blocked after repeated failed authentication attempts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error429'
        '500':
          description: Internal server error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
        '502':
          description: >-
            The upstream source answered, but with data this endpoint cannot process — for example a response schema the
            source has retired. Unlike 503 this is deterministic: the same request will keep failing until a fix ships,
            so it never carries Retry-After and retrying only burns credits. These are alerted on automatically.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error502'
        '503':
          description: >-
            Service temporarily unavailable: a live data upstream, or a creator search, match or lookalike request that
            could not finish in time. Check Retry-After when present and retry with bounded backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error503'
  /v1/raw/tiktok/search/users:
    get:
      operationId: searchLiveTikTokUsers
      summary: Search TikTok Users
      tags:
        - Live Scraping
      description: >-
        Fetch one page of TikTok user search results. Unknown profile fields are null. Continue with next_cursor and the
        same query; treat cursors as opaque. A successful page is charged once, including an empty page.


        **Availability:** When live data is temporarily unavailable this endpoint returns `503` with `error.code:
        service_unavailable` in the standard error envelope. Honor `Retry-After` when present and retry with bounded
        backoff; API-key/OAuth usage billing and x402 do not charge these failures. MPP may already be settled before a
        later service error; retain its payment receipt and do not assume a `503` reverses that payment.


        **Pricing**: 0.18 credits per user search page ($0.0018)
      parameters:
        - schema:
            type: string
            minLength: 1
            maxLength: 100
            pattern: ^[^\u0000-\u001f\u007f-\u009f]+$
          in: query
          name: query
          required: true
        - schema:
            type: string
            minLength: 1
            maxLength: 2048
          in: query
          name: cursor
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LiveTikTokUserSearchResponse'
        '400':
          description: Validation error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '402':
          description: Account billing requires attention, or available credits cannot cover this request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiCreditError402'
        '403':
          description: Permission error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '422':
          description: >-
            Unprocessable entity response. The request was well-formed but a value failed a semantic rule (e.g. an
            invalid social handle format).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error422'
        '429':
          description: >-
            Rate limit exceeded response. Check Retry-After header for backoff timing. Also returned (without
            RateLimit-* headers) when an IP is temporarily blocked after repeated failed authentication attempts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error429'
        '500':
          description: Internal server error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
        '502':
          description: >-
            The upstream source answered, but with data this endpoint cannot process — for example a response schema the
            source has retired. Unlike 503 this is deterministic: the same request will keep failing until a fix ships,
            so it never carries Retry-After and retrying only burns credits. These are alerted on automatically.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error502'
        '503':
          description: >-
            Service temporarily unavailable: a live data upstream, or a creator search, match or lookalike request that
            could not finish in time. Check Retry-After when present and retry with bounded backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error503'
  /v1/raw/tiktok/search/videos:
    get:
      operationId: searchLiveTikTokVideos
      summary: Search TikTok Videos
      tags:
        - Live Scraping
      description: >-
        Fetch one relevance-ordered page of TikTok videos matching a query. Continue with next_cursor and the same
        query; cursors are opaque. Duplicate results are preserved. Each successful page, including an empty page, is
        charged once. Media links are temporary.


        **Availability:** When live data is temporarily unavailable this endpoint returns `503` with `error.code:
        service_unavailable` in the standard error envelope. Honor `Retry-After` when present and retry with bounded
        backoff; API-key/OAuth usage billing and x402 do not charge these failures. MPP may already be settled before a
        later service error; retain its payment receipt and do not assume a `503` reverses that payment.


        **Pricing**: 0.18 credits per video search page ($0.0018)
      parameters:
        - schema:
            type: string
            minLength: 1
            maxLength: 100
            pattern: ^[^\u0000-\u001f\u007f-\u009f]+$
          in: query
          name: query
          required: true
        - schema:
            type: string
            minLength: 1
            maxLength: 2048
          in: query
          name: cursor
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LiveTikTokVideoSearchResponse'
        '400':
          description: Validation error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '402':
          description: Account billing requires attention, or available credits cannot cover this request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiCreditError402'
        '403':
          description: Permission error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '422':
          description: >-
            Unprocessable entity response. The request was well-formed but a value failed a semantic rule (e.g. an
            invalid social handle format).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error422'
        '429':
          description: >-
            Rate limit exceeded response. Check Retry-After header for backoff timing. Also returned (without
            RateLimit-* headers) when an IP is temporarily blocked after repeated failed authentication attempts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error429'
        '500':
          description: Internal server error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
        '502':
          description: >-
            The upstream source answered, but with data this endpoint cannot process — for example a response schema the
            source has retired. Unlike 503 this is deterministic: the same request will keep failing until a fix ships,
            so it never carries Retry-After and retrying only burns credits. These are alerted on automatically.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error502'
        '503':
          description: >-
            Service temporarily unavailable: a live data upstream, or a creator search, match or lookalike request that
            could not finish in time. Check Retry-After when present and retry with bounded backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error503'
  /v1/raw/tiktok/hashtag/videos:
    get:
      operationId: getLiveTikTokHashtagVideos
      summary: Get TikTok Hashtag Videos
      tags:
        - Live Scraping
      description: >-
        Fetch one page of videos under a hashtag, supplied without #. Continue with next_cursor and the same hashtag;
        cursors are opaque. Duplicate results are preserved. Each successful page, including an empty page, is charged
        once. Media links are temporary.


        **Availability:** When live data is temporarily unavailable this endpoint returns `503` with `error.code:
        service_unavailable` in the standard error envelope. Honor `Retry-After` when present and retry with bounded
        backoff; API-key/OAuth usage billing and x402 do not charge these failures. MPP may already be settled before a
        later service error; retain its payment receipt and do not assume a `503` reverses that payment.


        **Pricing**: 0.18 credits per hashtag video page ($0.0018)
      parameters:
        - schema:
            type: string
            minLength: 1
            maxLength: 100
            pattern: ^[^#\s\u0000-\u001f\u007f-\u009f]+$
          in: query
          name: hashtag
          required: true
        - schema:
            type: string
            minLength: 1
            maxLength: 2048
          in: query
          name: cursor
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LiveTikTokHashtagVideosResponse'
        '400':
          description: Validation error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '402':
          description: Account billing requires attention, or available credits cannot cover this request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiCreditError402'
        '403':
          description: Permission error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '422':
          description: >-
            Unprocessable entity response. The request was well-formed but a value failed a semantic rule (e.g. an
            invalid social handle format).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error422'
        '429':
          description: >-
            Rate limit exceeded response. Check Retry-After header for backoff timing. Also returned (without
            RateLimit-* headers) when an IP is temporarily blocked after repeated failed authentication attempts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error429'
        '500':
          description: Internal server error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
        '502':
          description: >-
            The upstream source answered, but with data this endpoint cannot process — for example a response schema the
            source has retired. Unlike 503 this is deterministic: the same request will keep failing until a fix ships,
            so it never carries Retry-After and retrying only burns credits. These are alerted on automatically.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error502'
        '503':
          description: >-
            Service temporarily unavailable: a live data upstream, or a creator search, match or lookalike request that
            could not finish in time. Check Retry-After when present and retry with bounded backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error503'
  /v1/raw/tiktok/music/videos:
    get:
      operationId: getLiveTikTokMusicVideos
      summary: Get TikTok Music Videos
      tags:
        - Live Scraping
      description: >-
        Fetch one page of TikTok videos using a sound clip, identified by music_id. Continue with next_cursor and the
        same music_id; cursors are opaque. Duplicate results are preserved. Each successful page, including an empty
        page, is charged once. Media links are temporary.


        **Availability:** When live data is temporarily unavailable this endpoint returns `503` with `error.code:
        service_unavailable` in the standard error envelope. Honor `Retry-After` when present and retry with bounded
        backoff; API-key/OAuth usage billing and x402 do not charge these failures. MPP may already be settled before a
        later service error; retain its payment receipt and do not assume a `503` reverses that payment.


        **Pricing**: 0.18 credits per music video page ($0.0018)
      parameters:
        - schema:
            type: string
            pattern: ^[1-9][0-9]{0,24}$
            description: TikTok sound clip ID, not a recording or album ID
          in: query
          name: music_id
          required: true
          description: TikTok sound clip ID, not a recording or album ID
        - schema:
            type: string
            minLength: 1
            maxLength: 2048
          in: query
          name: cursor
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LiveTikTokMusicVideosResponse'
        '400':
          description: Validation error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '402':
          description: Account billing requires attention, or available credits cannot cover this request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiCreditError402'
        '403':
          description: Permission error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '422':
          description: >-
            Unprocessable entity response. The request was well-formed but a value failed a semantic rule (e.g. an
            invalid social handle format).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error422'
        '429':
          description: >-
            Rate limit exceeded response. Check Retry-After header for backoff timing. Also returned (without
            RateLimit-* headers) when an IP is temporarily blocked after repeated failed authentication attempts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error429'
        '500':
          description: Internal server error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
        '502':
          description: >-
            The upstream source answered, but with data this endpoint cannot process — for example a response schema the
            source has retired. Unlike 503 this is deterministic: the same request will keep failing until a fix ships,
            so it never carries Retry-After and retrying only burns credits. These are alerted on automatically.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error502'
        '503':
          description: >-
            Service temporarily unavailable: a live data upstream, or a creator search, match or lookalike request that
            could not finish in time. Check Retry-After when present and retry with bounded backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error503'
  /v1/raw/tiktok/video/transcript:
    get:
      operationId: getLiveTikTokVideoTranscript
      summary: Get TikTok Video Transcript
      tags:
        - Live Scraping
      description: >-
        Fetch or generate a normalized TikTok transcript with plain text and timestamped segments. The detected-language
        transcript is reused on later requests.


        **Availability:** When live data is temporarily unavailable this endpoint returns `503` with `error.code:
        service_unavailable` in the standard error envelope. Honor `Retry-After` when present and retry with bounded
        backoff; API-key/OAuth usage billing and x402 do not charge these failures. MPP may already be settled before a
        later service error; retain its payment receipt and do not assume a `503` reverses that payment.


        **Pricing**: 2.5 credits per transcript ($0.025)
      parameters:
        - schema:
            description: HTTPS TikTok video or share URL
            example: https://www.tiktok.com/@creator/video/7517114944362499342
            $ref: '#/components/schemas/TikTokVideoUrl'
          in: query
          name: url
          required: true
          description: HTTPS TikTok video or share URL
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LiveTikTokTranscriptResponse'
        '400':
          description: Validation error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Authentication error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '402':
          description: Account billing requires attention, or available credits cannot cover this request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiCreditError402'
        '403':
          description: Permission error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error403'
        '404':
          description: Not found error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '422':
          description: >-
            Unprocessable entity response. The request was well-formed but a value failed a semantic rule (e.g. an
            invalid social handle format).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error422'
        '429':
          description: >-
            Rate limit exceeded response. Check Retry-After header for backoff timing. Also returned (without
            RateLimit-* headers) when an IP is temporarily blocked after repeated failed authentication attempts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error429'
        '500':
          description: Internal server error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
        '502':
          description: >-
            The upstream source answered, but with data this endpoint cannot process — for example a response schema the
            source has retired. Unlike 503 this is deterministic: the same request will keep failing until a fix ships,
            so it never carries Retry-After and retrying only burns credits. These are alerted on automatically.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error502'
        '503':
          description: >-
            Service temporarily unavailable: a live data upstream, or a creator search, match or lookalike request that
            could not finish in time. Check Retry-After when present and retry with bounded backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error503'
servers:
  - url: https://api.influship.com
    description: Production
security:
  - ApiKeyAuth: []
tags:
  - name: Shortlists
    description: Private creator shortlists saved to your API account or OAuth user.
  - name: Health
    description: API health and status endpoints
  - name: Creators
    description: >-
      Retrieve creator profiles and discover new creators through search, autocomplete, and lookalike matching. Creators
      are cross-platform entities that may have profiles on multiple social networks.
  - name: Profiles
    description: >-
      Access individual social media profiles with detailed metrics, growth data, and activity information. Profiles are
      platform-specific accounts linked to creators.
  - name: Creator Emails
    description: >-
      Look up known creator email addresses by creator ID or social username. Empty or unresolved results are not
      billable.
  - name: Posts
    description: Retrieve and analyze social media posts with engagement metrics, media content, and performance data.
  - name: Search
    description: >-
      AI-powered semantic search to find creators using natural language queries. Understands intent and context to
      match creators based on content themes, audience, and style.
  - name: Live Scraping
    description: Research Instagram, TikTok, and YouTube profiles, content, metrics, and transcripts with live platform endpoints.
