# Models

## The SearchResponse object

```json
{"openapi":"3.1.0","info":{"title":"Search API - Product Discovery & Image Search","version":"1.0.0"},"components":{"schemas":{"SearchResponse":{"type":"object","description":"Search results with products, facets, and pagination","required":["pagination","facets","sorters","search_text","products"],"properties":{"pagination":{"type":"object","description":"Pagination information","required":["current_page","num_pages","page_size","total_count"],"properties":{"current_page":{"type":"integer","description":"Current page number (1-indexed)"},"num_pages":{"type":"integer","description":"Total number of pages"},"page_size":{"type":"integer","description":"Number of items per page"},"total_count":{"type":"integer","description":"Total number of matching products"}}},"facets":{"type":"array","description":"Available filter facets/widgets for filtering search results. Each facet\nrepresents a filterable attribute (e.g., categories, price, color, size).\nFacets are configured through `FacetConfiguration` database records which\ndetermine widget type, display options, and aggregation settings.\nFacets are retrieved from Elasticsearch before product results and\nconverted to widgets based on their configuration.\n","items":{"$ref":"#/components/schemas/Widget"}},"sorters":{"type":"array","description":"Available sorting options for search results. Sort options are configured\nthrough `SortOption` database records which define display labels,\nparameter values, and Elasticsearch sort configurations. Only visible\nsort options are included, ordered by default status and custom order.\nThe currently selected sort option is marked with `is_selected: true`.\n","items":{"$ref":"#/components/schemas/Sorter"}},"search_text":{"type":["string","null"],"description":"The search query text used, or null if no search text was provided"},"products":{"type":"array","description":"Matching products","items":{"$ref":"#/components/schemas/Product"}}}},"Widget":{"type":"object","description":"Filter facet widget representing a filterable attribute in the search interface.\nWidgets are created during the facet conversion process after Elasticsearch\nreturns facet field data. The widget structure and behavior are controlled by\n`FacetConfiguration` database records managed via the administration interface.\n\n**Widget Type Determination:**\n- If a `FacetConfiguration` exists for the attribute, it specifies the widget type,\n  aggregation settings, and display options (name, order, widget_kwargs)\n- If no `FacetConfiguration` exists, fallback rules apply:\n  - `category_ids` always uses Category Widget\n  - `basket_offer_ids` always uses Promotion Widget\n  - All other attributes default to Multi Select Widget\n\n**Facet Configuration Properties:**\n- Widget type (multiselect, category, range, attribute_value, visual_swatch, etc.)\n- Widget kwargs (labels, sorting mode, display options)\n- Facet type and aggregation settings\n- Custom settings and display order\n- Translatable name and widget_kwargs for multi-language support\n\nFacet fields are retrieved from Elasticsearch first, before product results.\nThe facet field size (number of choices) is determined as follows:\n- If facet field has a `FacetConfiguration`, uses configured size from facet_kwargs\n- If attribute key is \"category_ids\", size is set to 500\n- Otherwise, default size is 100\n\nFacet fields are returned with inventory strategy context, as prices and\navailability may vary by inventory strategy. For multi-inventory scenarios,\nprice-related facets automatically adapt to show the active price list.\n","required":["name","key","search_key","widget_type","extra_params","data"],"properties":{"name":{"type":"string","description":"Display name of the facet shown to users"},"key":{"type":"string","description":"Facet key identifier used internally"},"search_key":{"type":"string","description":"Search parameter key used in query strings"},"widget_type":{"type":"string","description":"Widget type identifier. Determines how the filter is rendered in the UI.\nCommon types: \"category\", \"multiselect\", \"range\", \"promotion\"\n","enum":["category","multiselect","range","promotion"]},"order":{"type":["integer","null"],"description":"Display order for the widget. Lower numbers appear first. Null indicates\ndefault ordering based on attribute configuration\n"},"extra_params":{"type":"object","description":"Additional widget parameters for custom widget behavior. Used by\nFacet Configuration to pass widget-specific settings\n","additionalProperties":true},"data":{"type":"object","description":"Widget data including available choices or range values","required":["widget_type","name","key","search_key"],"properties":{"widget_type":{"type":"string","description":"Widget type identifier"},"name":{"type":"string","description":"Display name"},"key":{"type":"string","description":"Facet key identifier"},"search_key":{"type":"string","description":"Search parameter key"},"choices":{"type":"array","description":"Available filter choices (for multiselect and category widgets)","items":{"$ref":"#/components/schemas/WidgetChoice"}},"quantity":{"type":"integer","description":"Total number of matching products for this facet (for range widgets)"},"min_value":{"type":"number","description":"Minimum value in the range (for range widgets)"},"max_value":{"type":"number","description":"Maximum value in the range (for range widgets)"},"step":{"type":"number","description":"Step value for range slider (for range widgets)"},"order":{"type":["integer","null"],"description":"Display order"}},"additionalProperties":true}}},"WidgetChoice":{"type":"object","description":"Individual choice within a filter widget","required":["label","value","quantity","is_selected"],"properties":{"label":{"type":"string","description":"Display label for the choice"},"value":{"oneOf":[{"type":"integer"},{"type":"string"}],"description":"Choice value to use in filter requests"},"quantity":{"type":"integer","description":"Number of products matching this choice"},"is_selected":{"type":"boolean","description":"Whether this choice is currently active in the sorting"},"depth":{"type":"integer","description":"Category depth level (for category widgets)"},"real_depth":{"type":"integer","description":"Actual category depth in hierarchy (for category widgets)"},"url":{"type":"string","description":"URL to apply this filter (for category widgets)"},"menuitemmodel":{"type":["string","null"],"description":"Menu item model identifier (for category widgets)"},"is_parent_of_selection":{"type":"boolean","description":"Whether this category is a parent of a selected category (for category widgets)"}}},"Sorter":{"type":"object","description":"Sorting option available for search results. Sort options are configured\nthrough the `SortOption` database model and managed via the administration\ninterface.\n\nEach sort option defines:\n- Display label (translatable for multi-language support)\n- Parameter value used in the `sorter` query parameter\n- Elasticsearch sort configuration (field paths, directions, nested queries)\n- Display order and visibility settings\n- Default status\n\nSort options are retrieved based on the current language and filtered to\nshow only visible options, ordered by default status and custom order.\nWhen a sort option is selected, its Elasticsearch configuration is applied\nto the search query. Sort options automatically adapt to inventory strategy\ncontext, adjusting price field references when multiple price lists are\nactive (e.g., `products.price_1234` instead of `products.price`).\nA secondary sort by product listing ID ensures consistent ordering across pages.\n","required":["label","value","is_selected"],"properties":{"label":{"type":"string","description":"Display label for the sort option. Retrieved from the `SortOption` model\nand supports translation for multi-language sites\n"},"value":{"type":"string","description":"Sort option value to use in the `sorter` query parameter. This value\ncorresponds to the `value` field in the `SortOption` model\n"},"is_selected":{"type":"boolean","description":"Whether this sort option is currently active based on the `sorter` query\nparameter. Only one sort option should be selected at a time\n"}}},"Product":{"type":"object","description":"Product data returned in search results","required":["pk","name","sku","price","in_stock","currency_type","product_type"],"properties":{"pk":{"type":"integer","description":"Product identifier"},"name":{"type":"string","description":"Product name"},"sku":{"type":"string","description":"Product SKU"},"base_code":{"type":["string","null"],"description":"Product base code"},"attributes":{"type":"object","description":"Product attributes as key-value pairs","additionalProperties":true},"attribute_set":{"type":"integer","description":"Attribute set identifier"},"attributes_kwargs":{"type":"object","description":"Attribute metadata including labels and data types","additionalProperties":{"type":"object","properties":{"label":{"type":"string"},"value":{"type":"string"},"data_type":{"type":"string"}}}},"extra_attributes":{"type":"object","description":"Additional product attributes","additionalProperties":true},"productimage_set":{"type":"array","description":"Product images","items":{"$ref":"#/components/schemas/ProductImage"}},"price":{"type":"string","description":"Product price as stringified decimal"},"in_stock":{"type":"boolean","description":"Stock availability status"},"currency_type":{"type":"string","description":"Currency code"},"retail_price":{"type":"string","description":"Retail price as stringified decimal"},"unit_type":{"type":"string","description":"Stock unit type"},"tax_rate":{"type":"string","description":"Tax rate as stringified decimal"},"absolute_url":{"type":"string","description":"Product detail page URL"},"productvideo_set":{"type":"array","description":"Product videos","items":{"type":"object","additionalProperties":true}},"product_type":{"type":"string","description":"Product type identifier"},"price_type":{"type":"string","description":"Price type"},"form_schema":{"type":["array","null"],"description":"Form schema for product configuration","items":{"type":"object","additionalProperties":true}},"is_ready_to_basket":{"type":"boolean","description":"Whether product can be added to basket"},"stock":{"type":"integer","description":"Available stock quantity"},"data_source":{"type":["object","null"],"description":"Data source information","additionalProperties":true},"basket_offers":{"type":"array","description":"Applicable basket offers/promotions. When `OFFER_SHOW_LISTING_KWARGS` is\nenabled and the offer condition type is QUANTITY, `listing_kwargs` contains\ndiscounted pricing information for display on product listing pages.\n","items":{"type":"object","properties":{"pk":{"type":"integer","description":"Basket offer identifier"},"label":{"type":"string","description":"Display label for the offer"},"listing_kwargs":{"type":"object","description":"Listing arguments containing discounted price information. Only populated\nwhen `OFFER_SHOW_LISTING_KWARGS` is enabled and the offer has a QUANTITY\ncondition type with matching product collection. Contains:\n- `quantity`: Required quantity to qualify for the offer\n- `discounted_total_price`: Total price after discount for the specified quantity\n- `discount`: Discount amount applied\n- `data_sources`: (optional) Data source filters if applicable\n","properties":{"quantity":{"type":"integer","description":"Required quantity to qualify for the offer"},"discounted_total_price":{"type":"string","description":"Total price after discount for the specified quantity"},"discount":{"type":"string","description":"Discount amount applied"},"data_sources":{"type":"array","description":"Data source identifiers (optional, only if condition includes data_sources)","items":{"type":"integer"}}},"additionalProperties":true},"kwargs":{"type":"object","description":"Additional offer configuration parameters","additionalProperties":true},"client_types":{"type":"array","description":"Client types this offer applies to","items":{"type":"string"}}},"additionalProperties":true}},"extra_data":{"type":"object","description":"Additional product data including variants. The structure of this field\ncan be extended by registered plugins. When the `products.listable_product_variants`\nplugin is active and configured, the `variants` array is populated with\nvariant information based on the plugin configuration.\n\n**Plugin Configuration:**\n- When plugins are inactive or not configured, `variants` is an empty array\n- When the `products.listable_product_variants` plugin is active, `variants`\n  contains variant groups based on the configured `attribute_keys` (e.g., \"size\",\n  \"color\")\n- The `product_field_names` setting in the plugin configuration determines\n  which fields are included in variant product objects\n\nFor more information about plugins and their configuration, see:\n[Commerce Plugins Documentation](https://docs.akinon.com/technical-guides/commerce/plugins)\n","properties":{"variants":{"type":"array","description":"Product variants grouped by attribute keys. When the\n`products.listable_product_variants` plugin is active, this array contains\nvariant groups for each configured attribute key. Each group contains options\nwith variant product details based on the plugin's `product_field_names`\nconfiguration.\n\n**Without Plugin:**\n- Returns an empty array: `[]`\n\n**With Plugin Active:**\n- Returns variant groups for each configured attribute key\n- Each group contains options with variant product information\n- Product fields included depend on the plugin's `product_field_names` setting\n","items":{"type":"object","properties":{"attribute_key":{"type":"string","description":"The attribute key that defines this variant group (e.g., \"size\", \"color\").\nOnly present when the `products.listable_product_variants` plugin is\nactive and this attribute key is configured in the plugin's `attribute_keys`.\n"},"options":{"type":"array","description":"Array of variant options for this attribute key. Each option represents\na variant product with the corresponding attribute value. The fields\nincluded in each option's `product` object depend on the plugin's\n`product_field_names` configuration (e.g., pk, price, absolute_url,\nproductimage_set, attributes).\n","items":{"type":"object","properties":{"label":{"type":"string","description":"Display label for the variant option (attribute value)"},"product":{"type":"object","description":"Variant product data. Fields included depend on the plugin's\n`product_field_names` configuration. Common fields include:\n- `pk`: Product identifier\n- `sku`: Product SKU\n- `price`: Product price\n- `retail_price`: Retail price\n- `absolute_url`: Product detail page URL\n- `productimage_set`: Product images\n- `attributes`: Product attributes\n","additionalProperties":true},"in_stock":{"type":"boolean","description":"Stock availability for this variant"},"is_selectable":{"type":"boolean","description":"Whether this variant option can be selected"}},"additionalProperties":true}}},"additionalProperties":true}}},"additionalProperties":true},"is_listable":{"type":"boolean","description":"Whether product is listable"},"listing_code":{"type":["string","null"],"description":"Product listing code"},"price_extra_field":{"type":"object","description":"Additional price field data","additionalProperties":true},"discount_amount":{"type":"number","description":"Discount amount"},"discount_ratio":{"type":"number","description":"Discount ratio"}},"additionalProperties":true},"ProductImage":{"type":"object","description":"Product image metadata","required":["pk","status","image","order","created_date"],"properties":{"pk":{"type":"integer","description":"Image identifier"},"status":{"type":"string","description":"Image status"},"image":{"type":"string","format":"uri","description":"Image URL"},"order":{"type":"integer","description":"Display order"},"created_date":{"type":"string","format":"date-time","description":"Image creation timestamp"},"specialimage_set":{"type":"array","description":"Special images associated with this image","items":{"type":"object","additionalProperties":true}}}}}}}
```

