Skip to main content
This guide walks you through making your first calls to the Octogen Platform Catalog API. By the end, you will have listed your granted catalogs, searched for products, and resolved a product page URL to a full product record — using curl, the Python SDK, or the TypeScript SDK.

Prerequisites

Before you start, make sure you have:
  • A Catalog Partner organization provisioned by Octogen
  • A Platform API key from the partner portal (see Authentication)
  • At least one catalog granted to your organization
1

Set your API key

Export your API key so it’s available to all three methods below:
export OCTO_API_KEY="octo_live_<your-key>"
The Python and TypeScript SDKs read OCTO_API_KEY from the environment automatically. You can also pass the key directly to the client constructor — see Authentication for details.
2

List your catalogs

Retrieve the catalogs your organization has been granted access to. You can search all of these catalogs by omitting catalog from the search request, or pass a catalog value to restrict search to one catalog.
curl -sS https://api.octogen.ai/v1/catalogs \
  -H "Authorization: Bearer $OCTO_API_KEY"
import asyncio
from octogen_ai_sdk import OctogenClient

async def main():
    async with OctogenClient() as client:
        catalogs = await client.list_catalogs()
        for c in catalogs:
            print(c.catalog, "-", c.display_name)

asyncio.run(main())
import { OctogenClient } from "@octogen-ai/sdk";

const client = new OctogenClient();
const catalogs = await client.listCatalogs();
for (const c of catalogs) {
  console.log(c.catalog, "-", c.displayName);
}
Example response:
[
  {
    "catalog": "warrenlotas",
    "displayName": "Warren Lotas",
    "sourceBaseUrl": "https://warrenlotas.com",
    "productCount": 1248,
    "lastIndexedAt": "2026-05-19T18:04:10Z"
  }
]
An empty array means your organization has no active catalog grants. Contact Octogen to have catalogs assigned to your account.
3

Search products

Search for products across all granted catalogs using a keyword query. To restrict search to one catalog, pass a catalog value from the previous step.
curl -sS https://api.octogen.ai/v1/products/search \
  -H "Authorization: Bearer $OCTO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "q": "women'\''s linen summer dresses",
    "limit": 5
  }'
import asyncio
from octogen_ai_sdk import OctogenAPIError, OctogenClient

async def main():
    try:
        async with OctogenClient() as client:
            catalogs = await client.list_catalogs()
            if not catalogs:
                print("No catalogs are available for this API key.")
                return

            results = await client.search_products(
                q="women's linen summer dresses",
                limit=5,
            )

            print("Catalog scope: all granted catalogs")
            for product in results.items:
                brand = product.brand.name if product.brand else "Unknown brand"
                price = (
                    f"${product.current_price:.2f}"
                    if product.current_price is not None
                    else "Price unavailable"
                )
                title = product.title or "Untitled product"
                print(f"- {title} | {brand} | {price}")
                print(f"  {product.product_url}")
    except OctogenAPIError as exc:
        print(f"Octogen API error: status={exc.status_code}")
        raise

asyncio.run(main())
import { OctogenAPIError, OctogenClient } from "@octogen-ai/sdk";

try {
  const client = new OctogenClient();
  const catalogs = await client.listCatalogs();
  if (catalogs.length === 0) {
    console.log("No catalogs are available for this API key.");
    process.exit(0);
  }

  const results = await client.searchProducts({
    q: "women's linen summer dresses",
    limit: 5,
  });

  console.log("Catalog scope: all granted catalogs");
  for (const product of results.items) {
    const brand = product.brand?.name ?? "Unknown brand";
    const price =
      product.currentPrice == null
        ? "Price unavailable"
        : `$${product.currentPrice.toFixed(2)}`;
    console.log(`- ${product.title ?? "Untitled product"} | ${brand} | ${price}`);
    console.log(`  ${product.productUrl}`);
  }
} catch (error) {
  if (error instanceof OctogenAPIError) {
    console.error(`Octogen API error: status=${String(error.statusCode)}`);
  }
  throw error;
}
The response includes an items array and a nextCursor field for pagination. When nextCursor is non-null, pass it as cursor in your next request (with the same filters) to fetch the next page.
4

Look up a product by URL

Resolve any product page URL to its full canonical record — including pricing, sizing, images, and variants.
curl -sS https://api.octogen.ai/v1/products/lookup \
  -H "Authorization: Bearer $OCTO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://warrenlotas.com/products/black-hoodie"}'
import asyncio
from octogen_ai_sdk import OctogenClient

async def main():
    async with OctogenClient() as client:
        result = await client.lookup_product(
            "https://warrenlotas.com/products/black-hoodie"
        )
        product = result.product
        print(f"{product.title} — ${product.current_price:.2f}")
        print(f"In stock: {product.in_stock}")
        print(f"Sizes: {product.sizes}")

asyncio.run(main())
import { OctogenClient } from "@octogen-ai/sdk";

const client = new OctogenClient();
const result = await client.lookupProduct(
  "https://warrenlotas.com/products/black-hoodie"
);
const { product } = result;
console.log(`${product.title} — $${product.currentPrice?.toFixed(2)}`);
console.log(`In stock: ${product.inStock}`);
console.log(`Sizes: ${product.sizes?.join(", ")}`);
The lookup response includes the full product record with optional fields such as variants, categories, colors, reviews, promotions, and identifiers when the underlying catalog record has them.
The URL you pass must belong to a catalog granted to your organization. A URL from an unrecognized domain or an ungranted catalog returns a 404 error.

Next steps

  • Filter searches — use facets, price_min, and price_max to narrow results. See Catalog search.
  • Find similar products — use a product URL or UUID as the source for More Like This recommendations. See More Like This.
  • Paginate results — use the nextCursor field to fetch subsequent pages. See Pagination.
  • Handle errors — understand 401, 403, 404, and 422 responses. See Error handling.
  • Connect an AI agent — use the Catalog Partner MCP server to give Claude or Codex direct catalog access. See MCP overview.