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

# Retrieve product question answers

`POST /v1/agent_insights/qna`

## Request

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

Answer a shopper's question about one specific product. The agent answers from that product's own data rather than by searching the catalog, which is what makes it suitable for the question box on a product page. Which sources it draws on is configured per index key, and typically covers the product's attributes and description, and its customer reviews where those are ingested. Frequently asked questions may be answered from a pre-generated set, so a common question returns faster than a novel one. An answer can cite the part of the product imagery it draws on, such as a size chart or a dimensions diagram, and can suggest related products where they help. `page_context.item_id` is the product the question is about, and `shopper_input` is the question itself. Pass `thread_id` to ask a follow-up in the same conversation. 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

- QnARequestBody: A shopper's question about one product, with the page it was asked from. The product is identified by `page_context.item_id`.
  - `shopper_input` string, required: The question to answer about the product.
  - `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` QnAParameters: Extra parameters for `POST /v1/agent_insights/qna`. The question and the product are carried by `shopper_input` and `page_context` rather than here.
  - `request_context` AgentInsightsRequestContext: Facts that apply to this request only, supplied separately from `shopper_input`: they are never added to the conversation, so a later turn of the same thread cannot reuse them. Accepted only where request context is enabled: for `chat`, on the domain that serves the request; for `qna`, on the index key. Elsewhere a request carrying `request_context` is rejected with `400`. Once enabled, a turn without `request_context` tells the agent that no request price applies, so a price from an earlier turn is not reused. To send no price, omit `request_context`. "Printable", for a price's `item_id`, `variation_id` and `reason`, means letters, marks, numbers, punctuation, symbols and the plain space (U+0020) only. Tabs, line breaks, other control and format characters (such as a soft hyphen, or the zero-width joiner inside some emoji), other spaces (such as a non-breaking space) and private-use characters are rejected, and so, currently, are characters added after Unicode 14.0, such as emoji introduced since 2022.
    - `prices` AgentInsightsRequestScopedPrice[], required: Up to one item-level price, which omits `variation_id`, and one price for the selected variation, which sets it to `page_context.variation_id`. Both are for `page_context.item_id`. One price per item/variation scope.
      - `item_id` string, required: The product this price is for. Must equal `page_context.item_id`. Printable, with no leading or trailing whitespace; compared verbatim, never normalised.
      - `variation_id` string: The variation this price is for. Must equal `page_context.variation_id`. Omit it for a price that applies to the whole item. Printable, with no leading or trailing whitespace; compared verbatim, never normalised.
      - `amount` string, required: The price, as a decimal string greater than zero with at most 12 digits before the decimal point and 6 after it, e.g. `29.95`.
      - `currency` string, required: A three-letter currency code, e.g. `AUD`. Normalised to uppercase.
      - `expires_at` string, date-time, required: When the price stops applying, with a timezone. An expired price is accepted and treated as absent.
      - `source` 'integration' | 'browser', required: Who resolved the price, as the caller declares it: `integration` for a price resolved server-side, `browser` for one resolved in the shopper's browser. Not verified, so both carry the same trust; it is never an authorization or eligibility signal.
      - `reason` string: Why the shopper gets this price, e.g. `VIP Loyalty Program`, so the agent can mention it next to the price. Declared by the caller like `source`, so it proves nothing about eligibility. One printable line, with no leading or trailing whitespace.

## 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, or an unknown index key. Also returned for a `request_context` the index key has not enabled, or one that fails validation.
- `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)
