---
title: "Retrieve product recommendations"
method: POST
path: "/v1/agent_insights/recommendations"
tags: ["Agent insights"]
---

# Retrieve product recommendations

`POST /v1/agent_insights/recommendations`

## Request

- Base URL: `https://agent.cnstrc.com`
- URL: `https://agent.cnstrc.com/v1/agent_insights/recommendations`
- Auth: none required

Produce a curated set of recommendations for a recommendations widget. The agent retrieves candidates related to an anchor product, then selects and orders them for this shopper, writing a title for the set and, where useful, a short explanation of why these products go together. It also returns refinement options, so a shopper can narrow the set without leaving the widget: pass the chosen one back as `shopper_input` on the next request. Nothing else is needed on the first render, which is the usual way to call this mode. `parameters.strategy` names the configured pod to run, which decides what kind of set this is — complements, alternatives, or another relationship the index key has configured. `page_context.item_id` is the anchor product it is built around, and `page_context.filters` scope the candidates to the facets the shopper already has active. Results stream back as [server-sent events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events) (`text/event-stream`) so the agent's reply can be rendered as it is produced. To receive the finished reply as a single JSON document instead, send `Accept: application/json`.

## Query parameters

- `key` string, required: The key of the index to use.
- `thread_id` string, uuid: A unique identifier for the conversation thread. This ID links multiple requests to the same conversation. When omitted, a new thread is created.
- `guard` boolean: Turn the content moderation check on or off. When on, shopper input is screened before the agent processes it.
- `num_result_events` integer: The maximum number of result events to return.
- `num_results_per_event` integer: The maximum number of results to return per `item_results` event.
- `fmt_options` FmtOptions: Options to format different aspects of the response.
  - `fields` string[]: A list of specific item fields to return in the response. Allows the request to control which fields are returned.
  - `show_hidden_fields` boolean: A flag to return all `hidden` fields in the response.
  - `hidden_fields` string[]: A list of specific hidden fields to return in the response. Unlike `show_hidden_fields` this parameter allows the request to control which `hidden` fields are returned. Used to return item fields for a particular store or user segment.
  - `variations_return_type` 'default' | 'all' | 'matched'
  - `groups_max_depth` integer: The maximum depth of the group hierarchy in the response.
  - `groups_start` string: A flag to specify the start of the group hierarchy returned in the response. `current` returns groups starting from the currently selected one. `top` returns groups starting from the root category in the hierarchy. `group_id:{id}`, returns the whole tree starting from group with the provided id.
  - `groups_path` string[]: Specifies the path from the root group to the current group you are browsing. It is used to construct the parents path in the `response.groups` for the current browsed group. Max depth allowed for the path is 10. This option is only accepted when `groups_start` is 'current'.
  - `groups_sort_by` 'relevance' | 'value' | 'num_matches'
  - `groups_sort_order` 'ascending' | 'descending'
  - `show_hidden_facets` boolean: A flag to return all facets configured as `hidden` in `response.facets`.
  - `hidden_facets` string[]: A list of specific hidden facets to return in the response. Unlike `show_hidden_facets` this parameter allows the request to control which hidden facets are returned. Used to return facets for a particular store or user segment.
  - `show_hidden_facet_options` boolean: A flag to return all `hidden` facets options in the response.
  - `show_protected_facets` boolean: A flag to return all `protected` facets in the response. Requires authentication.
  - `facet_options` object: A list of specific facet options per facet to return in the response. This parameter accepts up to 5 facets and works only with facets of type `multiple`. Invalid facet options will be ignored. Used to return facet options for a particular facet like store or user segment.
  - `facet_groups_limit` integer: The maximum limit of the facet groups returned in the response.
  - `show_hidden_sort_options` boolean: A flag to return all sort options configured as `hidden` in `response.sort_options`.
  - `hidden_sort_options` string[]: A list of `sort_by` fields whose hidden sort options should be included in the response. Unlike `show_hidden_sort_options` this parameter allows you to specify exactly which hidden sort options are returned.