## The Widget object

```json
{"openapi":"3.1.0","info":{"title":"Search API - Product Discovery & Image Search","version":"1.0.0"},"components":{"schemas":{"Widget":{"type":"object","description":"Filter facet widget representing a filterable attribute in the search interface.\nWidgets are created during the facet conversion process after Elasticsearch\nreturns facet field data. The widget structure and behavior are controlled by\n`FacetConfiguration` database records managed via the administration interface.\n\n**Widget Type Determination:**\n- If a `FacetConfiguration` exists for the attribute, it specifies the widget type,\n  aggregation settings, and display options (name, order, widget_kwargs)\n- If no `FacetConfiguration` exists, fallback rules apply:\n  - `category_ids` always uses Category Widget\n  - `basket_offer_ids` always uses Promotion Widget\n  - All other attributes default to Multi Select Widget\n\n**Facet Configuration Properties:**\n- Widget type (multiselect, category, range, attribute_value, visual_swatch, etc.)\n- Widget kwargs (labels, sorting mode, display options)\n- Facet type and aggregation settings\n- Custom settings and display order\n- Translatable name and widget_kwargs for multi-language support\n\nFacet fields are retrieved from Elasticsearch first, before product results.\nThe facet field size (number of choices) is determined as follows:\n- If facet field has a `FacetConfiguration`, uses configured size from facet_kwargs\n- If attribute key is \"category_ids\", size is set to 500\n- Otherwise, default size is 100\n\nFacet fields are returned with inventory strategy context, as prices and\navailability may vary by inventory strategy. For multi-inventory scenarios,\nprice-related facets automatically adapt to show the active price list.\n","required":["name","key","search_key","widget_type","extra_params","data"],"properties":{"name":{"type":"string","description":"Display name of the facet shown to users"},"key":{"type":"string","description":"Facet key identifier used internally"},"search_key":{"type":"string","description":"Search parameter key used in query strings"},"widget_type":{"type":"string","description":"Widget type identifier. Determines how the filter is rendered in the UI.\nCommon types: \"category\", \"multiselect\", \"range\", \"promotion\"\n","enum":["category","multiselect","range","promotion"]},"order":{"type":["integer","null"],"description":"Display order for the widget. Lower numbers appear first. Null indicates\ndefault ordering based on attribute configuration\n"},"extra_params":{"type":"object","description":"Additional widget parameters for custom widget behavior. Used by\nFacet Configuration to pass widget-specific settings\n","additionalProperties":true},"data":{"type":"object","description":"Widget data including available choices or range values","required":["widget_type","name","key","search_key"],"properties":{"widget_type":{"type":"string","description":"Widget type identifier"},"name":{"type":"string","description":"Display name"},"key":{"type":"string","description":"Facet key identifier"},"search_key":{"type":"string","description":"Search parameter key"},"choices":{"type":"array","description":"Available filter choices (for multiselect and category widgets)","items":{"$ref":"#/components/schemas/WidgetChoice"}},"quantity":{"type":"integer","description":"Total number of matching products for this facet (for range widgets)"},"min_value":{"type":"number","description":"Minimum value in the range (for range widgets)"},"max_value":{"type":"number","description":"Maximum value in the range (for range widgets)"},"step":{"type":"number","description":"Step value for range slider (for range widgets)"},"order":{"type":["integer","null"],"description":"Display order"}},"additionalProperties":true}}},"WidgetChoice":{"type":"object","description":"Individual choice within a filter widget","required":["label","value","quantity","is_selected"],"properties":{"label":{"type":"string","description":"Display label for the choice"},"value":{"oneOf":[{"type":"integer"},{"type":"string"}],"description":"Choice value to use in filter requests"},"quantity":{"type":"integer","description":"Number of products matching this choice"},"is_selected":{"type":"boolean","description":"Whether this choice is currently active in the sorting"},"depth":{"type":"integer","description":"Category depth level (for category widgets)"},"real_depth":{"type":"integer","description":"Actual category depth in hierarchy (for category widgets)"},"url":{"type":"string","description":"URL to apply this filter (for category widgets)"},"menuitemmodel":{"type":["string","null"],"description":"Menu item model identifier (for category widgets)"},"is_parent_of_selection":{"type":"boolean","description":"Whether this category is a parent of a selected category (for category widgets)"}}}}}}
```

