OCTO_API_KEY, and you can list catalogs, search products by keyword and facet, and look up any product by URL — all backed by Pydantic models so your IDE can autocomplete every field.
Installation
Install the package
Requires Python 3.11 or later. The SDK ships from the public Run your code against the synced environment with
octogen-dev repository and is managed with uv. Clone the repository and sync the sdks/python project:uv run --project sdks/python python your_script.py, or activate it with source sdks/python/.venv/bin/activate.Set your API key
The client reads your key from the You can also pass
OCTO_API_KEY environment variable automatically.api_key= directly to the constructor if you prefer to manage secrets yourself (see Authentication below).Authentication
OctogenClient resolves your API key in this order:
- The
api_keyconstructor argument, if provided. - The
OCTO_API_KEYenvironment variable.
MissingAPIKeyError immediately — before any network request is made. Every request then sends the key as Authorization: Bearer <api-key>.
Client constructor
OctogenClient accepts the following keyword-only arguments:
| Parameter | Type | Default | Description |
|---|---|---|---|
api_key | str | None | None (reads OCTO_API_KEY) | Your Platform API key. |
base_url | str | https://api.octogen.ai/v1 | Override the API base URL (useful for testing). |
timeout | float | httpx.Timeout | 30.0 | Request timeout in seconds, or a full httpx.Timeout object. |
http_client | httpx.AsyncClient | None | None (SDK creates one) | Supply your own httpx.AsyncClient to reuse connections or configure proxies. |
Using the client as an async context manager
Useasync with to ensure the underlying HTTP connection pool is closed when you are done:
await client.aclose() when finished.
Methods
list_catalogs
catalog from search_products to search all of them, or pass a catalog value to restrict search to one catalog.
list[MerchantCatalogSummary]
Each MerchantCatalogSummary has:
| Field | Type | Description |
|---|---|---|
catalog | str | Catalog identifier — pass this to search_products when you want to search only this catalog. |
display_name | str | Human-readable catalog name. |
product_count | int | Number of indexed products. |
source_base_url | str | None | Base URL of the catalog source. |
last_indexed_at | datetime | None | When the catalog was last indexed. |
lookup_product
MerchantProductUrlLookupResponse
| Field | Type | Description |
|---|---|---|
catalog_key | str | Catalog the product belongs to. |
catalog_display_name | str | Human-readable catalog name. |
product | MerchantProductView | Full product record with all detail fields. |
search_products
catalog only when you want to restrict search to one catalog.
| Parameter | Type | Default | Description |
|---|---|---|---|
catalog | str | None | None | Optional catalog identifier from list_catalogs(). Omit to search all granted catalogs. |
q | str | None | None | Keyword search query. |
facets | Sequence[Facet | dict] | None | None | List of facet filters to apply. See Faceted search. |
price_min | float | None | None | Minimum price filter (inclusive). |
price_max | float | None | None | Maximum price filter (inclusive). |
cursor | str | None | None | Pagination cursor from a previous response’s next_cursor. |
limit | int | 50 | Number of results per page. Must be between 1 and 100. |
MerchantProductListPage
| Field | Type | Description |
|---|---|---|
items | list[MerchantProductListItem] | Products on this page. |
next_cursor | str | None | Pass as cursor in your next call to get the next page. None means no more results. |
MerchantProductListItem includes uuid, product_url, title, brand, current_price, original_price, image_url, images, rating, and updated_at.
Complete example
The following example confirms that catalogs are available, searches all granted catalogs for women’s linen dresses, and prints each result with its brand and price:Faceted search
UseFacet objects to filter by brand, gender, color, category, and other attributes. Pass a list of facets to the facets parameter of search_products.
Facet instances — the SDK coerces them automatically:
Pagination
Whennext_cursor is not None in a response, pass it as cursor in your next call to retrieve the following page:
Error handling
All SDK errors inherit fromOctogenError. HTTP errors inherit from OctogenAPIError, which exposes status_code, detail, and response attributes.
OctogenAuthenticationError — 401
OctogenAuthenticationError — 401
Raised when your API key is missing, malformed, or has been revoked. Check that
OCTO_API_KEY is set correctly and that the key is still active in the partner portal.OctogenForbiddenError — 403
OctogenForbiddenError — 403
Raised when a valid key attempts an action it is not authorized for — for example, accessing a catalog that has not been granted to your organization.
OctogenNotFoundError — 404
OctogenNotFoundError — 404
Raised when a catalog or product URL cannot be found. For
lookup_product, verify the URL belongs to a catalog your key can access.OctogenValidationError — 422
OctogenValidationError — 422
Raised when the API rejects a request due to invalid parameters. The
detail attribute contains the validation error list from the API.OctogenConnectionError
OctogenConnectionError
Raised when the SDK cannot reach the API — for example, due to a network timeout or DNS failure. Does not have a
status_code.OctogenAPIError to handle all HTTP errors in one place:
BigQuery subscribe (optional)
If Octogen shares a catalog with you over BigQuery Analytics Hub, the SDK can subscribe to the listing and create a linked dataset in your own Google Cloud project, so you can query the catalog with SQL. See the Subscribe to a catalog in BigQuery guide for the full walkthrough. This helper uses your Google Cloud Application Default Credentials — not yourOCTO_API_KEY — so it lives behind an optional bigquery extra. Sync it from the octogen-dev repository:
octogen-bq-subscribe CLI (dry-run by default; --apply to subscribe) and the octogen-bq-autosubscribe cron helper for keeping linked datasets current as new listings become available:
subscribe_to_listing
OctogenClient). Idempotent — an existing subscription to the same listing in destination_project is returned as-is.
| Parameter | Type | Default | Description |
|---|---|---|---|
listing_resource | str | — | Listing resource name from the Platform UI BigQuery sharing page or MCP list_bigquery_listing_resources tool. |
destination_project | str | — | Destination GCP project for the linked dataset (must be yours). |
destination_dataset_id | str | None | octogen_<listing-id> | Linked dataset id. |
location | str | None | The listing’s location | BigQuery dataset location. |
friendly_name | str | None | None | Linked dataset display name. |
credentials | google.auth.credentials.Credentials | None | None (uses ADC) | Explicit Google credentials, if you don’t want to use ADC. |
BigQuerySubscriptionResult with listing_resource, linked_project, linked_dataset, state, already_subscribed, subscription_name, and a ready-to-run sample_query.
Two BigQuery error types extend
OctogenError: OctogenBigQueryError (base) and OctogenBigQueryAccessPendingError, raised when Octogen’s IAM grant on the listing hasn’t propagated yet. Because the grant is asynchronous, catch the access-pending error and retry after a few minutes.