- `qs` string, json: Additional query parameters to forward to the underlying Constructor search, browse and recommendations API calls, as a JSON-encoded string: for example `qs={"sort_by":"price","sort_order":"ascending"}`. Each mode forwards only the keys that apply to the calls it makes, and any key managed by `page_context.filters` must not be overridden here.
- `c` string: The ID of the client and version that the request is coming from, such as `cio-js-2.90`.
- `us` string[]: A customer defined context (such as `vip-club-member`) used to evaluate redirect or refined tag rules. Pass multiple segments by passing multiple `us` arguments.
- `ui` string: A customer generated anonymized identifier for a user on a customer website. It should only be sent for logged in customers and helps constructor to tie multiple client and session ID's together to form a behavioral data profile across devices.
- `feature_variants` object: Feature variants keyed by feature name. Accepts flattened `feature_variants[<feature_name>]` query parameters.
- `features` object: Feature toggles keyed by feature name. Accepts flattened `features[<feature_name>]` query parameters.
- `s` integer: An integer representing the user's session number (starting with `1`), incremented after a 30 minute period of inactivity.
- `i` string: A globally unique identifier for the user browser (or mobile application instance) making the request.

## Request body

- RecommendationsRequestBody: A request for recommendations seeded by one product, with the page the shopper is on. `parameters.strategy` selects which configured recommendations pod runs.
  - `shopper_input` string: An optional shopper utterance to steer the recommendations. When present it acts as an extra refinement signal on top of `parameters.strategy` and `page_context`.
  - `page_context` AgentInsightsItemPageContext, required: Page context for a mode that acts on one specific product, whatever page the shopper asked from. `item_id` is required here rather than only on a PDP: `qna` always answers about a single product, and `recommendations` needs an anchor to recommend relative to, but either can be triggered from a quick-view on a listing page or from an email campaign.
    - `page_type` 'home' | 'plp' | 'pdp' | 'collection' | 'email_campaign' | 'cart', required: The type of e-commerce page the shopper is currently on. Drives different validation rules and gives the agent additional context about the shopper's position in the catalog.
    - `item_id` string, required: The product identifier this request is about. Required.
    - `variation_id` string: The variation (SKU) identifier for the currently viewed product variant. Gives the agent context to focus on a particular variation. Only valid when `item_id` is set.
    - `search_term` string: The search query that produced the current product listing. Relevant for PLP pages with search context.
    - `browse_filter` AgentInsightsBrowseFilter: The primary browse filter pair that defines the category or collection being browsed. This corresponds to the main navigation filter in the Constructor Browse API: typically a group_id or collection_id that determines which product listing the shopper is viewing. See: https://docs.constructor.com/reference/v1-browse-get-browse-results
      - `name` string, required: The browse filter name, typically `group_id` for category pages or `collection_id` for collections.
      - `value` string, required: The browse filter value: the specific category or collection identifier.
    - `filters` AgentInsightsFilterExpression[]: Active product filters (facets) currently applied on the page, as a list of [filter expressions](/reference/shared-filter-expressions). They describe the shopper's context, and are forwarded to the downstream Constructor call by any mode that issues a filterable one. `qna` looks its products up by ID, so it does not narrow results by them.
      - `name` string, required: The filter (facet) name, as configured in the customer's index.
      - `value` union: The selected filter value(s). A single value is accepted and normalized to a single-element list, and numbers/booleans are rendered as strings. Mutually exclusive with `range`.
        - string
        - integer
        - number
        - boolean
        - union[]
          - union
            - string
            - integer
            - number
            - boolean
      - `range` union[]: An inclusive [start, end] range for numeric or date filters. Numbers are accepted and rendered as strings. Use '-inf' or 'inf' for an open bound. Mutually exclusive with `value`.
        - union
          - string
          - integer
          - number
          - boolean
      - `match_type` 'any' | 'all' | 'none': Controls how multiple selected values for the same filter are combined. Used to override the default OR behavior when multiple options of the same facet are selected: - any: Results must match ANY of the selected values (OR, default Constructor behavior). - all: Results must match ALL of the selected values (AND). - none: Results must match NONE of the selected values (exclusion).
  - `parameters` RecommendationsParameters, required: Extra parameters for `POST /v1/agent_insights/recommendations`.
    - `strategy` string, required: The recommendations pod to run, named by the `id` of a routing rule configured for this index key, for example `complementary_pod` or `alternatives_pod`. The accepted values are whatever the key has configured rather than a fixed platform list, so an unconfigured id is rejected with `400` and the error lists the ids the key does offer. Note this is not a Constructor Recommendations API pod id such as `complementary_items`: a single routing rule may draw on several of those.
    - `default_title` string: Title to display when the returned recommendations set is the non-personalized default, i.e. when the agent did not produce a personalized title. At most 100 characters.