## The WidgetChoice object

```json
{"openapi":"3.1.0","info":{"title":"Search API - Product Discovery & Image Search","version":"1.0.0"},"components":{"schemas":{"WidgetChoice":{"type":"object","description":"Individual choice within a filter widget","required":["label","value","quantity","is_selected"],"properties":{"label":{"type":"string","description":"Display label for the choice"},"value":{"oneOf":[{"type":"integer"},{"type":"string"}],"description":"Choice value to use in filter requests"},"quantity":{"type":"integer","description":"Number of products matching this choice"},"is_selected":{"type":"boolean","description":"Whether this choice is currently active in the sorting"},"depth":{"type":"integer","description":"Category depth level (for category widgets)"},"real_depth":{"type":"integer","description":"Actual category depth in hierarchy (for category widgets)"},"url":{"type":"string","description":"URL to apply this filter (for category widgets)"},"menuitemmodel":{"type":["string","null"],"description":"Menu item model identifier (for category widgets)"},"is_parent_of_selection":{"type":"boolean","description":"Whether this category is a parent of a selected category (for category widgets)"}}}}}}
```

## The Sorter object

```json
{"openapi":"3.1.0","info":{"title":"Search API - Product Discovery & Image Search","version":"1.0.0"},"components":{"schemas":{"Sorter":{"type":"object","description":"Sorting option available for search results. Sort options are configured\nthrough the `SortOption` database model and managed via the administration\ninterface.\n\nEach sort option defines:\n- Display label (translatable for multi-language support)\n- Parameter value used in the `sorter` query parameter\n- Elasticsearch sort configuration (field paths, directions, nested queries)\n- Display order and visibility settings\n- Default status\n\nSort options are retrieved based on the current language and filtered to\nshow only visible options, ordered by default status and custom order.\nWhen a sort option is selected, its Elasticsearch configuration is applied\nto the search query. Sort options automatically adapt to inventory strategy\ncontext, adjusting price field references when multiple price lists are\nactive (e.g., `products.price_1234` instead of `products.price`).\nA secondary sort by product listing ID ensures consistent ordering across pages.\n","required":["label","value","is_selected"],"properties":{"label":{"type":"string","description":"Display label for the sort option. Retrieved from the `SortOption` model\nand supports translation for multi-language sites\n"},"value":{"type":"string","description":"Sort option value to use in the `sorter` query parameter. This value\ncorresponds to the `value` field in the `SortOption` model\n"},"is_selected":{"type":"boolean","description":"Whether this sort option is currently active based on the `sorter` query\nparameter. Only one sort option should be selected at a time\n"}}}}}}
```

