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

# Create Turn

> Run one conversation turn. Omit `conversation_id` to create the thread with this turn; pass it to continue an existing thread.

See [Run a turn](/conversations/run-a-turn) and [Streaming events](/conversations/streaming-events).


## OpenAPI

````yaml post /v1/conversations
openapi: 3.1.0
info:
  title: FastAPI
  version: 0.1.0
servers:
  - url: https://api.trychannel3.com
    description: Production
security: []
paths:
  /v1/conversations:
    post:
      tags:
        - v1
      summary: Create Turn
      description: >-
        Run one conversation turn. Omit `conversation_id` to create the thread
        with this turn; pass it to continue an existing thread.
      operationId: create_turn_v1_conversations_post
      parameters:
        - name: x-user-id
          in: header
          required: false
          schema:
            anyOf:
              - type: string
              - type: 'null'
            description: >-
              Optional user identifier to attribute clicks and sales to a user
              in your system. Channel3 appends it to buy URLs in the response.
            title: X-User-Id
          description: >-
            Optional user identifier to attribute clicks and sales to a user in
            your system. Channel3 appends it to buy URLs in the response.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateTurnRequest'
      responses:
        '200':
          description: >-
            `text/event-stream` of `TurnEvent` objects (one `data:` JSON frame
            each), terminated by `data: [DONE]`. With `stream: false`, a
            buffered `TurnResult` JSON body instead.
          content:
            text/event-stream:
              schema:
                $ref: '#/components/schemas/TurnEvent'
            application/json:
              schema:
                $ref: '#/components/schemas/TurnResult'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ConversationErrorBody'
        '402':
          description: Payment required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ConversationErrorBody'
        '404':
          description: Conversation not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ConversationErrorBody'
        '409':
          description: Turn already in progress
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ConversationErrorBody'
        '422':
          description: Request validation failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ConversationErrorBody'
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ConversationErrorBody'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ConversationErrorBody'
        '503':
          description: All model providers unavailable; retryable
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ConversationErrorBody'
      security:
        - APIKeyHeader: []
        - Bearer: []
      x-codeSamples:
        - lang: JavaScript
          source: >-
            import Channel3 from '@channel3/sdk';


            const client = new Channel3({
              apiKey: process.env['CHANNEL3_API_KEY'], // This is the default and can be omitted
            });


            const turnResult = await client.conversations.create({ message: {}
            });


            console.log(turnResult.conversation_id);
        - lang: Python
          source: |-
            import os
            from channel3_sdk import Channel3

            client = Channel3(
                api_key=os.environ.get("CHANNEL3_API_KEY"),  # This is the default and can be omitted
            )
            turn_result = client.conversations.create(
                message={},
            )
            print(turn_result.conversation_id)
        - lang: Go
          source: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/channel3-ai/sdk-go\"\n\t\"github.com/channel3-ai/sdk-go/option\"\n)\n\nfunc main() {\n\tclient := channel3go.NewClient(\n\t\toption.WithAPIKey(\"My API Key\"),\n\t)\n\tturnResult, err := client.Conversations.New(context.TODO(), channel3go.ConversationNewParams{\n\t\tCreateTurnRequest: channel3go.CreateTurnRequestParam{\n\t\t\tMessage: channel3go.UserMessageParam{},\n\t\t},\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", turnResult.ConversationID)\n}\n"
        - lang: CLI
          source: |-
            channel3 conversations create \
              --api-key 'My API Key' \
              --message '{}'
