> ## 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.

# Get started with StoreRouter in minutes

> Go from zero to your first product search result: set up your API key, search active crawled catalogs, and look up a product by URL.

This guide walks you through making your first calls to the StoreRouter Platform Catalog API. By the end, you will have searched 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 **Developer organization** provisioned by StoreRouter
* A **Platform API key** from StoreRouter Platform (see [Authentication](/docs/authentication))

<Steps>
  <Step title="Set your API key">
    Export your API key so it's available to all three methods below:

    ```bash theme={null}
    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](/docs/authentication) for details.
  </Step>

  <Step title="Search products">
    Search every active crawled catalog using a keyword query. Omit `catalog` for policy-wide search, or pass a known active crawled catalog key to restrict the request.

    <CodeGroup>
      ```bash curl theme={null}
      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
        }'
      ```

      ```python Python theme={null}
      import asyncio
      from octogen_ai_sdk import OctogenAPIError, OctogenClient

      async def main():
          try:
              async with OctogenClient() as client:
                  results = await client.search_products(
                      q="women's linen summer dresses",
                      limit=5,
                  )

                  print("Catalog scope: all active crawled 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"StoreRouter API error: status={exc.status_code}")
              raise

      asyncio.run(main())
      ```

      ```typescript TypeScript theme={null}
      import { OctogenAPIError, OctogenClient } from "@octogen-ai/sdk";

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

        console.log("Catalog scope: all active crawled 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(`StoreRouter API error: status=${String(error.statusCode)}`);
        }
        throw error;
      }
      ```
    </CodeGroup>

    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.
  </Step>

  <Step title="Look up a product by URL">
    Resolve any product page URL to its full product record — including pricing, sizing, images, and variants.

    <CodeGroup>
      ```bash curl theme={null}
      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"}'
      ```

      ```python Python theme={null}
      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())
      ```

      ```typescript TypeScript theme={null}
      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(", ")}`);
      ```
    </CodeGroup>

    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.

    <Note>
      The URL you pass must belong to an active crawled catalog. A URL from an unrecognized domain or unavailable catalog returns a `404` error.
    </Note>
  </Step>
</Steps>

## Next steps

* **Filter searches** — use `facets`, `price_min`, and `price_max` to narrow results. See [Catalog search](/docs/guides/catalog-search).
* **Find similar products** — use a product URL or UUID as the source for More Like This recommendations. See [More Like This](/docs/guides/more-like-this).
* **Paginate results** — use the `nextCursor` field to fetch subsequent pages. See [Pagination](/docs/guides/pagination).
* **Handle errors** — understand `401`, `402`, `403`, `404`, and `422` responses. See [Error handling](/docs/guides/error-handling).
* **Understand pricing** — see [API pricing and billing](/docs/guides/pricing-and-billing) for request prices, prepaid credit, and payments.
* **Connect an AI agent** — use the Developer MCP server to give Claude or Codex direct catalog access. See [MCP overview](/docs/mcp/overview).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.