## The Product object

```json
{"openapi":"3.1.0","info":{"title":"Search API - Product Discovery & Image Search","version":"1.0.0"},"components":{"schemas":{"Product":{"type":"object","description":"Product data returned in search results","required":["pk","name","sku","price","in_stock","currency_type","product_type"],"properties":{"pk":{"type":"integer","description":"Product identifier"},"name":{"type":"string","description":"Product name"},"sku":{"type":"string","description":"Product SKU"},"base_code":{"type":["string","null"],"description":"Product base code"},"attributes":{"type":"object","description":"Product attributes as key-value pairs","additionalProperties":true},"attribute_set":{"type":"integer","description":"Attribute set identifier"},"attributes_kwargs":{"type":"object","description":"Attribute metadata including labels and data types","additionalProperties":{"type":"object","properties":{"label":{"type":"string"},"value":{"type":"string"},"data_type":{"type":"string"}}}},"extra_attributes":{"type":"object","description":"Additional product attributes","additionalProperties":true},"productimage_set":{"type":"array","description":"Product images","items":{"$ref":"#/components/schemas/ProductImage"}},"price":{"type":"string","description":"Product price as stringified decimal"},"in_stock":{"type":"boolean","description":"Stock availability status"},"currency_type":{"type":"string","description":"Currency code"},"retail_price":{"type":"string","description":"Retail price as stringified decimal"},"unit_type":{"type":"string","description":"Stock unit type"},"tax_rate":{"type":"string","description":"Tax rate as stringified decimal"},"absolute_url":{"type":"string","description":"Product detail page URL"},"productvideo_set":{"type":"array","description":"Product videos","items":{"type":"object","additionalProperties":true}},"product_type":{"type":"string","description":"Product type identifier"},"price_type":{"type":"string","description":"Price type"},"form_schema":{"type":["array","null"],"description":"Form schema for product configuration","items":{"type":"object","additionalProperties":true}},"is_ready_to_basket":{"type":"boolean","description":"Whether product can be added to basket"},"stock":{"type":"integer","description":"Available stock quantity"},"data_source":{"type":["object","null"],"description":"Data source information","additionalProperties":true},"basket_offers":{"type":"array","description":"Applicable basket offers/promotions. When `OFFER_SHOW_LISTING_KWARGS` is\nenabled and the offer condition type is QUANTITY, `listing_kwargs` contains\ndiscounted pricing information for display on product listing pages.\n","items":{"type":"object","properties":{"pk":{"type":"integer","description":"Basket offer identifier"},"label":{"type":"string","description":"Display label for the offer"},"listing_kwargs":{"type":"object","description":"Listing arguments containing discounted price information. Only populated\nwhen `OFFER_SHOW_LISTING_KWARGS` is enabled and the offer has a QUANTITY\ncondition type with matching product collection. Contains:\n- `quantity`: Required quantity to qualify for the offer\n- `discounted_total_price`: Total price after discount for the specified quantity\n- `discount`: Discount amount applied\n- `data_sources`: (optional) Data source filters if applicable\n","properties":{"quantity":{"type":"integer","description":"Required quantity to qualify for the offer"},"discounted_total_price":{"type":"string","description":"Total price after discount for the specified quantity"},"discount":{"type":"string","description":"Discount amount applied"},"data_sources":{"type":"array","description":"Data source identifiers (optional, only if condition includes data_sources)","items":{"type":"integer"}}},"additionalProperties":true},"kwargs":{"type":"object","description":"Additional offer configuration parameters","additionalProperties":true},"client_types":{"type":"array","description":"Client types this offer applies to","items":{"type":"string"}}},"additionalProperties":true}},"extra_data":{"type":"object","description":"Additional product data including variants. The structure of this field\ncan be extended by registered plugins. When the `products.listable_product_variants`\nplugin is active and configured, the `variants` array is populated with\nvariant information based on the plugin configuration.\n\n**Plugin Configuration:**\n- When plugins are inactive or not configured, `variants` is an empty array\n- When the `products.listable_product_variants` plugin is active, `variants`\n  contains variant groups based on the configured `attribute_keys` (e.g., \"size\",\n  \"color\")\n- The `product_field_names` setting in the plugin configuration determines\n  which fields are included in variant product objects\n\nFor more information about plugins and their configuration, see:\n[Commerce Plugins Documentation](https://docs.akinon.com/technical-guides/commerce/plugins)\n","properties":{"variants":{"type":"array","description":"Product variants grouped by attribute keys. When the\n`products.listable_product_variants` plugin is active, this array contains\nvariant groups for each configured attribute key. Each group contains options\nwith variant product details based on the plugin's `product_field_names`\nconfiguration.\n\n**Without Plugin:**\n- Returns an empty array: `[]`\n\n**With Plugin Active:**\n- Returns variant groups for each configured attribute key\n- Each group contains options with variant product information\n- Product fields included depend on the plugin's `product_field_names` setting\n","items":{"type":"object","properties":{"attribute_key":{"type":"string","description":"The attribute key that defines this variant group (e.g., \"size\", \"color\").\nOnly present when the `products.listable_product_variants` plugin is\nactive and this attribute key is configured in the plugin's `attribute_keys`.\n"},"options":{"type":"array","description":"Array of variant options for this attribute key. Each option represents\na variant product with the corresponding attribute value. The fields\nincluded in each option's `product` object depend on the plugin's\n`product_field_names` configuration (e.g., pk, price, absolute_url,\nproductimage_set, attributes).\n","items":{"type":"object","properties":{"label":{"type":"string","description":"Display label for the variant option (attribute value)"},"product":{"type":"object","description":"Variant product data. Fields included depend on the plugin's\n`product_field_names` configuration. Common fields include:\n- `pk`: Product identifier\n- `sku`: Product SKU\n- `price`: Product price\n- `retail_price`: Retail price\n- `absolute_url`: Product detail page URL\n- `productimage_set`: Product images\n- `attributes`: Product attributes\n","additionalProperties":true},"in_stock":{"type":"boolean","description":"Stock availability for this variant"},"is_selectable":{"type":"boolean","description":"Whether this variant option can be selected"}},"additionalProperties":true}}},"additionalProperties":true}}},"additionalProperties":true},"is_listable":{"type":"boolean","description":"Whether product is listable"},"listing_code":{"type":["string","null"],"description":"Product listing code"},"price_extra_field":{"type":"object","description":"Additional price field data","additionalProperties":true},"discount_amount":{"type":"number","description":"Discount amount"},"discount_ratio":{"type":"number","description":"Discount ratio"}},"additionalProperties":true},"ProductImage":{"type":"object","description":"Product image metadata","required":["pk","status","image","order","created_date"],"properties":{"pk":{"type":"integer","description":"Image identifier"},"status":{"type":"string","description":"Image status"},"image":{"type":"string","format":"uri","description":"Image URL"},"order":{"type":"integer","description":"Display order"},"created_date":{"type":"string","format":"date-time","description":"Image creation timestamp"},"specialimage_set":{"type":"array","description":"Special images associated with this image","items":{"type":"object","additionalProperties":true}}}}}}}
```

