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

# Search

> Unified creator search for exact, broad, and filter-only queries.

**Exact lookup:** Provide `creator_url` (or an exact `query`) to quickly find the creator and linked channels.

**Broad discovery:** Provide `query` with optional filters (platforms, category_ids, follower_bucket, follower range, country/language).

**Filter-only browse:** Provide `category_ids` + `follower_bucket` without a text query to browse creators by category and size.

Pass `next_cursor` from any search response back as `cursor` with the same query and filters to fetch the next page.

Use the `include` query parameter for optional expansions. In `/creators/search`, include expansions are supported only for exact `creator_url` lookups.



## OpenAPI

````yaml /api-reference/openapi.json post /v1/creators/search
openapi: 3.1.0
info:
  title: Upriver API
  description: >-
    A social insights API for ad generation platforms. It provides structured
    signals, like psychographics, behavioral insights, trends, and audience
    language, to help AI models generate relevant, higher-converting ads.
  version: 1.0.0
servers:
  - url: https://api.upriver.ai
    description: Production API server
security: []
tags:
  - name: Brands
  - name: Products
  - name: Creators
  - name: Audience
  - name: Sponsorships
  - name: Trends
  - name: Breakout Topics
  - name: Taxonomy
paths:
  /v1/creators/search:
    post:
      tags:
        - Creators
      summary: Search
      description: >-
        Unified creator search for exact, broad, and filter-only queries.


        **Exact lookup:** Provide `creator_url` (or an exact `query`) to quickly
        find the creator and linked channels.


        **Broad discovery:** Provide `query` with optional filters (platforms,
        category_ids, follower_bucket, follower range, country/language).


        **Filter-only browse:** Provide `category_ids` + `follower_bucket`
        without a text query to browse creators by category and size.


        Pass `next_cursor` from any search response back as `cursor` with the
        same query and filters to fetch the next page.


        Use the `include` query parameter for optional expansions. In
        `/creators/search`, include expansions are supported only for exact
        `creator_url` lookups.
      operationId: creator_search
      parameters:
        - name: include
          in: query
          required: false
          schema:
            type: array
            items:
              type: string
            description: >-
              Optional expansions to include in the response.


              The same include options are available on `GET /v1/creators`
              (lookup by URL) and `GET /v1/creators/{creator_id}` (lookup by
              Upriver creator ID).


              **Include values and what each adds:**

              - `engagement_metrics`: Recent per-channel engagement performance
              (average views, likes, comments, engagement rate). Returned as
              `channels[].engagement_metrics`.

              - `video_metrics`: Per-channel upload cadence and duration-based
              inventory signals over a trailing 12-week window (YouTube).
              Returned as `channels[].video_metrics`.

              - `relative_metrics`: Per-channel public benchmark summaries
              compared with similar creators. Returned as
              `channels[].relative_metrics`.

              - `bio`: Creator summary and key context. Returned as top-level
              `bio`.

              - `audience`: Directional audience demographics (age, gender,
              geography). Returned as top-level `audience`.

              - `brand_safety`: Brand safety advisories with citations. Returned
              as top-level `brand_safety`.

              - `email`: Public contact email addresses the creator has
              published for business inquiries, gathered across their linked
              channels. Returned as top-level `emails`.

              - `creator_id`: Backward-compatible no-op; `creator_id` is always
              returned.


              **Format:**

              - Repeat params: `?include=engagement_metrics&include=bio`

              - CSV: `?include=engagement_metrics,bio`


              **`/creators/search` modes:** `include=email` is available in
              every mode (broad query, filter-only browse, and exact
              `creator_url`), and may also be passed in the request body. The
              richer expansions (`engagement_metrics`, `video_metrics`,
              `relative_metrics`, `bio`, `audience`, `brand_safety`) are
              returned only for exact `creator_url` lookups; in
              broad/filter-only mode they are rejected — call `/creators` or
              `/creators/{creator_id}` to enrich a selected result.
            default: []
            title: Include
          description: >-
            Optional expansions to include in the response.


            The same include options are available on `GET /v1/creators` (lookup
            by URL) and `GET /v1/creators/{creator_id}` (lookup by Upriver
            creator ID).


            **Include values and what each adds:**

            - `engagement_metrics`: Recent per-channel engagement performance
            (average views, likes, comments, engagement rate). Returned as
            `channels[].engagement_metrics`.

            - `video_metrics`: Per-channel upload cadence and duration-based
            inventory signals over a trailing 12-week window (YouTube). Returned
            as `channels[].video_metrics`.

            - `relative_metrics`: Per-channel public benchmark summaries
            compared with similar creators. Returned as
            `channels[].relative_metrics`.

            - `bio`: Creator summary and key context. Returned as top-level
            `bio`.

            - `audience`: Directional audience demographics (age, gender,
            geography). Returned as top-level `audience`.

            - `brand_safety`: Brand safety advisories with citations. Returned
            as top-level `brand_safety`.

            - `email`: Public contact email addresses the creator has published
            for business inquiries, gathered across their linked channels.
            Returned as top-level `emails`.

            - `creator_id`: Backward-compatible no-op; `creator_id` is always
            returned.


            **Format:**

            - Repeat params: `?include=engagement_metrics&include=bio`

            - CSV: `?include=engagement_metrics,bio`


            **`/creators/search` modes:** `include=email` is available in every
            mode (broad query, filter-only browse, and exact `creator_url`), and
            may also be passed in the request body. The richer expansions
            (`engagement_metrics`, `video_metrics`, `relative_metrics`, `bio`,
            `audience`, `brand_safety`) are returned only for exact
            `creator_url` lookups; in broad/filter-only mode they are rejected —
            call `/creators` or `/creators/{creator_id}` to enrich a selected
            result.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreatorSearchInput'
      responses:
        '200':
          description: JSON object containing associated social profiles
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreatorSearchResponse'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
      security:
        - APIKeyHeader: []
