Skip to main content

Documentation Index

Fetch the complete documentation index at: https://www.octogen.ai/docs/llms.txt

Use this file to discover all available pages before exploring further.

POST /products/search lets you search and browse products within a single catalog your organization has been granted access to. You can combine a free-text query (q) with structured facet filters, price range bounds, and a pagination cursor. The response returns a page of MerchantProductListItem objects and an opaque nextCursor for advancing through results.

Request

POST https://api.octogen.ai/v1/products/search
Authorization: Bearer <your-platform-api-key>
Content-Type: application/json

Body parameters

catalog
string
required
Key of the catalog to search. Must be a catalog currently granted to your organization. Retrieve available keys from GET /catalogs. Cross-catalog search is not supported — issue separate requests for each catalog.
q
string
Free-text keyword query. Omit or set to null to browse the catalog without keyword filtering. Can be combined with facets and price filters.
facets
Facet[]
Array of structured facet filters. Each facet has a name and a values array. Multiple facets are ANDed; multiple values within a facet are ORed.
[
  {"name": "color_family", "values": ["Black", "Gray"]},
  {"name": "gender", "values": ["female"]}
]
See Facet names below for the full list of supported names.
price_min
number
Inclusive minimum price filter. Only products with currentPrice >= price_min are returned.
price_max
number
Inclusive maximum price filter. Only products with currentPrice <= price_max are returned.
cursor
string
Opaque pagination cursor from a previous response’s nextCursor field. Pass this value — unmodified — along with the same filters to retrieve the next page. Omit on the first request.
limit
integer
default:"50"
Number of products to return per page. Accepted range: 1–100. Defaults to 50.

Example

curl -sS https://api.octogen.ai/v1/products/search \
  -H "Authorization: Bearer $OCTOGEN_PLATFORM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "catalog": "warrenlotas",
    "q": "black hoodie",
    "facets": [
      {"name": "color_family", "values": ["Black"]},
      {"name": "gender", "values": ["male", "unisex"]}
    ],
    "price_min": 50,
    "price_max": 300,
    "limit": 25
  }'

Response

items
MerchantProductListItem[]
required
The current page of product results. See the Product model for the full field reference.
nextCursor
string | null
Opaque cursor for the next page of results. Pass as cursor on your next request with the same filters. null when you have reached the last page.

Example response

{
  "items": [
    {
      "uuid": "prod_01HX...",
      "title": "Black Hoodie",
      "productUrl": "https://warrenlotas.com/products/black-hoodie",
      "imageUrl": "https://cdn.example.com/black-hoodie.jpg",
      "images": ["https://cdn.example.com/black-hoodie.jpg"],
      "brand": {"name": "Warren Lotas", "slug": "warren-lotas", "url": null},
      "currentPrice": 180,
      "originalPrice": null,
      "rating": null,
      "updatedAt": "2026-05-19T18:04:10Z"
    }
  ],
  "nextCursor": "eyJzZWFyY2hBZnRlciI6Wy4uLl19"
}

Facet names

Use these values for the name field in each facet object. Facet values should be lowercase; phrase values may contain spaces.
Facet nameDescription
brand_nameCanonical brand display name.
brand_slugURL-safe brand identifier.
product_typeProduct type classification (e.g. "hoodie", "sneaker").
genderTarget gender: male, female, or unisex.
age_groupsTarget age group: infant, toddler, kids, or adult.
colorSpecific color label as indexed from the merchant.
color_familyNormalized color family: Black, Blue, Brown, Gray, Green, Orange, Pink, Purple, Red, White, Yellow.
category_path.depth_0Top-level category.
category_path.depth_1Second-level category.
category_path.depth_2Third-level category.
category_path.depth_3Fourth-level category.
category_path.depth_4Fifth-level category.
category_path.depth_5Sixth-level category.
category_path.depth_6Seventh-level category.
You can also filter on dynamic product attribute facets by passing the bare attribute key (e.g. fit) or its fully qualified form (e.g. attribute_facets.fit).

Pagination

For a detailed walkthrough of cursor-based pagination, see Pagination guide.
Advance through pages by repeating your request with the same filters and the cursor value from the previous response:
  1. Send your initial search request with the desired filters and an optional limit.
  2. If nextCursor is non-null in the response, send a new request with cursor set to that value and all other fields unchanged.
  3. Repeat until nextCursor is null.
Cursors are opaque — do not parse or construct them. They encode internal continuation state and may change shape across releases.

SDK equivalents

import asyncio
from octogen_ai_sdk import OctogenClient
from octogen_ai_sdk.models import Facet

async def main() -> None:
    async with OctogenClient() as client:
        cursor = None
        while True:
            page = await client.search_products(
                catalog="warrenlotas",
                q="black hoodie",
                facets=[
                    Facet(name="color_family", values=["Black"]),
                    Facet(name="gender", values=["male", "unisex"]),
                ],
                price_min=50,
                price_max=300,
                limit=25,
                cursor=cursor,
            )
            for product in page.items:
                print(product.title, product.current_price)
            if page.next_cursor is None:
                break
            cursor = page.next_cursor

asyncio.run(main())