## The ProductImage object

```json
{"openapi":"3.1.0","info":{"title":"Search API - Product Discovery & Image Search","version":"1.0.0"},"components":{"schemas":{"ProductImage":{"type":"object","description":"Product image metadata","required":["pk","status","image","order","created_date"],"properties":{"pk":{"type":"integer","description":"Image identifier"},"status":{"type":"string","description":"Image status"},"image":{"type":"string","format":"uri","description":"Image URL"},"order":{"type":"integer","description":"Display order"},"created_date":{"type":"string","format":"date-time","description":"Image creation timestamp"},"specialimage_set":{"type":"array","description":"Special images associated with this image","items":{"type":"object","additionalProperties":true}}}}}}}
```

## The AutocompleteResponse object

```json
{"openapi":"3.1.0","info":{"title":"Search API - Product Discovery & Image Search","version":"1.0.0"},"components":{"schemas":{"AutocompleteResponse":{"type":"object","description":"Autocomplete suggestions grouped by type","required":["groups"],"properties":{"groups":{"type":"array","description":"Suggestion groups","items":{"$ref":"#/components/schemas/SuggestionGroup"}}}},"SuggestionGroup":{"type":"object","description":"Group of suggestions of the same type","required":["suggestion_type","entries"],"properties":{"suggestion_type":{"type":"string","description":"Type of suggestions in this group","enum":["product","category"]},"entries":{"type":"array","description":"Suggestion entries","items":{"$ref":"#/components/schemas/SuggestionEntry"}}}},"SuggestionEntry":{"type":"object","description":"Individual search suggestion","required":["label","url","suggestion_type","extra"],"properties":{"label":{"type":"string","description":"Display label"},"url":{"type":"string","description":"URL to navigate to"},"suggestion_type":{"type":"string","description":"Type of suggestion","enum":["product","category"]},"extra":{"type":"object","description":"Additional suggestion data","properties":{"image":{"type":["string","null"],"format":"uri","description":"Product image URL (for product suggestions)"},"price":{"type":["string","null"],"description":"Product price (for product suggestions)"},"retail_price":{"type":["string","null"],"description":"Product retail price (for product suggestions)"},"product_type":{"type":"string","description":"Product type (for product suggestions)"},"parent_categories":{"type":"array","items":{"type":"string"},"description":"Parent category names (for category suggestions)"},"category_id":{"type":"integer","description":"Category identifier (for category suggestions)"}},"additionalProperties":true}}}}}}
```

