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

# Compare products

> Compare products from the tenant's catalogue.

Compare products from the tenant's catalogue. The endpoint selects the product-comparison intent automatically, so you do not send an `intent` field.

## Selecting products

Supply the catalogue product IDs in `productIds`. Provide at least two product IDs for a useful comparison. The `content` field tells the API which attributes or use case matter to the shopper.

## Request example

```bash theme={null}
curl --no-buffer --request POST \
  "$PREEZIE_API_URL/api/operation/compare" \
  --header "Authorization: Bearer $PREEZIE_OPERATION_TOKEN" \
  --header "Tenantid: $PREEZIE_TENANT_ID" \
  --header "Content-Type: application/json" \
  --data '{
    "sessionId": "session-123",
    "visitorId": "visitor-456",
    "content": "Compare these products for everyday running",
    "requestOrigin": "Operation",
    "productIds": ["product-123", "product-456"],
    "operationHideAiMessage": false,
    "operationReturnFullProductInfo": false
  }'
```

## Behaviour

* Products are loaded in the order requested when their IDs can be resolved.
* Unknown product IDs are skipped; use IDs from the same tenant catalogue.
* `content` can focus the comparison on qualities such as price, fit, material, features, or intended use.
* Comparison results are delivered incrementally through the response stream.

## Streaming response

The response uses `text/event-stream`. Each `data:` line contains one JSON message:

```text theme={null}
data: {"chatStream":"The first product is lighter, while the second offers more cushioning."}

```

Set `operationHideAiMessage` to `true` to suppress AI-message events when your integration only needs non-chat stream data.


## OpenAPI

````yaml openapi/preezie-api.json POST /api/operation/compare
openapi: 3.1.0
info:
  title: preezie API
  version: 0.1.0
  description: >-
    API reference for product discovery operations and generated product-page
    content. Core Intent responses are streamed as server-sent events (SSE); FAQ
    and Highlights responses use JSON.
servers: []
security: []
tags:
  - name: Core intents
    description: >-
      Run a specific product-discovery intent without sending an intent value in
      the request body.
  - name: Product content
    description: Retrieve generated product FAQs and highlights for product detail pages.
paths:
  /api/operation/compare:
    post:
      tags:
        - Core intents
      summary: Compare products
      description: >-
        Compares products from the tenant's catalogue. Supply the products in
        `productIds` and use `content` to describe the comparison the shopper
        wants.
      operationId: compareProducts
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CoreIntentRequest'
            example:
              sessionId: session-123
              visitorId: visitor-456
              content: Compare these products for everyday running
              requestOrigin: Operation
              productIds:
                - product-123
                - product-456
              operationHideAiMessage: false
              operationReturnFullProductInfo: false
      responses:
        '200':
          $ref: '#/components/responses/CoreIntentStream'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/TenantNotFound'
      security:
        - bearerAuth: []
          tenantId: []
components:
  schemas:
    CoreIntentRequest:
      type: object
      required:
        - content
      properties:
        sessionId:
          type: string
          description: Conversation session identifier. Reuse it for related requests.
          example: session-123
        visitorId:
          type: string
          description: Stable identifier for the shopper or visitor.
          example: visitor-456
        websiteUrl:
          type: string
          format: uri
          deprecated: true
          description: >-
            Legacy top-level URL field. Use `chatMetadata.websiteUrl` for the
            current page context.
        chatMetadata:
          $ref: '#/components/schemas/ChatMetadata'
        content:
          type: string
          minLength: 1
          description: Natural-language request that guides the selected operation.
          example: Show me lightweight black running shoes
        requestOrigin:
          type: string
          enum:
            - Operation
          default: Operation
          description: Source of the request. Use `Operation` for these endpoints.
        productIds:
          type: array
          description: >-
            Explicit product identifiers consumed by operations such as
            comparison. For similarity and bundling, identify the base product
            with `chatMetadata.productId` instead.
          items:
            type: string
          default: []
        pageSize:
          type: integer
          minimum: 1
          description: >-
            Maximum number of product results requested. When omitted, the
            tenant's configured default is used.
        operationHideAiMessage:
          type: boolean
          default: false
          description: >-
            When `true`, suppresses `chatStream` events and returns only
            non-chat stream events.
        operationReturnFullProductInfo:
          type: boolean
          default: false
          description: >-
            When `false`, products in a conversation response payload are
            reduced to `{"id": "..."}` objects. When `true`, the full product
            objects are returned.
    ChatMetadata:
      type: object
      description: Optional context from the current product or page.
      properties:
        productId:
          type: string
          description: Current product identifier.
        variantId:
          type: string
          description: Current product variant identifier.
        title:
          type: string
          description: Current product or page title.
        websiteUrl:
          type: string
          format: uri
          description: URL of the current storefront page.
  responses:
    CoreIntentStream:
      description: >-
        A server-sent event stream. Each message is written as `data: <JSON>`
        followed by a blank line. The JSON payload contains one response key.
        `operationHideAiMessage` removes `chatStream` events;
        `operationReturnFullProductInfo` controls whether product payloads
        contain IDs only or full product objects.
      headers:
        Cache-Control:
          description: Disables caching of the event stream.
          schema:
            type: string
            example: no-cache
        X-Accel-Buffering:
          description: Disables proxy buffering so events reach the client immediately.
          schema:
            type: string
            example: 'no'
      content:
        text/event-stream:
          schema:
            type: string
            description: >-
              A sequence of SSE messages whose data values follow the
              `StreamEvent` schema.
          example: >+
            data: {"chatStream":"I found several products that match your
            request."}


            data:
            {"data":{"responseType":"ProductSearch","sessionId":"session-123","visitorId":"visitor-456","responsePayload":[{"id":"product-123"}],"hasMoreProducts":false,"total":1}}

    BadRequest:
      description: >-
        The operation could not be completed because the downstream AI request
        was invalid.
    Unauthorized:
      description: >-
        The operation token is missing, invalid, expired, or belongs to a
        different tenant.
    Forbidden:
      description: >-
        The `Tenantid` header is missing, the tenant is inactive, or the tenant
        has exceeded its usage allowance.
      content:
        text/plain:
          schema:
            type: string
          example: Tenant ID Invalid.
    TenantNotFound:
      description: No tenant exists for the supplied `Tenantid` value.
      content:
        text/plain:
          schema:
            type: string
          example: 'Tenant tenant-123 not found #000'
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >-
        A short-lived HS256 operation token. Its `tenantId` claim must exactly
        match the `Tenantid` header. Mint this token on a trusted server; never
        expose the tenant signing credential in browser code.
    tenantId:
      type: apiKey
      in: header
      name: Tenantid
      description: >-
        The preezie tenant identifier. This value identifies the catalogue and
        is not a secret.

````