components:
  schemas:
    CreatorSearchInput:
      properties:
        creator_url:
          anyOf:
            - type: string
            - type: 'null'
          title: Creator Url
          description: Known social media URL for the creator.
          examples:
            - https://www.youtube.com/@MrBeast
        name_or_handle:
          anyOf:
            - type: string
            - type: 'null'
          title: Name Or Handle
          description: >-
            Resolve a specific creator by handle or display name. Matches
            exactly, by prefix, and by fuzzy substring (e.g. 'beast' finds
            'MrBeast'). For discovery, use the category/follower/platform
            filters instead.
          examples:
            - MrBeast
            - mkbhd
        creator_name:
          anyOf:
            - type: string
            - type: 'null'
          title: Creator Name
          description: Deprecated. Use `name_or_handle`.
          deprecated: true
          examples:
            - MrBeast
        query:
          anyOf:
            - type: string
            - type: 'null'
          title: Query
          description: Deprecated. Use `name_or_handle` for creator resolution.
          deprecated: true
          examples:
            - '@mkbhd'
            - tech creators
        limit:
          type: integer
          maximum: 50
          minimum: 1
          title: Limit
          description: Maximum number of creators to return, from 1 to 50.
          default: 10
        platforms:
          anyOf:
            - items:
                type: string
              type: array
            - type: 'null'
          title: Platforms
          description: >-
            Optional platform filter. Supported platforms: instagram, podcast,
            spotify, substack, tiktok, twitch, x, youtube (the alias `twitter`
            is accepted for `x`). Any other value returns a 400 error.
          examples:
            - - youtube
              - tiktok
        category_ids:
          anyOf:
            - items:
                type: string
              type: array
            - type: 'null'
          title: Category Ids
          description: >-
            Optional category filter using taxonomy IDs (e.g. technology,
            tech_news_lifestyle).
          examples:
            - - technology
              - tech_news_lifestyle
        categories:
          anyOf:
            - items:
                type: string
              type: array
            - type: 'null'
          title: Categories
          description: Free-text category keywords to filter results by content category.
          examples:
            - - gaming and esports
              - AI tools
        min_followers:
          anyOf:
            - type: integer
              minimum: 0
            - type: 'null'
          title: Min Followers
          description: Optional minimum follower/subscriber count filter.
          examples:
            - 10000
        max_followers:
          anyOf:
            - type: integer
              minimum: 0
            - type: 'null'
          title: Max Followers
          description: Optional maximum follower/subscriber count filter.
          examples:
            - 5000000
        follower_bucket:
          anyOf:
            - items:
                type: string
              type: array
            - type: 'null'
          title: Follower Bucket
          description: Follower count filter using bucket IDs.
          examples:
            - - 10k_50k
              - 50k_100k
        cursor:
          anyOf:
            - type: string
            - type: 'null'
          title: Cursor
          description: Opaque cursor from a previous response for pagination.
        creator_country:
          anyOf:
            - type: string
            - items:
                type: string
              type: array
            - type: 'null'
          title: Creator Country
          description: >-
            Filter by where creators are based, as one or more ISO 3166-1
            alpha-2 country codes (e.g. US). Location coverage varies by
            platform, and not every creator has a known location.
          examples:
            - - US
            - - US
              - GB
        audience_country:
          anyOf:
            - type: string
            - items:
                type: string
              type: array
            - type: 'null'
          title: Audience Country
          description: >-
            Filter by where a creator's audience is located, as one or more ISO
            3166-1 alpha-2 country codes. Matches creators whose known audience
            includes any of these countries, or who are themselves based in
            them.
          examples:
            - - US
            - - US
              - CA
        creator_language:
          anyOf:
            - type: string
            - type: 'null'
          title: Creator Language
          description: Optional creator language filter.
          examples:
            - en
        has_email:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Has Email
          description: >-
            Filter by whether the creator has at least one public contact email
            available. `true` returns only creators with a contact email;
            `false` returns only those without; omit to include both.
          examples:
            - true
        include:
          anyOf:
            - items:
                type: string
              type: array
            - type: 'null'
          title: Include
          description: >-
            Optional response expansions, equivalent to the `include` query
            parameter (the two are merged). In broad/filter-only search only
            `email` is supported; other expansions require an exact
            `creator_url`.
          examples:
            - - email
        content_query:
          anyOf:
            - type: string
            - type: 'null'
          title: Content Query
          description: >-
            Describe the kind of content or creator you're looking for in plain
            language, and results are ranked by how well each creator's content
            matches — going beyond name and handle matching. Combine with the
            category, platform, follower, country, and language filters to
            narrow the field. When set, this drives ranking and any name/handle
            'query' is not applied.
          examples:
            - cozy gaming creators
            - football players
            - creators who reviewed the DJI Pocket 3
      type: object
      title: CreatorSearchInput
      description: Input payload for creator discovery.
    CreatorSearchResponse:
      properties:
        results:
          items:
            $ref: '#/components/schemas/CreatorSearchResult'
          type: array
          title: Results
          description: >-
            Ordered list of creator matches. The first result is the best
            canonical match when an exact creator exists.
        next_cursor:
          anyOf:
            - type: string
            - type: 'null'
          title: Next Cursor
          description: >-
            Opaque cursor for fetching the next page of results. Null when the
            current ranked result frontier is exhausted.
      type: object
      title: CreatorSearchResponse
      description: Envelope returned by the creator search endpoint.
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
      type: object
      title: HTTPValidationError
    CreatorSearchResult:
      properties:
        score:
          anyOf:
            - type: number
              maximum: 1
              minimum: 0
            - type: 'null'
          title: Score
          description: >-
            Relevance score in [0,1] for this result, where higher is a stronger
            match. Returned for keyword and URL search. Omitted for
            category/size browse, which has no query to rank relevance against
            and is ordered by audience size instead.
        similarity_score:
          anyOf:
            - type: number
              maximum: 1
              minimum: 0
            - type: 'null'
          title: Similarity Score
          description: >-
            Similarity score in [0,1] for similar-creator discovery. Higher
            means the result is more similar to the anchor creator.
        similarity_signals:
          anyOf:
            - items:
                type: string
              type: array
            - type: 'null'
          title: Similarity Signals
          description: >-
            Human-readable signals explaining why a creator matched (e.g.,
            shared topics, niche, or profession). Present for similar-creator
            discovery and for natural-language content searches; omitted from
            plain keyword and filter-only results.
        bio:
          anyOf:
            - $ref: '#/components/schemas/CreatorBio'
            - type: 'null'
          description: >-
            Biographical summary of the creator. Only present when include=bio
            is specified.
        channels:
          items:
            $ref: '#/components/schemas/CreatorPlatform'
          type: array
          title: Channels
          description: Social media channels for the creator across supported platforms.
        associated_creators:
          items:
            $ref: '#/components/schemas/CreatorAssociatedCreator'
          type: array
          title: Associated Creators
          description: Distinct associated creator clusters related to this creator.
        labels:
          items:
            $ref: '#/components/schemas/CreatorLabel'
          type: array
          title: Labels
          description: >-
            Descriptive labels for the creator. Includes stable categories
            (type='category', use for filtering) and dynamic tags (type='tag').
            See /media_categories for the full category taxonomy.
          examples:
            - - id: sports
                level: 1
                name: Sports
                type: category
              - id: nfl
                level: 2
                name: NFL
                parent_id: sports
                type: category
            - - id: beauty
                level: 1
                name: Beauty
                type: category
              - id: skincare
                level: 2
                name: Skincare
                parent_id: beauty
                type: category
              - id: clean-beauty-expert
                name: Clean Beauty Expert
                type: tag
        creator_id:
          anyOf:
            - type: string
            - type: 'null'
          title: Creator Id
          description: >-
            Upriver creator ID for the creator's unified cross-platform
            identity. Present once a creator has been resolved to a unified
            identity; when present, store and reuse it for consistency across
            API calls. May be absent for creators not yet resolved to a unified
            identity (common for single-platform results) — re-query those by a
            channel URL instead.
        emails:
          anyOf:
            - items:
                type: string
              type: array
            - type: 'null'
          title: Emails
          description: >-
            Public contact email addresses for the creator, if any are
            available. Returned only when requested via include=email.
          examples:
            - - press@creator.com
        skipped_enrichments:
          anyOf:
            - $ref: '#/components/schemas/CreatorSkippedEnrichments'
            - type: 'null'
          description: >-
            Compact metadata for requested enrichments that were skipped and
            therefore omitted from their top-level keys.
        tags:
          items:
            $ref: '#/components/schemas/CreatorTag'
          type: array
          title: Tags
          description: >-
            DEPRECATED: Use 'labels' instead. This field will be removed in a
            future version.
          deprecated: true
        audience:
          anyOf:
            - $ref: '#/components/schemas/CreatorAudience'
            - type: 'null'
          description: >-
            Directional audience demographics. Only present when
            include=audience is specified. `age.min_age`/`max_age` is a
            directional envelope; `age.segments` contains explicit percentage
            buckets and may be partial.
      type: object
      title: CreatorSearchResult
      description: Single search match containing primary channels for a creator.
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
              - type: string
              - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
      type: object
      required:
        - loc
        - msg
        - type
      title: ValidationError
    CreatorBio:
      properties:
        status:
          anyOf:
            - type: string
              enum:
                - full_coverage
                - limited_coverage
                - no_coverage
                - skipped
            - type: 'null'
          title: Status
          description: >-
            Coverage quality of this enrichment block. `full_coverage` means the
            research passed the reliability threshold and a clean result can be
            trusted as a real signal. `limited_coverage` means some evidence was
            found but below the reliability threshold — treat absent findings as
            unknown, not negative. `no_coverage` means research could not gather
            enough evidence to make a call. `skipped` means the account did not
            meet the minimum bar for this enrichment to return useful results —
            see `skip_reason` for details.
        skip_reason:
          anyOf:
            - $ref: '#/components/schemas/EnrichmentSkipReason'
            - type: 'null'
          description: >-
            Present only when `status` is `skipped`. Explains why this
            enrichment was not attempted.
        summary:
          anyOf:
            - type: string
            - type: 'null'
          title: Summary
          description: Short 2-3 sentence summary of the creator's background and focus.
          examples:
            - >-
              MrBeast is a YouTube creator known for expensive stunts and
              philanthropy.
            - >-
              Marques Brownlee is a tech reviewer focused on consumer
              electronics.
      type: object
      title: CreatorBio
      description: Biographical summary of a creator.
    CreatorPlatform:
      properties:
        platform:
          type: string
          title: Platform
          description: Platform identifier (e.g., youtube, x).
        handle:
          type: string
          title: Handle
          description: Canonical handle with required prefix.
        url:
          type: string
          minLength: 1
          format: uri
          title: Url
          description: Primary profile URL for the platform.
        platform_id:
          anyOf:
            - type: string
            - type: 'null'
          title: Platform Id
          description: Native platform identifier (e.g., YouTube channel ID, Instagram pk).
          examples:
            - UCBcRF18a7Qf58cCRy5xuWwQ
            - '1234567890'
        display_name:
          anyOf:
            - type: string
            - type: 'null'
          title: Display Name
          description: The creator's display name or channel title.
          examples:
            - MrBeast
            - Lex Fridman
            - Colin and Samir
        channel_relationship:
          anyOf:
            - type: string
              enum:
                - attached
                - group
            - type: 'null'
          title: Channel Relationship
          description: >-
            Only present for non-primary channels. Omitted for channels the
            creator directly owns. 'attached' = a distinct show, brand, project,
            or publication surface closely associated with the creator (e.g.
            @Denki for Austin Evans). 'group' = a shared, joint, or collab
            surface the creator is part of (e.g. @samandcolby for Sam Golbach).
          examples:
            - attached
            - group
        profile_pic_url:
          anyOf:
            - type: string
            - type: 'null'
          title: Profile Pic Url
          description: >-
            Short-lived URL for the channel's profile picture. Fetch a new
            creator result after the URL expires; previously downloaded image
            bytes may be cached by the client.
          examples:
            - https://d111111abcdef8.cloudfront.net/creator-avatars/v1/...
        subscriber_count:
          anyOf:
            - type: integer
            - type: 'null'
          title: Subscriber Count
          description: >-
            Subscriber/follower count for sorting and calculations. Only present
            for platforms that support subscriber counts.
          examples:
            - 4227
            - 133017
            - 1500000
            - 51389232
        subscriber_count_text:
          anyOf:
            - type: string
            - type: 'null'
          title: Subscriber Count Text
          description: >-
            Subscriber/follower count formatted for display. Only present for
            platforms that support subscriber counts.
          examples:
            - 4.2K
            - 133K
            - 1.5M
            - 51M
        follower_bucket:
          anyOf:
            - $ref: '#/components/schemas/FollowerBucket'
            - type: 'null'
          description: >-
            Advertiser-facing follower bucket derived from subscriber_count.
            Only present for platforms that support subscriber counts.
        engagement_metrics:
          anyOf:
            - $ref: '#/components/schemas/EngagementMetrics'
            - type: 'null'
          description: >-
            Engagement metrics from the most recent videos/posts. Includes
            average views, likes, comments, and engagement rate.
        video_metrics:
          anyOf:
            - $ref: '#/components/schemas/VideoMetrics'
            - type: 'null'
          description: >-
            Video-specific metrics for ad inventory estimation. Includes average
            duration, upload frequency, and optional lookback coverage metadata.
            Only present when include=video_metrics is specified.
        relative_metrics:
          anyOf:
            - $ref: '#/components/schemas/RelativeMetrics'
            - type: 'null'
          description: >-
            Public benchmark summaries relative to similar creators. Only
            present when include=relative_metrics is specified and benchmark
            data is available.
      type: object
      required:
        - platform
        - handle
        - url
      title: CreatorPlatform
      description: Primary social profile discovered for a creator.
    CreatorAssociatedCreator:
      properties:
        creator_id:
          type: string
          title: Creator Id
          description: Upriver creator ID for the associated creator cluster.
          examples:
            - cb4f53f0-c905-4c0a-86df-9a6c7551c408
        creator_role:
          type: string
          enum:
            - surface
            - primary_creator
            - group
            - member
            - peer
          title: Creator Role
          description: >-
            Role of the associated creator cluster relative to the current
            creator. 'surface' = a distinct project, brand, or publication
            surface associated with this creator. 'primary_creator' = the main
            creator this cluster is a surface for. 'group' = a shared or collab
            cluster this creator is part of. 'member' = an individual creator
            who is part of this cluster. 'peer' = a co-equal shared-owner
            creator cluster.
          examples:
            - surface
            - primary_creator
            - group
            - member
            - peer
      type: object
      required:
        - creator_id
        - creator_role
      title: CreatorAssociatedCreator
      description: Reference to a related but separate creator cluster.
    CreatorLabel:
      properties:
        id:
          type: string
          title: Id
          description: Stable identifier. For categories, matches /media_categories IDs.
          examples:
            - beauty
            - skincare
            - clean-beauty-expert
        name:
          type: string
          title: Name
          description: Human-readable display name.
          examples:
            - Beauty
            - Skincare
            - Clean Beauty Expert
        type:
          type: string
          enum:
            - category
            - tag
          title: Type
          description: >-
            Label type: 'category' = stable taxonomy (filterable), 'tag' =
            dynamic descriptor.
        level:
          anyOf:
            - type: integer
            - type: 'null'
          title: Level
          description: >-
            Hierarchy level for categories: 1 = broad, 2 = specific. Null for
            tags.
          examples:
            - 1
            - 2
        parent_id:
          anyOf:
            - type: string
            - type: 'null'
          title: Parent Id
          description: Parent category ID for level-2 categories. Null for L1 and tags.
          examples:
            - beauty
      type: object
      required:
        - id
        - name
        - type
      title: CreatorLabel
      description: >-
        Descriptive label for a creator (category or tag).


        Labels come in two types:

        - `category`: Stable classifications from the taxonomy (see
        /media_categories).
          Use these for filtering. Categories have `level` (1=broad, 2=specific) and
          L2 categories include `parent_id` linking to their parent L1.
        - `tag`: Dynamic descriptors extracted for this creator. More specific
        but
          may vary over time.
    CreatorSkippedEnrichments:
      properties:
        fields:
          items:
            type: string
            enum:
              - bio
              - audience
              - brand_safety
          type: array
          title: Fields
          description: >-
            Requested enrichment fields that were omitted because enrichment was
            deterministically skipped.
        reason:
          $ref: '#/components/schemas/EnrichmentSkipReason'
          description: Structured reason those enrichment fields were skipped.
      type: object
      required:
        - fields
        - reason
      title: CreatorSkippedEnrichments
      description: Compact metadata for omitted enrichment blocks.
    CreatorTag:
      properties:
        id:
          type: string
          title: Id
          description: Stable tag ID (taxonomy slug)
        name:
          type: string
          title: Name
          description: Human-readable display name for the tag
      type: object
      required:
        - id
        - name
      title: CreatorTag
      description: |-
        User-facing tag object for creator search results.

        Deprecated: Use CreatorLabel instead for richer metadata.
    CreatorAudience:
      properties:
        status:
          anyOf:
            - type: string
              enum:
                - full_coverage
                - limited_coverage
                - no_coverage
                - skipped
            - type: 'null'
          title: Status
          description: >-
            Coverage quality of this enrichment block. `full_coverage` means the
            research passed the reliability threshold and a clean result can be
            trusted as a real signal. `limited_coverage` means some evidence was
            found but below the reliability threshold — treat absent findings as
            unknown, not negative. `no_coverage` means research could not gather
            enough evidence to make a call. `skipped` means the account did not
            meet the minimum bar for this enrichment to return useful results —
            see `skip_reason` for details.
        skip_reason:
          anyOf:
            - $ref: '#/components/schemas/EnrichmentSkipReason'
            - type: 'null'
          description: >-
            Present only when `status` is `skipped`. Explains why this
            enrichment was not attempted.
        description:
          anyOf:
            - type: string
            - type: 'null'
          title: Description
          description: Natural language description of the typical audience.
          examples:
            - Young female audience interested in comedy and lifestyle content.
            - Tech-savvy males aged 25-44 interested in gadgets and gaming.
        gender:
          anyOf:
            - $ref: '#/components/schemas/AudienceGender'
            - type: 'null'
          description: Gender distribution with confidence level.
        age:
          anyOf:
            - $ref: '#/components/schemas/AudienceAge'
            - type: 'null'
          description: Age distribution with optional segment breakdown.
        geography:
          anyOf:
            - $ref: '#/components/schemas/AudienceGeography'
            - type: 'null'
          description: Geographic distribution with optional country breakdown.
        languages:
          anyOf:
            - $ref: '#/components/schemas/AudienceLanguages'
            - type: 'null'
          description: Language distribution with optional language breakdown.
      type: object
      title: CreatorAudience
      description: >-
        Audience demographic information for a creator.


        All fields are **directional signals** — they indicate where the creator

        has significant audience presence, not exact analytics. Use these to
        answer

        "does this creator reach X demographic?" rather than "what is the exact

        breakdown?" Check the `confidence` field on each sub-object to gauge

        reliability.


        Demographic breakdowns (age segments, country percentages, language

        breakdown) are only included when explicit percentage data is available
        from

        analytics or research sources. When data is inferred without specific

        percentages, only primary directional fields and `confidence` are
        returned.


        Age contract:

        - `age.min_age` / `age.max_age`: directional envelope from all available
          evidence.
        - `age.segments`: explicit percentage buckets only.

        - These can coexist when percentages are partial; segments do not need
        to
          cover the full envelope or sum to 100.

        **With explicit analytics data** (high confidence):

        ```json

        {
          "description": "Young female audience interested in comedy and lifestyle.",
          "gender": {"value": "female", "percentage": 72, "confidence": "high"},
          "age": {
            "min_age": 18, "max_age": 24,
            "segments": [
              {"min_age": 18, "max_age": 24, "percentage": 45},
              {"min_age": 25, "max_age": 34, "percentage": 30}
            ],
            "confidence": "high"
          },
          "geography": {
            "countries": [
              {"country": "US", "percentage": 65},
              {"country": "GB", "percentage": 15}
            ],
            "international": true,
            "confidence": "high"
          },
          "languages": {
            "value": "English",
            "breakdown": [
              {"language": "English", "percentage": 85},
              {"language": "Spanish", "percentage": 10}
            ],
            "confidence": "high"
          }
        }

        ```


        **Without explicit data** (inferred, medium/low confidence):

        ```json

        {
          "description": "Young female audience interested in comedy and lifestyle.",
          "gender": {"value": "female", "confidence": "medium"},
          "age": {"min_age": 18, "max_age": 24, "confidence": "medium"},
          "geography": {"countries": [{"country": "US"}], "confidence": "medium"},
          "languages": {"value": "English", "confidence": "high"}
        }

        ```
    EnrichmentSkipReason:
      properties:
        code:
          type: string
          const: below_minimum_subscribers
          title: Code
          description: >-
            Machine-readable reason code. `below_minimum_subscribers` means the
            account's follower count is below the minimum where this enrichment
            reliably returns useful results.
        minimum_subscribers:
          type: integer
          title: Minimum Subscribers
          description: The minimum subscriber count required to attempt this enrichment.
        platform:
          type: string
          title: Platform
          description: Platform this threshold was evaluated against.
      type: object
      required:
        - code
        - minimum_subscribers
        - platform
      title: EnrichmentSkipReason
      description: Structured reason why an enrichment block was deterministically skipped.
    FollowerBucket:
      properties:
        id:
          type: string
          title: Id
          description: Stable follower bucket identifier.
          examples:
            - 10k_50k
            - 100k_300k
            - over_1m
        display:
          type: string
          title: Display
          description: Human-readable label for the follower bucket.
          examples:
            - 10K-50K followers
            - 100K-300K followers
            - 1M+ followers
        min_followers:
          type: integer
          minimum: 0
          title: Min Followers
          description: Inclusive lower bound for the bucket.
          examples:
            - 10000
            - 100000
            - 1000000
        max_followers:
          anyOf:
            - type: integer
              minimum: 0
            - type: 'null'
          title: Max Followers
          description: Inclusive upper bound for the bucket, if finite.
          examples:
            - 49999
            - 299999
            - 999999
      type: object
      required:
        - id
        - display
        - min_followers
      title: FollowerBucket
      description: Advertiser-facing follower bucket for a channel.
    EngagementMetrics:
      properties:
        avg_views:
          anyOf:
            - type: integer
            - type: 'null'
          title: Avg Views
          description: >-
            Average view count from recent content. On platforms with multiple
            upload formats, this blends across the supported formats.
          examples:
            - 125000
            - 500000
            - 2000000
        avg_likes:
          anyOf:
            - type: integer
            - type: 'null'
          title: Avg Likes
          description: >-
            Average like count from recent content. On platforms with multiple
            upload formats, this blends across the supported formats.
          examples:
            - 5000
            - 25000
            - 100000
        avg_comments:
          anyOf:
            - type: integer
            - type: 'null'
          title: Avg Comments
          description: >-
            Average comment count from recent content. On platforms with
            multiple upload formats, this blends across the supported formats.
          examples:
            - 500
            - 2500
            - 10000
        avg_engagement_rate:
          anyOf:
            - type: number
            - type: 'null'
          title: Avg Engagement Rate
          description: >-
            Average engagement rate calculated as (likes + comments) / views.
            Expressed as a decimal (e.g., 0.05 = 5%).
          examples:
            - 0.05
            - 0.1
            - 0.15
      type: object
      title: EngagementMetrics
      description: Engagement metrics from recent videos/posts.
    VideoMetrics:
      properties:
        avg_duration_seconds:
          anyOf:
            - type: integer
            - type: 'null'
          title: Avg Duration Seconds
          description: >-
            Average video duration in seconds from uploads inside the trailing
            12-week long-form inventory window. Omitted from creator responses
            when no uploads fall inside the window.
          examples:
            - 600
            - 120
            - 45
        uploads_per_week:
          anyOf:
            - type: number
            - type: 'null'
          title: Uploads Per Week
          description: >-
            Average number of uploads per week over the trailing 12-week
            inventory window for long-form uploads. When the creator has less
            history than the full lookback, the rate is calculated over the
            observed weeks and accompanied by coverage metadata.
          examples:
            - 1.5
            - 3
            - 7
        pct_over_8m:
          anyOf:
            - type: number
            - type: 'null'
          title: Pct Over 8M
          description: >-
            Percentage of in-window videos with duration over 8 minutes (480
            seconds). Videos over 8 minutes are eligible for mid-roll ads. Based
            on long-form uploads only. Omitted from creator responses when no
            uploads fall inside the window.
          examples:
            - 75
            - 100
            - 0
        lookback_weeks:
          anyOf:
            - type: integer
            - type: 'null'
          title: Lookback Weeks
          description: >-
            Trailing lookback window used for advertiser inventory estimation.
            Currently fixed at 12 weeks in the public creator API.
          examples:
            - 12
        weeks_observed:
          anyOf:
            - type: integer
            - type: 'null'
          title: Weeks Observed
          description: >-
            Number of weeks of upload history actually observed for the
            inventory calculation. Can be less than lookback_weeks for newer
            creators.
          examples:
            - 2
            - 12
        window_complete:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Window Complete
          description: >-
            True when a full lookback window was observed. False when the
            creator has less than the full lookback of upload history.
          examples:
            - true
            - false
      type: object
      title: VideoMetrics
      description: >-
        Video-specific metrics for ad inventory estimation.


        Computed from the creator's trailing 12-week long-form upload window.
        Includes

        average duration (useful for estimating mid-roll ad slots), upload

        frequency, and coverage metadata describing how much recent history

        was actually observed.
      examples:
        - avg_duration_seconds: 615
          lookback_weeks: 12
          pct_over_8m: 66.7
          uploads_per_week: 1.75
          weeks_observed: 12
          window_complete: true
        - lookback_weeks: 12
          uploads_per_week: 0
          weeks_observed: 12
          window_complete: true
        - avg_duration_seconds: 420
          lookback_weeks: 12
          pct_over_8m: 25
          uploads_per_week: 2.5
          weeks_observed: 2
          window_complete: false
    RelativeMetrics:
      properties:
        engagement:
          anyOf:
            - $ref: '#/components/schemas/RelativeEngagementMetrics'
            - type: 'null'
          description: >-
            Relative benchmark output for engagement metrics. Only present when
            benchmarks were available for the channel and engagement metrics.
      type: object
      title: RelativeMetrics
      description: Public benchmark summaries relative to similar creators.
    AudienceGender:
      properties:
        value:
          anyOf:
            - type: string
              enum:
                - male
                - female
                - balanced
            - type: 'null'
          title: Value
          description: 'Gender skew: male, female, balanced (45-55%), or null.'
          examples:
            - female
            - male
            - balanced
        percentage:
          anyOf:
            - type: integer
            - type: 'null'
          title: Percentage
          description: >-
            Percentage of primary gender (0-100). Only present when explicit
            analytics data is available.
          examples:
            - 72
            - 65
            - 55
        confidence:
          type: string
          enum:
            - low
            - medium
            - high
          title: Confidence
          description: Confidence level based on data source quality.
          default: medium
      type: object
      title: AudienceGender
      description: >-
        Gender distribution with confidence.


        The `percentage` field is only included when explicit numerical data
        exists.

        When gender skew is inferred without specific percentages (e.g.,
        "female-leaning"),

        only `value` and `confidence` are returned.


        Values:
          - "male"/"female": audience skews this direction
          - "balanced": roughly even split (45-55%), backed by evidence
          - null: unknown / insufficient data

        Example with explicit data:
            {"value": "female", "percentage": 72, "confidence": "high"}

        Example without explicit data:
            {"value": "female", "confidence": "medium"}
    AudienceAge:
      properties:
        min_age:
          anyOf:
            - type: integer
            - type: 'null'
          title: Min Age
          description: >-
            Primary directional envelope lower bound (inclusive), null if
            unbounded. May be broader than quantified segments.
          examples:
            - 13
            - 18
            - 25
        max_age:
          anyOf:
            - type: integer
            - type: 'null'
          title: Max Age
          description: >-
            Primary directional envelope upper bound (inclusive), null if
            unbounded. May be broader than quantified segments.
          examples:
            - 24
            - 34
            - 44
        segments:
          anyOf:
            - items:
                $ref: '#/components/schemas/AudienceAgeSegment'
              type: array
            - type: 'null'
          title: Segments
          description: >-
            Explicit percentage breakdown by age range. May be partial and not
            exhaustive.
        confidence:
          type: string
          enum:
            - low
            - medium
            - high
          title: Confidence
          description: Confidence level based on data source quality.
          default: medium
      type: object
      title: AudienceAge
      description: >-
        Age distribution with confidence.


        The `min_age`/`max_age` range is a directional envelope where the
        creator

        has meaningful audience concentration. It is not an exact analytics

        breakdown.


        The `segments` field contains only explicit percentage buckets from
        grounded

        data. Segments may be partial: they do not need to cover the full

        `min_age`/`max_age` envelope and do not need to sum to 100.


        When both are present:

        - `min_age`/`max_age` gives broad directional context

        - `segments` gives the quantified subset with explicit percentages


        When only one data type is available, the other may be omitted.


        Example with explicit data:
            {
              "min_age": 18, "max_age": 24,
              "segments": [
                {"min_age": 18, "max_age": 24, "percentage": 45},
                {"min_age": 25, "max_age": 34, "percentage": 30}
              ],
              "confidence": "high"
            }

        Example without explicit data:
            {"min_age": 18, "max_age": 24, "confidence": "medium"}

        Example with partial segments:
            {
              "min_age": 18, "max_age": 34,
              "segments": [
                {"min_age": 24, "max_age": 29, "percentage": 40},
                {"min_age": 30, "max_age": 34, "percentage": 30}
              ],
              "confidence": "medium"
            }

        Example unbounded:
            {"min_age": 55, "confidence": "medium"}  (55+)
    AudienceGeography:
      properties:
        countries:
          anyOf:
            - items:
                $ref: '#/components/schemas/AudienceCountrySegment'
              type: array
            - type: 'null'
          title: Countries
          description: >-
            Countries where the creator has significant audience presence, as
            ISO codes. Order is approximate, not a strict ranking. This list may
            not be exhaustive — absence of a country does not mean the creator
            has no audience there. Percentage is included only when grounded
            data is available.
        international:
          anyOf:
            - type: boolean
            - type: 'null'
          title: International
          description: >-
            True if meaningful audience outside primary country, false if
            concentrated in one country, null if unknown.
        confidence:
          type: string
          enum:
            - low
            - medium
            - high
          title: Confidence
          description: Confidence level based on data source quality.
          default: medium
      type: object
      title: AudienceGeography
      description: |-
        Geographic distribution with confidence.

        The `countries` field lists countries where the creator has significant
        audience presence — NOT necessarily ranked by dominance. Ordering is
        approximate and should not be treated as a strict ranking. This list
        may not be exhaustive; absence of a country does not mean the creator
        has no audience there. Use this to answer "does this creator reach
        audiences in X?" rather than "what is their #1 country?"

        Percentage is included only when grounded analytics data exists.

        Example with percentages:
            {
              "countries": [
                {"country": "US", "percentage": 65},
                {"country": "GB", "percentage": 15}
              ],
              "international": true,
              "confidence": "high"
            }

        Example without percentages (countries still listed):
            {
              "countries": [{"country": "US"}, {"country": "GB"}],
              "international": true,
              "confidence": "medium"
            }
    AudienceLanguages:
      properties:
        value:
          type: string
          title: Value
          description: Primary language.
          examples:
            - English
            - Spanish
            - Portuguese
        breakdown:
          anyOf:
            - items:
                $ref: '#/components/schemas/AudienceLanguageSegment'
              type: array
            - type: 'null'
          title: Breakdown
          description: >-
            Breakdown by language with percentages. Only present when explicit
            analytics data is available.
        confidence:
          type: string
          enum:
            - low
            - medium
            - high
          title: Confidence
          description: Confidence level based on data source quality.
          default: medium
      type: object
      required:
        - value
      title: AudienceLanguages
      description: >-
        Language distribution with confidence.


        The `breakdown` field is only included when explicit percentage data
        exists.

        When language is inferred without specific breakdowns, only `value` and

        `confidence` are returned.


        Example with explicit data:
            {
              "value": "English",
              "breakdown": [
                {"language": "English", "percentage": 85},
                {"language": "Spanish", "percentage": 10}
              ],
              "confidence": "high"
            }

        Example without explicit data:
            {"value": "English", "confidence": "high"}
    RelativeEngagementMetrics:
      properties:
        benchmark_basis:
          $ref: '#/components/schemas/RelativeMetricBenchmarkBasis'
          description: Public explanation of the cohort used for engagement metrics.
        avg_views:
          anyOf:
            - $ref: '#/components/schemas/RelativeMetricSignal'
            - type: 'null'
          description: Relative benchmark for average views.
        avg_engagement_rate:
          anyOf:
            - $ref: '#/components/schemas/RelativeMetricSignal'
            - type: 'null'
          description: Relative benchmark for average engagement rate.
      type: object
      required:
        - benchmark_basis
      title: RelativeEngagementMetrics
      description: Relative benchmark output for engagement metrics.
    AudienceAgeSegment:
      properties:
        min_age:
          anyOf:
            - type: integer
            - type: 'null'
          title: Min Age
          description: Lower bound (inclusive), null if unbounded below.
          examples:
            - 13
            - 18
            - 25
            - 35
            - 45
            - 55
        max_age:
          anyOf:
            - type: integer
            - type: 'null'
          title: Max Age
          description: Upper bound (inclusive), null if unbounded above.
          examples:
            - 17
            - 24
            - 34
            - 44
            - 54
        percentage:
          type: integer
          maximum: 100
          minimum: 0
          title: Percentage
          description: Percentage of audience in this age range.
          examples:
            - 45
            - 30
            - 15
      type: object
      required:
        - percentage
      title: AudienceAgeSegment
      description: Age segment with percentage breakdown.
    AudienceCountrySegment:
      properties:
        country:
          type: string
          title: Country
          description: ISO 3166-1 alpha-2 country code.
          examples:
            - US
            - GB
            - CA
            - BR
        country_name:
          anyOf:
            - type: string
            - type: 'null'
          title: Country Name
          description: Human-readable country name derived from ISO code.
          examples:
            - United States
            - United Kingdom
        percentage:
          anyOf:
            - type: integer
              maximum: 100
              minimum: 0
            - type: 'null'
          title: Percentage
          description: Percentage of audience in this country, if known.
          examples:
            - 65
            - 15
            - 10
      type: object
      required:
        - country
      title: AudienceCountrySegment
      description: Country segment with optional percentage breakdown.
    AudienceLanguageSegment:
      properties:
        language:
          type: string
          title: Language
          description: Language name.
          examples:
            - English
            - Spanish
            - Portuguese
        percentage:
          type: integer
          maximum: 100
          minimum: 0
          title: Percentage
          description: Percentage of audience using this language.
          examples:
            - 85
            - 10
            - 5
      type: object
      required:
        - language
        - percentage
      title: AudienceLanguageSegment
      description: Language segment with percentage breakdown.
    RelativeMetricBenchmarkBasis:
      properties:
        platform:
          type: string
          title: Platform
          description: Platform used for the benchmark cohort.
          examples:
            - youtube
            - instagram
        follower_bucket_id:
          type: string
          title: Follower Bucket Id
          description: Follower bucket identifier used for the benchmark cohort.
          examples:
            - 50k_100k
            - 100k_300k
        specificity:
          type: string
          enum:
            - follower_bucket
            - follower_bucket_content_category
          title: Specificity
          description: How specific the benchmark cohort was.
        benchmark_date:
          type: string
          title: Benchmark Date
          description: Date the benchmark snapshot was computed.
          examples:
            - '2026-03-17'
        content_category:
          anyOf:
            - $ref: '#/components/schemas/RelativeMetricContentCategory'
            - type: 'null'
          description: >-
            Content category used for the benchmark cohort when a
            category-specific comparison was available.
      type: object
      required:
        - platform
        - follower_bucket_id
        - specificity
        - benchmark_date
      title: RelativeMetricBenchmarkBasis
      description: Public explanation of which peer cohort powered a benchmark.
    RelativeMetricSignal:
      properties:
        band:
          type: string
          enum:
            - bottom_25
            - mid_50
            - top_25
          title: Band
          description: Coarse benchmark band relative to similar creators.
      type: object
      required:
        - band
      title: RelativeMetricSignal
      description: Public-facing benchmark summary for a single metric.
    RelativeMetricContentCategory:
      properties:
        id:
          type: string
          title: Id
          description: Category identifier from the creator taxonomy.
          examples:
            - sports
            - nfl
            - beauty
        name:
          type: string
          title: Name
          description: Human-readable category name.
          examples:
            - Sports
            - NFL
            - Beauty
      type: object
      required:
        - id
        - name
      title: RelativeMetricContentCategory
      description: Content category actually used in a public benchmark basis.
  securitySchemes:
    APIKeyHeader:
      type: apiKey
      in: header
      name: X-API-Key

````