## Response `200`

AI-powered agent insights, streamed as server-sent events or aggregated into a single JSON document.

- AgentInsightsResponse: The collected agent insight returned when the client asks for `application/json`.
  - `result_id` string, required: Agent insight result ID.
  - `thread_id` string, uuid: A unique identifier for the conversation thread. Pass it back on the next request to continue the same conversation. Only populated for conversational modes.
  - `status` 'complete' | 'partial', required: Whether the collected stream represents the agent's full answer. - complete: the underlying stream finished normally. - partial: the stream was truncated or emitted a server_error, so the answer may be incomplete.
  - `message` string: The agent's text output. When the agent produced several message events they are joined in the order they were emitted.
  - `route` 'customer_support': Where the client should send the shopper next. `customer_support` marks a customer support answer.
  - `item_results` AggregatedItemResults[]: Every set of product results the agent produced, in emission order.
    - `result_id` string: The result ID of the underlying Constructor response.
    - `title` string: Agent-generated title for this set of results.
    - `text` string: Agent-generated explanation of this set of results.
    - `request` AgentInsightsItemResultsRequest: The Constructor request used to obtain the accompanying results. Exposed so the caller can either re-issue the request itself (for pagination, refinement, or analytics) or use the results delivered alongside it. Extra keys are allowed because the underlying Constructor request shape differs per request type (e.g., `search_term` for search, `strategy` for recommendations).
      - `type` 'search' | 'browse' | 'recommendations', required: Which Constructor API produced a set of item results. Lets the client understand the nature of the results and render them accordingly: - search: retrieved via the Constructor Search API. - browse: retrieved via the Constructor Browse API. - recommendations: retrieved via the Constructor Recommendations API.
      - `ids` string[]: The item identifiers requested, when the results were retrieved by explicit id lookup.
      - `params` object: The parameters of the underlying Constructor call (num_results_per_page, page, sort_by, section, filters, fmt_options, features, ...).
    - `response` AgentInsightsItemResultsResponse, required: The Constructor response carrying the items themselves. `result_id` here is the identifier of the underlying Constructor search, browse, or recommendations response, used for analytics matching. It is distinct from the top-level ASA `result_id` of the event.
      - `result_id` string: The result ID of the underlying Constructor response, used for analytics matching. Distinct from the top-level ASA result_id.
      - `results` union[]: The items returned by the underlying Constructor call. Searchandizing metadata (is_slotted, labels) is preserved when the underlying API provides it.
        - union
          - SearchandizedResult
            - `value` string, required: Name of the matched item or variation (if variations are defined).
            - `matched_terms` string[], required: All terms within the item matching the user's query (regardless of whether misspelled).
            - `data` ResultData, required
              - …
            - `variations` ResultVariation[]: An array of this item's variations matching user's query.
              - …
            - `variations_map` union: Variations data in the format requested by `variations_map` query parameter.
              - …
            - `is_slotted` boolean, required: `true` if the current product is slotted as a result of searchandizing.
            - `labels` object, required: A set of miscellaneous properties of this result. For example, it can indicate whether a slotted result is advertised or promoted.
          - Result
            - `value` string, required: Name of the matched item or variation (if variations are defined).
            - `matched_terms` string[], required: All terms within the item matching the user's query (regardless of whether misspelled).
            - `data` ResultData, required
              - …
            - `variations` ResultVariation[], nullable: An array of this item's variations matching user's query.
              - …
            - `variations_map` union: Variations data in the format requested by `variations_map` query parameter.
              - …
      - `facets` union[]: Facets associated with the returned items, when the underlying Constructor call returned them.
        - union
          - RangeFacet
            - `type` 'range', required: If a facet is of type `range`, then no facet options are provided. Instead a `min` and `max` value is provided to specify the range of values that can be sent in `filters`.
            - `name` string, required: The name of the facet. This should be passed in the filters parameter when a facet of this type is selected. `filters[name]=value`
            - `display_name` string, required: The name of the facet as it is displayed to end users. Note that in `filters` parameter you need to use not `display_name` but `name`.
            - `hidden` boolean, required: The boolean value saying whether facet is available for interaction.
            - `data` object, required: Object containing custom data associated with this facet. An empty object (`{}`) if no data is currently associated with this facet.
            - `status` RangeFacetStatus
              - …
            - `min` union: Minimum facet value of the result items.
              - …
            - `max` union: Maximum facet value of the result items.
              - …
          - SingleOrMultipleFacet
            - `type` 'single' | 'multiple', required: If a facet is of type `single`, then only one of the options may be selected (e.g: display as radio button). If the type is `multiple`, then multiple options may be selected (e.g: display as checkboxes).
            - `name` string, required: The name of the facet. This should be passed in the filters parameter when a facet of this type is selected. `filters[name]=value`
            - `display_name` string, required: The name of the facet as it is displayed to end users. Note that in `filters` parameter you need to use not `display_name` but `name`.
            - `hidden` boolean, required: The boolean value saying whether facet is available for interaction.
            - `data` object, required: Object containing custom data associated with this facet. An empty object (`{}`) if no data is currently associated with this facet.
            - `options` FacetOption[]: An array of possible facet values matching this search. By default, facet options are sorted by relevance. Number of options is limited, by default, to 500. But the limit can be configured per [facet](/reference/v1-facets-create-facet) key.
              - …
          - HierarchicalFacet
            - `type` 'hierarchical', required
            - `name` string, required: The name of the facet. This should be passed in the filters parameter when a facet of this type is selected. `filters[name]=value`
            - `display_name` string, required: The name of the facet as it is displayed to end users. Note that in `filters` parameter you need to use not `display_name` but `name`.
            - `hidden` boolean, required: The boolean value saying whether facet is available for interaction.
            - `data` object, required: Object containing custom data associated with this facet. An empty object (`{}`) if no data is currently associated with this facet.
            - `options` HierarchicalFacetOption[]: An array of possible facet values matching this search. By default, facet options are sorted by relevance.
              - …
  - `article_references` AggregatedArticleReference[]: Knowledge base articles the agent referenced, in emission order.
    - `source` string, uri, required: Canonical URL of the referenced article.
    - `title` string, required: Title of the referenced article.
    - `image_url` string, uri: Representative image for the referenced article.
    - `abstract` string: Short abstract of the referenced article.
  - `images` AggregatedImageMeta[]: Images the agent referenced while answering, in emission order.
    - `item_id` string, required: The item this image belongs to.
    - `image_url` string, uri, required: Full-size image URL.
  - `recipes` AggregatedRecipe[]: Recipes the agent assembled, in emission order, each joined with its instructions. Present only for domains configured for recipes.
    - `recipe_title` string, required: The name of the recipe.
    - `prep_time_minutes` integer, required: How long the recipe takes to prepare, in minutes.
    - `cook_time_minutes` integer, required: How long the recipe takes to cook, in minutes.
    - `number_of_servings` integer: How many servings the recipe yields, when the agent stated it.
    - `ingredients` string[], required: The ingredients the recipe calls for, as free-form lines.
    - `steps` string[]: The preparation steps, in the order they are to be followed. Absent when the agent described the recipe without emitting instructions for it.
    - `text` string: A closing remark on the recipe, such as a serving suggestion.
  - `follow_up_refinement` AggregatedFollowUpRefinement: The suggested refinement, flattened from a `follow_up_refinement` event.
    - `question` string: The refinement prompt shown to the shopper. Absent when the mode suggests follow-ups without a prompt, in which case the suggestions are carried by `options`.
    - `options` string[]: Selectable answers to the refinement prompt.

## Other responses

- `400`: Invalid request parameters, an unknown index key, or a `parameters.strategy` not configured for the key. The error lists the strategies the key does offer.
- `429`: Rate limit exceeded.
- `500`: Internal server error.
- `503`: An upstream service was unavailable.

---

[API](https://skmtc.dev/constructor/apis/ai-shopping-agent.md) - [All operations](https://skmtc.dev/constructor/apis/ai-shopping-agent/llms.txt) - [OpenAPI document](https://skmtc.dev/constructor/apis/ai-shopping-agent/revisions/dbdbd16abddd?raw)
