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

# Recommend products

> Return compact, render-ready product and selected-variant recommendations.

The response contains one selected target per product and omits full variant
and media collections. See [Recommendation behavior](/recommendations/api#response)
for target semantics and fallbacks.


## OpenAPI

````yaml openapi.yaml POST /recommendations
openapi: 3.1.0
info:
  title: virtual.fit API
  version: 2.0.0
  description: Catalog sync, storefront fit evidence, and product recommendation endpoints.
servers:
  - url: https://api.virtual.fit
security:
  - bearerAuth: []
tags:
  - name: Catalog
  - name: Storefront evidence
  - name: Recommendations
paths:
  /recommendations:
    post:
      tags:
        - Recommendations
      summary: Recommend products
      description: >-
        Returns at most one selected target per product with compact display
        fields.
      operationId: recommendProducts
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RecommendationsRequest'
      responses:
        '200':
          description: Ranked recommendations.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecommendationsResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '413':
          $ref: '#/components/responses/TooLarge'
        '429':
          description: Short-term request limit reached.
          headers:
            Retry-After:
              schema:
                type: integer
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '503':
          description: Recommendations are temporarily unavailable.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  schemas:
    RecommendationsRequest:
      type: object
      required:
        - intent
      properties:
        intent:
          type: string
          enum:
            - similar
            - complete_the_look
            - likely_purchases
        site_key:
          type: string
          description: Custom JavaScript public site key. Provide this or `shop_domain`.
        shop_domain:
          type: string
          description: Canonical `.myshopify.com` domain. Provide this or `site_key`.
        product_ids:
          type: array
          maxItems: 5
          items:
            type: string
            maxLength: 256
        cart_product_ids:
          type: array
          maxItems: 500
          items:
            type: string
            maxLength: 256
        candidate_product_ids:
          type: array
          minItems: 1
          maxItems: 10000
          items:
            type: string
            maxLength: 256
        exclude_product_ids:
          type: array
          maxItems: 500
          items:
            type: string
            maxLength: 256
        shopper_id:
          type: string
          maxLength: 256
        limit:
          type: integer
          minimum: 1
          maximum: 100
          default: 12
        surface:
          type: string
    RecommendationsResponse:
      type: object
      required:
        - items
        - unknown_context_ids
      properties:
        items:
          type: array
          maxItems: 100
          items:
            $ref: '#/components/schemas/RecommendationItem'
        unknown_context_ids:
          type: array
          items:
            type: string
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: string
    RecommendationItem:
      type: object
      required:
        - product_id
        - target_type
        - variant_id
        - rank
        - available
      properties:
        product_id:
          type: string
        target_type:
          type: string
          enum:
            - product
            - visual_group
            - variant
        variant_id:
          type:
            - string
            - 'null'
        recommended_option_values:
          type: object
          additionalProperties:
            type: string
        rank:
          type: integer
          minimum: 1
        score:
          type: number
        title:
          type: string
        handle:
          type: string
        canonical_url:
          type: string
          format: uri
        image_url:
          type: string
          format: uri
        variant_title:
          type: string
        price:
          type: string
          description: Decimal amount.
        compare_at_price:
          type: string
          description: Decimal amount.
        currency:
          type: string
        available:
          type:
            - boolean
            - 'null'
          description: >-
            Known-unavailable targets are omitted; null means inventory is
            unknown.
        fit_evidence:
          $ref: '#/components/schemas/RecommendationFitEvidence'
    RecommendationFitEvidence:
      type: object
      required:
        - review_count
      properties:
        review_count:
          type: integer
          description: Current overall source review count.
        analyzed_review_count:
          type: integer
          description: Number of full review records available for fit analysis.
        average_rating:
          type: number
          minimum: 0
          maximum: 5
        signals:
          type: array
          items:
            $ref: '#/components/schemas/RecommendationFitSignal'
    RecommendationFitSignal:
      type: object
      required:
        - dimension_code
        - evidence_count
        - average_score
        - tight_count
        - neutral_count
        - loose_count
      properties:
        dimension_code:
          type: string
        evidence_count:
          type: integer
        average_score:
          type: number
          description: >-
            Negative means tighter, smaller, or shorter. Positive means looser,
            larger, or longer.
        tight_count:
          type: integer
        neutral_count:
          type: integer
        loose_count:
          type: integer
  responses:
    BadRequest:
      description: Invalid field or inconsistent catalog data.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Unauthorized:
      description: Missing or invalid API key.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    NotFound:
      description: Site, product, variant, or recommendation context not found.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    TooLarge:
      description: Request body, file, field, or collection exceeds its documented limit.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: Keep the virtual.fit API key on your server.

````