components:
  schemas:
    CreateTurnRequest:
      properties:
        message:
          $ref: '#/components/schemas/UserMessage'
        conversation_id:
          anyOf:
            - type: string
            - type: 'null'
          title: Conversation Id
          description: >-
            Existing thread to continue. When omitted, a new thread is created
            and its id returned.
        filters:
          anyOf:
            - $ref: '#/components/schemas/SearchFilters'
            - type: 'null'
          description: Pinned catalog filters applied to every product search in this turn.
        config:
          $ref: '#/components/schemas/SearchConfig'
          description: Optional search configuration, including `collection_id`.
          default: {}
        context:
          anyOf:
            - $ref: '#/components/schemas/ConversationContext'
            - type: 'null'
        stream:
          type: boolean
          title: Stream
          description: >-
            Stream turn events over SSE (default) or return the assembled turn
            as JSON.
          default: true
      type: object
      required:
        - message
      title: CreateTurnRequest
      description: Run one turn. Without ``conversation_id`` a new thread is created first.
    TurnEvent:
      discriminator:
        mapping:
          error:
            $ref: '#/components/schemas/TurnErrorEvent'
          part.completed:
            $ref: '#/components/schemas/PartCompletedEvent'
          part.delta:
            $ref: '#/components/schemas/PartDeltaEvent'
          part.started:
            $ref: '#/components/schemas/PartStartedEvent'
          turn.completed:
            $ref: '#/components/schemas/TurnCompletedEvent'
          turn.started:
            $ref: '#/components/schemas/TurnStartedEvent'
        propertyName: type
      oneOf:
        - $ref: '#/components/schemas/TurnStartedEvent'
        - $ref: '#/components/schemas/PartStartedEvent'
        - $ref: '#/components/schemas/PartDeltaEvent'
        - $ref: '#/components/schemas/PartCompletedEvent'
        - $ref: '#/components/schemas/TurnCompletedEvent'
        - $ref: '#/components/schemas/TurnErrorEvent'
    TurnResult:
      properties:
        conversation_id:
          type: string
          title: Conversation Id
        turn_id:
          type: string
          title: Turn Id
        usage:
          $ref: '#/components/schemas/TurnUsage'
        message:
          $ref: '#/components/schemas/AssistantMessage'
      type: object
      required:
        - conversation_id
        - turn_id
        - usage
        - message
      title: TurnResult
      description: 'Buffered equivalent of a streamed turn (``stream: false``).'
    ConversationErrorBody:
      properties:
        error:
          $ref: '#/components/schemas/ConversationError'
      type: object
      required:
        - error
      title: ConversationErrorBody
      description: Error envelope for all non-2xx ``/v1/conversations`` responses.
    UserMessage:
      properties:
        role:
          type: string
          const: user
          title: Role
          default: user
        parts:
          items:
            oneOf:
              - $ref: '#/components/schemas/TextPart'
              - $ref: '#/components/schemas/ImagePart'
            discriminator:
              propertyName: type
              mapping:
                image:
                  $ref: '#/components/schemas/ImagePart'
                text:
                  $ref: '#/components/schemas/TextPart'
          type: array
          title: Parts
      type: object
      title: UserMessage
    SearchFilters:
      properties:
        brand_ids:
          anyOf:
            - items:
                type: string
              type: array
            - type: 'null'
          title: Brand Ids
          description: If provided, only products from these brands will be returned
        gender:
          anyOf:
            - $ref: '#/components/schemas/Gender'
            - type: 'null'
        conditions:
          items:
            $ref: '#/components/schemas/Condition'
          type: array
          minItems: 1
          title: Conditions
          description: >-
            Offer conditions to match (OR). Defaults to ['new'], which also
            matches offers whose condition is unknown. Pass every value to
            disable condition filtering.
        age:
          anyOf:
            - items:
                $ref: '#/components/schemas/Age'
              type: array
            - type: 'null'
          title: Age
          description: >-
            Filter by age group. Age-agnostic products are treated as adult
            products.
        price:
          anyOf:
            - $ref: '#/components/schemas/SearchFilterPrice'
            - type: 'null'
          description: If provided, only products within this price range will be returned
        availability:
          items:
            $ref: '#/components/schemas/OfferAvailabilityStatus'
          type: array
          minItems: 1
          title: Availability
          description: >-
            Offer availability statuses to match (OR). Defaults to ['InStock'].
            An offer with no availability data counts as 'InStock'. Pass every
            value to disable availability filtering.
        sale:
          anyOf:
            - $ref: '#/components/schemas/Sale'
            - type: 'null'
          description: >-
            If 'on_sale', only products with at least one on-sale offer (priced
            below its compare-at price) for the requested locale are returned.
            If omitted, no filter.
        website_ids:
          anyOf:
            - items:
                type: string
              type: array
            - type: 'null'
          title: Website Ids
          description: >-
            If provided, only products from these websites will be returned.
            Accepts website IDs or domains (e.g. "nike.com").
        category_ids:
          anyOf:
            - items:
                type: string
              type: array
            - type: 'null'
          title: Category Ids
          description: >-
            If provided, only products from these categories will be returned.
            Accepts category slugs.
        exclude_brand_ids:
          anyOf:
            - items:
                type: string
              type: array
            - type: 'null'
          title: Exclude Brand Ids
          description: >-
            If provided, products from these brands will be excluded from the
            results
        exclude_website_ids:
          anyOf:
            - items:
                type: string
              type: array
            - type: 'null'
          title: Exclude Website Ids
          description: >-
            If provided, products from these websites will be excluded from the
            results. Accepts website IDs or domains (e.g. "nike.com").
        exclude_category_ids:
          anyOf:
            - items:
                type: string
              type: array
            - type: 'null'
          title: Exclude Category Ids
          description: >-
            If provided, products in these categories (or their descendants)
            will be excluded from the results. Accepts category slugs.
        colors:
          anyOf:
            - $ref: '#/components/schemas/SearchColorsFilter'
            - type: 'null'
          description: >-
            [Beta: filter is experimental and may be changed] If provided, find
            products containing all of these colors.
        attributes:
          anyOf:
            - additionalProperties:
                items:
                  type: string
                type: array
              type: object
            - type: 'null'
          title: Attributes
          description: >-
            If provided, only products whose extracted attributes match these
            key/value constraints will be returned. Keys are attribute handles
            (e.g. 'color', 'material') and values are lists of allowed values
            (OR within a key, AND across keys). When a category filter is also
            supplied, all keys must be valid attributes of at least one of the
            requested categories. See `Category.attributes` for the valid
            keys/values per category.
        dimensions:
          anyOf:
            - $ref: '#/components/schemas/SearchFilterDimensions'
            - type: 'null'
          description: >-
            If provided, only products with at least one offer whose physical
            dimensions satisfy every given range will be returned. Offer
            dimensions in responses are converted to the units used here.
      additionalProperties: false
      type: object
      title: SearchFilters
      description: Search filters for the search API.
    SearchConfig:
      properties:
        language:
          anyOf:
            - $ref: '#/components/schemas/LanguageCode'
            - type: 'null'
          description: >-
            ISO 639-1 language code. When unset, inferred from ``country``
            (preferred) then ``currency``, defaulting to ``en``.
        country:
          anyOf:
            - $ref: '#/components/schemas/CountryCode'
            - type: 'null'
          description: >-
            ISO 3166-1 alpha-2 country code. May stay unset for pan-region
            storefronts (e.g. ``currency=EUR`` with no specific country).
        currency:
          anyOf:
            - $ref: '#/components/schemas/CurrencyCode'
            - type: 'null'
          description: >-
            ISO 4217 currency code. When unset, inferred from ``country`` (e.g.
            ``GB`` → ``GBP``), defaulting to ``USD``.
        length_unit:
          anyOf:
            - $ref: '#/components/schemas/LengthUnit'
            - type: 'null'
          description: >-
            Preferred unit for length dimensions (length/width/height) in
            responses. A request dimension filter's unit for the field takes
            precedence; when neither is set, the merchant's stated unit is
            returned.
        weight_unit:
          anyOf:
            - $ref: '#/components/schemas/WeightUnit'
            - type: 'null'
          description: >-
            Preferred unit for weight dimensions in responses. A request
            dimension filter's weight unit takes precedence; when neither is
            set, the merchant's stated unit is returned.
        collection_id:
          anyOf:
            - type: string
            - type: 'null'
          title: Collection Id
          description: >-
            Optional saved collection to scope this request. Clauses are ORed.
            Within a clause, brand/website/category lists are ORed inside each
            list and ANDed across lists. Request filters further narrow results
            but cannot widen the collection scope.
        mode:
          $ref: '#/components/schemas/SearchMode'
          description: >-
            Search strategy. `default` (recommended) combines lexical + semantic
            search and is right for most use cases. `keyword` is lexical only —
            use it for real-time, low-latency needs like ad targeting. `agentic`
            uses an LLM to plan multiple structured sub-searches for complex
            queries, with higher latency than the other modes.
          default: default
      additionalProperties: false
      type: object
      title: SearchConfig
      description: Search, locale, and optional collection scope for a text search request.
    ConversationContext:
      properties:
        user_context:
          anyOf:
            - type: string
            - type: 'null'
          title: User Context
          description: Who the conversation is with (profile, preferences, session facts).
        application_context:
          anyOf:
            - type: string
            - type: 'null'
          title: Application Context
          description: What platform or surface is hosting this conversation.
      type: object
      title: ConversationContext
      description: Partner-supplied context pinned to the top of a conversation thread.
    TurnErrorEvent:
      properties:
        type:
          const: error
          default: error
          title: Type
          type: string
        code:
          $ref: '#/components/schemas/TurnErrorCode'
        message:
          type: string
          title: Message
        retryable:
          default: false
          title: Retryable
          type: boolean
      required:
        - code
        - message
      title: TurnErrorEvent
      type: object
    PartCompletedEvent:
      description: Final state of the part at ``part_index``; replace any streamed state.
      properties:
        type:
          const: part.completed
          default: part.completed
          title: Type
          type: string
        part_index:
          title: Part Index
          type: integer
        part:
          discriminator:
            mapping:
              text:
                $ref: '#/components/schemas/TextPart'
              tool:
                $ref: '#/components/schemas/ToolPart'
            propertyName: type
          oneOf:
            - $ref: '#/components/schemas/TextPart'
            - $ref: '#/components/schemas/ToolPart'
          title: Part
      required:
        - part_index
        - part
      title: PartCompletedEvent
      type: object
    PartDeltaEvent:
      description: Append ``delta`` to the text of the part at ``part_index``.
      properties:
        type:
          const: part.delta
          default: part.delta
          title: Type
          type: string
        part_index:
          title: Part Index
          type: integer
        delta:
          title: Delta
          type: string
      required:
        - part_index
        - delta
      title: PartDeltaEvent
      type: object
    PartStartedEvent:
      description: A new part began at ``part_index``; ``part`` is its initial state.
      properties:
        type:
          const: part.started
          default: part.started
          title: Type
          type: string
        part_index:
          title: Part Index
          type: integer
        part:
          discriminator:
            mapping:
              text:
                $ref: '#/components/schemas/TextPart'
              tool:
                $ref: '#/components/schemas/ToolPart'
            propertyName: type
          oneOf:
            - $ref: '#/components/schemas/TextPart'
            - $ref: '#/components/schemas/ToolPart'
          title: Part
      required:
        - part_index
        - part
      title: PartStartedEvent
      type: object
    TurnCompletedEvent:
      description: Terminal event of a successful turn.
      properties:
        type:
          const: turn.completed
          default: turn.completed
          title: Type
          type: string
        message:
          $ref: '#/components/schemas/AssistantMessage'
        usage:
          $ref: '#/components/schemas/TurnUsage'
      required:
        - message
        - usage
      title: TurnCompletedEvent
      type: object
    TurnStartedEvent:
      description: First event of every turn; carries the ids clients need to correlate.
      properties:
        type:
          const: turn.started
          default: turn.started
          title: Type
          type: string
        conversation_id:
          type: string
          title: Conversation Id
        turn_id:
          type: string
          title: Turn Id
        message_id:
          title: Message Id
          type: string
      required:
        - conversation_id
        - turn_id
        - message_id
      title: TurnStartedEvent
      type: object
    TurnUsage:
      properties:
        credits_charged:
          type: integer
          title: Credits Charged
          description: API credits charged for this turn (turn fee plus catalog searches).
        searches_run:
          type: integer
          title: Searches Run
          description: Catalog searches executed during this turn.
      type: object
      required:
        - credits_charged
        - searches_run
      title: TurnUsage
    AssistantMessage:
      properties:
        role:
          type: string
          const: assistant
          title: Role
          default: assistant
        parts:
          items:
            oneOf:
              - $ref: '#/components/schemas/TextPart'
              - $ref: '#/components/schemas/ToolPart'
            discriminator:
              propertyName: type
              mapping:
                text:
                  $ref: '#/components/schemas/TextPart'
                tool:
                  $ref: '#/components/schemas/ToolPart'
          type: array
          title: Parts
        suggestions:
          items:
            type: string
          type: array
          title: Suggestions
          description: Tap-ready follow-up messages offered after this reply.
      type: object
      title: AssistantMessage
    ConversationError:
      properties:
        code:
          $ref: '#/components/schemas/TurnErrorCode'
        message:
          type: string
          title: Message
      type: object
      required:
        - code
        - message
      title: ConversationError
    TextPart:
      properties:
        type:
          type: string
          const: text
          title: Type
          default: text
        text:
          type: string
          title: Text
      type: object
      required:
        - text
      title: TextPart
    ImagePart:
      properties:
        type:
          type: string
          const: image
          title: Type
          default: image
        url:
          type: string
          title: Url
      type: object
      required:
        - url
      title: ImagePart
      description: An image by URL. ``data:`` URIs are uploaded and rewritten server-side.
    Gender:
      type: string
      enum:
        - male
        - female
      title: Gender
      description: >-
        Product gender. 'unisex' is deprecated: coerced to None on input, never
        emitted.
    Condition:
      type: string
      enum:
        - new
        - used
      title: Condition
      description: >-
        Offer condition. 'refurbished' is deprecated: rejected as a filter
        value,

        coerced to None on responses.
    Age:
      type: string
      enum:
        - newborn
        - infant
        - toddler
        - kids
        - adult
      title: Age
    SearchFilterPrice:
      properties:
        min_price:
          anyOf:
            - type: number
            - type: 'null'
          title: Min Price
          description: Minimum price, in dollars and cents
        max_price:
          anyOf:
            - type: number
            - type: 'null'
          title: Max Price
          description: Maximum price, in dollars and cents
      additionalProperties: false
      type: object
      title: SearchFilterPrice
      description: Price filter for search. Values are inclusive.
    OfferAvailabilityStatus:
      type: string
      enum:
        - InStock
        - OutOfStock
      title: OfferAvailabilityStatus
      description: |-
        The two availability values the public API emits on offers.

        Internal ``AvailabilityStatus`` values are collapsed to these via
        ``AvailabilityStatus.to_api()``.
    Sale:
      type: string
      enum:
        - on_sale
      title: Sale
    SearchColorsFilter:
      properties:
        palette:
          items:
            $ref: '#/components/schemas/SearchFilterColor'
          type: array
          title: Palette
          description: Colors required in matching products. Treated as an AND condition.
        match:
          $ref: '#/components/schemas/ColorMatch'
          description: 'How tightly colors must match: ''strict'', ''standard'', or ''loose''.'
          default: standard
      additionalProperties: false
      type: object
      required:
        - palette
      title: SearchColorsFilter
      description: >-
        [Beta] Color filter wrapper. Holds required colors and optional match
        mode.
    SearchFilterDimensions:
      properties:
        length:
          anyOf:
            - $ref: '#/components/schemas/SearchFilterLengthDimension'
            - type: 'null'
        width:
          anyOf:
            - $ref: '#/components/schemas/SearchFilterLengthDimension'
            - type: 'null'
        height:
          anyOf:
            - $ref: '#/components/schemas/SearchFilterLengthDimension'
            - type: 'null'
        weight:
          anyOf:
            - $ref: '#/components/schemas/SearchFilterWeightDimension'
            - type: 'null'
      additionalProperties: false
      type: object
      title: SearchFilterDimensions
      description: >-
        Physical-dimension range filters, matched against the same offer.


        Matching products have at least one offer satisfying every provided

        range (alongside any locale/price/availability filters). Values are

        compared with a small relative tolerance. An offer with no dimension
        data

        for a filtered field does not match; note that when a single merchant on
        a

        product reports a dimension it is shared across that product's offers,
        so a

        matching offer may not itself surface that dimension in the response.
    LanguageCode:
      type: string
      enum:
        - en
        - de
        - fr
        - it
        - es
        - nl
        - sv
        - fi
        - pt
        - cs
        - el
        - ro
      title: LanguageCode
      description: ISO 639-1 language code.
    CountryCode:
      type: string
      enum:
        - US
        - GB
        - EU
        - AU
        - CA
        - IE
        - DE
        - AT
        - FR
        - BE
        - IT
        - ES
        - NL
        - SE
        - FI
        - PT
        - CZ
        - GR
        - RO
      title: CountryCode
      description: ISO 3166-1 alpha-2 country code (plus the pan-region ``EU``).
    CurrencyCode:
      type: string
      enum:
        - USD
        - CAD
        - AUD
        - GBP
        - EUR
        - SEK
        - CZK
        - RON
      title: CurrencyCode
      description: ISO 4217 currency code.
    LengthUnit:
      type: string
      enum:
        - mm
        - cm
        - m
        - in
        - ft
      title: LengthUnit
    WeightUnit:
      type: string
      enum:
        - mg
        - g
        - kg
        - oz
        - lb
      title: WeightUnit
    SearchMode:
      type: string
      enum:
        - keyword
        - default
        - agentic
      title: SearchMode
      description: >-
        Search strategy.


        ``default`` (recommended) combines lexical and semantic search and is
        the

        right choice for most use cases. ``keyword`` runs lexical search only —
        use

        it for real-time, low-latency needs such as ad targeting. ``agentic``
        uses

        an LLM to plan multiple structured sub-searches for complex queries,
        with

        higher latency than the other modes.
    TurnErrorCode:
      type: string
      enum:
        - invalid_request
        - unauthorized
        - insufficient_credits
        - conversation_not_found
        - turn_conflict
        - rate_limited
        - model_unavailable
        - token_not_found
        - service_unavailable
        - internal
      title: TurnErrorCode
    ToolPart:
      properties:
        type:
          type: string
          const: tool
          title: Type
          default: tool
        tool_call_id:
          type: string
          title: Tool Call Id
        tool_name:
          type: string
          title: Tool Name
        input:
          anyOf:
            - $ref: '#/components/schemas/SearchProductsInput'
            - $ref: '#/components/schemas/ProductIdsInput'
          title: Input
        output:
          anyOf:
            - $ref: '#/components/schemas/CatalogDisplayPayload'
            - $ref: '#/components/schemas/CatalogToolError'
            - type: 'null'
          title: Output
      type: object
      required:
        - tool_call_id
        - tool_name
      title: ToolPart
      description: One catalog tool call and its display payload from an assistant turn.
    SearchFilterColor:
      properties:
        hex:
          type: string
          title: Hex
          description: sRGB hex string, e.g. '#a1b2c3'
        percentage:
          anyOf:
            - type: number
            - type: 'null'
          title: Percentage
          description: Percentage of color, where 1.0 is 100%
      type: object
      required:
        - hex
      title: SearchFilterColor
      description: A single color requirement for the color filter.
    ColorMatch:
      type: string
      enum:
        - strict
        - standard
        - loose
      title: ColorMatch
      description: How tightly a product's colors must match the requested palette.
    SearchFilterLengthDimension:
      properties:
        min:
          anyOf:
            - type: number
            - type: 'null'
          title: Min
          description: Minimum value, in `unit`. Inclusive.
        max:
          anyOf:
            - type: number
            - type: 'null'
          title: Max
          description: Maximum value, in `unit`. Inclusive.
        unit:
          $ref: '#/components/schemas/LengthUnit'
          description: Unit that min/max are expressed in
      additionalProperties: false
      type: object
      required:
        - unit
      title: SearchFilterLengthDimension
    SearchFilterWeightDimension:
      properties:
        min:
          anyOf:
            - type: number
            - type: 'null'
          title: Min
          description: Minimum value, in `unit`. Inclusive.
        max:
          anyOf:
            - type: number
            - type: 'null'
          title: Max
          description: Maximum value, in `unit`. Inclusive.
        unit:
          $ref: '#/components/schemas/WeightUnit'
          description: Unit that min/max are expressed in
      additionalProperties: false
      type: object
      required:
        - unit
      title: SearchFilterWeightDimension
    SearchProductsInput:
      properties:
        query:
          type: string
          title: Query
      type: object
      required:
        - query
      title: SearchProductsInput
    ProductIdsInput:
      properties:
        product_ids:
          items:
            type: string
          type: array
          title: Product Ids
      type: object
      title: ProductIdsInput
    CatalogDisplayPayload:
      properties:
        products:
          items:
            $ref: '#/components/schemas/Product'
          type: array
          title: Products
        next_page_token:
          anyOf:
            - type: string
            - type: 'null'
          title: Next Page Token
      additionalProperties: true
      type: object
      title: CatalogDisplayPayload
      description: >-
        Client-facing catalog tool result shown on the stream and on
        ``ToolPart``.
    CatalogToolError:
      properties:
        error:
          type: string
          title: Error
        is_error:
          type: boolean
          const: true
          title: Is Error
          default: true
        products:
          items:
            $ref: '#/components/schemas/Product'
          type: array
          title: Products
      type: object
      required:
        - error
      title: CatalogToolError
    Product:
      properties:
        id:
          type: string
          title: Id
        title:
          type: string
          title: Title
        description:
          anyOf:
            - type: string
            - type: 'null'
          title: Description
        brands:
          items:
            $ref: '#/components/schemas/ProductBrand'
          type: array
          title: Brands
          description: Ordered list of brands.
        images:
          items:
            $ref: '#/components/schemas/ProductImage'
          type: array
          title: Images
          default: []
        category:
          anyOf:
            - $ref: '#/components/schemas/CategorySummary'
            - type: 'null'
          description: >-
            The single category this product belongs to, as a structured
            `CategorySummary` (slug, title, path, has_children).
        gender:
          anyOf:
            - $ref: '#/components/schemas/Gender'
            - type: 'null'
        age:
          anyOf:
            - $ref: '#/components/schemas/Age'
            - type: 'null'
          description: >-
            Target age group. Age-agnostic products are typically returned as
            'adult'.
        materials:
          anyOf:
            - items:
                type: string
              type: array
            - type: 'null'
          title: Materials
        key_features:
          anyOf:
            - items:
                type: string
              type: array
            - type: 'null'
          title: Key Features
        offers:
          items:
            $ref: '#/components/schemas/ProductOffer'
          type: array
          title: Offers
          description: All merchant offers for this product in the requested locale.
        variants:
          anyOf:
            - $ref: '#/components/schemas/Variants'
            - type: 'null'
          description: >-
            Variant interaction state — options, selected. Absent when the
            product has no variations.
        structured_attributes:
          additionalProperties:
            items:
              type: string
            type: array
          type: object
          title: Structured Attributes
          description: >-
            Structured attributes extracted for this product, keyed by attribute
            handle (e.g. 'color', 'material'). Values are the canonical allowed
            values for that handle.
      type: object
      required:
        - id
        - title
      title: Product
      description: Product with detailed information.
    ProductBrand:
      properties:
        id:
          type: string
          title: Id
        name:
          type: string
          title: Name
      type: object
      required:
        - id
        - name
      title: ProductBrand
    ProductImage:
      properties:
        url:
          type: string
          title: Url
        cleaned_url:
          anyOf:
            - type: string
            - type: 'null'
          title: Cleaned Url
          description: >-
            Background-removed square image on Channel3 CDN when available. Use
            for product grids; ``url`` is the regular hosted shot.
        is_main_image:
          type: boolean
          title: Is Main Image
          default: false
        shot_type:
          anyOf:
            - $ref: '#/components/schemas/ApiProductImageType'
            - type: 'null'
        alt_text:
          anyOf:
            - type: string
            - type: 'null'
          title: Alt Text
      type: object
      required:
        - url
      title: ProductImage
      description: Product image with metadata.
    CategorySummary:
      properties:
        slug:
          type: string
          title: Slug
          description: URL-friendly slug (e.g. 'sofas')
        title:
          type: string
          title: Title
          description: Human-readable category title
        path:
          items:
            $ref: '#/components/schemas/CategoryRef'
          type: array
          title: Path
          description: >-
            Hierarchical path as a structured list, root first; the last entry
            is this category itself
        has_children:
          type: boolean
          title: Has Children
          description: Whether this category has subcategories
      type: object
      required:
        - slug
        - title
        - has_children
      title: CategorySummary
      description: Lean category representation used in search hits and list rows.
    ProductOffer:
      properties:
        url:
          type: string
          title: Url
        domain:
          type: string
          title: Domain
        price:
          $ref: '#/components/schemas/Price'
        availability:
          $ref: '#/components/schemas/OfferAvailabilityStatus'
        condition:
          anyOf:
            - $ref: '#/components/schemas/Condition'
            - type: 'null'
          description: >-
            Condition of this merchant offer (new or used). Null when condition
            is unknown.
        max_commission_rate:
          type: number
          title: Max Commission Rate
          description: >-
            The maximum commission rate for the merchant, as a decimal fraction:
            0 is no commission, 0.5 is 50% commission. 'Max' because the actual
            commission rate may be lower due to vendor-specific affiliate rules.
          default: 0
        dimensions:
          anyOf:
            - $ref: '#/components/schemas/Dimensions'
            - type: 'null'
          description: Physical dimensions of this offer. Null when unknown.
      type: object
      required:
        - url
        - domain
        - price
        - availability
      title: ProductOffer
    Variants:
      properties:
        options:
          items:
            $ref: '#/components/schemas/VariantOption'
          type: array
          title: Options
        selected:
          items:
            $ref: '#/components/schemas/SelectedOption'
          type: array
          title: Selected
      type: object
      required:
        - options
        - selected
      title: Variants
      description: |-
        Wrapper for variant-interaction state on a Product.

        Holds `options` and `selected`. `options` represent all of the
        configuration options for the product. `selected` represents the
        currently selected option values.
    ApiProductImageType:
      type: string
      enum:
        - hero
        - lifestyle
        - on_model
        - detail
        - scale_reference
        - angle_view
        - flat_lay
        - in_use
        - packaging
        - size_chart
        - product_information
        - merchant_information
      title: ApiProductImageType
      description: Product image type classification for API responses.
    CategoryRef:
      properties:
        slug:
          type: string
          title: Slug
          description: URL-friendly slug (e.g. 'sofas')
        title:
          type: string
          title: Title
          description: Human-readable category title
      type: object
      required:
        - slug
        - title
      title: CategoryRef
      description: Lean reference to a category, used in path and children arrays.
    Price:
      properties:
        price:
          type: number
          title: Price
          description: The current price of the product, including any discounts.
        compare_at_price:
          anyOf:
            - type: number
            - type: 'null'
          title: Compare At Price
          description: The original price of the product before any discounts.
        currency:
          type: string
          title: Currency
          description: The currency code of the product, like USD, EUR, GBP, etc.
      type: object
      required:
        - price
        - currency
      title: Price
    Dimensions:
      properties:
        length:
          anyOf:
            - $ref: '#/components/schemas/LengthDimension'
            - type: 'null'
        width:
          anyOf:
            - $ref: '#/components/schemas/LengthDimension'
            - type: 'null'
        height:
          anyOf:
            - $ref: '#/components/schemas/LengthDimension'
            - type: 'null'
        weight:
          anyOf:
            - $ref: '#/components/schemas/WeightDimension'
            - type: 'null'
      type: object
      title: Dimensions
      description: >-
        Physical dimensions of a product offer. Members are null when unknown.


        Values are standardized to the supported unit set; a merchant-stated
        value

        whose unit is not one of those units is omitted rather than shown.
    VariantOption:
      properties:
        name:
          type: string
          title: Name
          description: The name of the option (e.g. 'Color', 'Size')
        values:
          items:
            $ref: '#/components/schemas/OptionValue'
          type: array
          title: Values
          description: The values of the option (e.g. ['Blue', 'Red', 'Green'])
      type: object
      required:
        - name
        - values
      title: VariantOption
      description: One dimension of a product family (e.g. 'Color', 'Size').
    SelectedOption:
      properties:
        name:
          type: string
          title: Name
          description: The name of the selected option (e.g. 'Color', 'Size')
        label:
          type: string
          title: Label
          description: The display value of the selected option (e.g. 'Blue', 'XL')
      type: object
      required:
        - name
        - label
      title: SelectedOption
      description: One effective selection on a product, post server-side relaxation.
    LengthDimension:
      properties:
        number:
          type: number
          title: Number
        unit:
          $ref: '#/components/schemas/LengthUnit'
          description: >-
            The unit from the request's dimension filters when one was given
            (the value is converted to it); otherwise the unit the merchant
            stated.
      type: object
      required:
        - number
        - unit
      title: LengthDimension
      description: A length measurement, in one of the supported length units.
    WeightDimension:
      properties:
        number:
          type: number
          title: Number
        unit:
          $ref: '#/components/schemas/WeightUnit'
          description: >-
            The unit from the request's dimension filters when one was given
            (the value is converted to it); otherwise the unit the merchant
            stated.
      type: object
      required:
        - number
        - unit
      title: WeightDimension
      description: A weight measurement, in one of the supported weight units.
    OptionValue:
      properties:
        label:
          type: string
          title: Label
          description: The display value of the option value (e.g. 'Blue')
        exists:
          type: boolean
          title: Exists
          description: >-
            Whether the option value exists on the product, or is a
            configuration only present on another variant of the same product.
            For example, a shirt that comes in multiple colors, but only one
            color is available in Size XL.
        available:
          anyOf:
            - $ref: '#/components/schemas/OfferAvailabilityStatus'
            - type: 'null'
          description: >-
            The availability status of the option value. None when returned on
            search results, hydrated only on get product detail requests.
        thumbnail_url:
          anyOf:
            - type: string
            - type: 'null'
          title: Thumbnail Url
          description: >-
            For options that reference different products, this is the URL of
            the thumbnail image for the option value. E.g., a shoe that comes in
            multiple colors will have an OptionValue for each color with a
            thumbnail_url set.
        product_id:
          anyOf:
            - type: string
            - type: 'null'
          title: Product Id
          description: >-
            The product id that represents this value. Variants that point to
            different products will have this field set, as well as
            thumbnail_url for displaying selector icons.
      type: object
      required:
        - label
        - exists
      title: OptionValue
      description: One value of one variant option (e.g. 'Blue' under 'Color')
  securitySchemes:
    APIKeyHeader:
      type: apiKey
      in: header
      name: x-api-key
    Bearer:
      type: http
      scheme: bearer
      x-fern-bearer:
        name: token
        env: CHANNEL3_TOKEN

````