## The SuggestionGroup object

```json
{"openapi":"3.1.0","info":{"title":"Search API - Product Discovery & Image Search","version":"1.0.0"},"components":{"schemas":{"SuggestionGroup":{"type":"object","description":"Group of suggestions of the same type","required":["suggestion_type","entries"],"properties":{"suggestion_type":{"type":"string","description":"Type of suggestions in this group","enum":["product","category"]},"entries":{"type":"array","description":"Suggestion entries","items":{"$ref":"#/components/schemas/SuggestionEntry"}}}},"SuggestionEntry":{"type":"object","description":"Individual search suggestion","required":["label","url","suggestion_type","extra"],"properties":{"label":{"type":"string","description":"Display label"},"url":{"type":"string","description":"URL to navigate to"},"suggestion_type":{"type":"string","description":"Type of suggestion","enum":["product","category"]},"extra":{"type":"object","description":"Additional suggestion data","properties":{"image":{"type":["string","null"],"format":"uri","description":"Product image URL (for product suggestions)"},"price":{"type":["string","null"],"description":"Product price (for product suggestions)"},"retail_price":{"type":["string","null"],"description":"Product retail price (for product suggestions)"},"product_type":{"type":"string","description":"Product type (for product suggestions)"},"parent_categories":{"type":"array","items":{"type":"string"},"description":"Parent category names (for category suggestions)"},"category_id":{"type":"integer","description":"Category identifier (for category suggestions)"}},"additionalProperties":true}}}}}}
```

## The SuggestionEntry object

```json
{"openapi":"3.1.0","info":{"title":"Search API - Product Discovery & Image Search","version":"1.0.0"},"components":{"schemas":{"SuggestionEntry":{"type":"object","description":"Individual search suggestion","required":["label","url","suggestion_type","extra"],"properties":{"label":{"type":"string","description":"Display label"},"url":{"type":"string","description":"URL to navigate to"},"suggestion_type":{"type":"string","description":"Type of suggestion","enum":["product","category"]},"extra":{"type":"object","description":"Additional suggestion data","properties":{"image":{"type":["string","null"],"format":"uri","description":"Product image URL (for product suggestions)"},"price":{"type":["string","null"],"description":"Product price (for product suggestions)"},"retail_price":{"type":["string","null"],"description":"Product retail price (for product suggestions)"},"product_type":{"type":"string","description":"Product type (for product suggestions)"},"parent_categories":{"type":"array","items":{"type":"string"},"description":"Parent category names (for category suggestions)"},"category_id":{"type":"integer","description":"Category identifier (for category suggestions)"}},"additionalProperties":true}}}}}}
```

## The ImageSearchRequest object

```json
{"openapi":"3.1.0","info":{"title":"Search API - Product Discovery & Image Search","version":"1.0.0"},"components":{"schemas":{"ImageSearchRequest":{"type":"object","description":"Request payload for base64 image search","required":["image"],"properties":{"image":{"type":"string","description":"Base64-encoded image data. Must be a valid image format (JPEG, PNG, etc.).\nThe decoded image must be smaller than the configured maximum file size\nand have dimensions less than the configured maximum.\n"},"excluded_product_ids":{"type":"array","description":"Product identifiers to exclude from results","items":{"type":"integer"}},"text":{"type":"string","description":"Optional text keywords to refine the image search","maxLength":5000}}}}}}
```

## The ImageSearchResponse object

```json
{"openapi":"3.1.0","info":{"title":"Search API - Product Discovery & Image Search","version":"1.0.0"},"components":{"schemas":{"ImageSearchResponse":{"type":"object","description":"Image search results","required":["product_ids"],"properties":{"product_ids":{"type":"array","description":"List of product identifiers matching the image","items":{"type":"integer"}}}}}}}
```

## The ErrorResponse object

```json
{"openapi":"3.1.0","info":{"title":"Search API - Product Discovery & Image Search","version":"1.0.0"},"components":{"schemas":{"ErrorResponse":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string","description":"Error message"}}}}}}
```

## The ValidationErrorResponse object

```json
{"openapi":"3.1.0","info":{"title":"Search API - Product Discovery & Image Search","version":"1.0.0"},"components":{"schemas":{"ValidationErrorResponse":{"type":"object","description":"Validation error response","additionalProperties":{"type":"array","items":{"type":"string"}}}}}}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://apidocs.akinon.com/commerce-openapis/search/models.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
