> ## Documentation Index
> Fetch the complete documentation index at: https://docs.omnicommerce.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Catalog queries and durable operations

> Query matching SKUs on the server, submit durable price and cost updates, and inspect compact progress and paginated evidence.

Available in TypeScript SDK 0.21.0, Python SDK 0.16.0 and CLI 0.12.0. These methods use the authenticated organization's canonical catalog and marketplace services.

## Query matching products and variants

`catalog.query` defaults to active sellable SKUs. Parent containers are excluded, and variants do not need separate lookups. Select the fields needed for the task and use cursor pagination for matching rows. IDs and currency companions of monetary fields are always included. Maximum page size: 500.

```python theme={null}
page = client.catalog.query(
    filters={"statuses": ["active"], "costComparison": "above_price"},
    fields=["id", "sku", "price", "currency", "cost", "costCurrency", "updatedAt"],
    limit=500,
)["data"]
```

```typescript theme={null}
const page = await client.catalog.query({
  filters: { statuses: ["active"], costComparison: "above_price" },
  fields: [
    "id",
    "sku",
    "price",
    "currency",
    "cost",
    "costCurrency",
    "updatedAt",
  ],
  limit: 500,
});
```

Supported filters also include exact `productIds`, `skus`, and `currencies`. Set `sellableOnly: false` to include parent containers. These are catalog statuses, independent of marketplace listing status. Read-only credentials require `catalog:read`.

`matchedCount` counts the full filtered selection. Continue with `nextCursor`, the same filters/fields, and `includeCount: false` (`include_count=False` in Python) to avoid repeating the count. `hasMore: true` means the selection is incomplete.

Cost comparisons use each product's catalog currency and valid recorded conversions. Missing costs and unavailable conversions are excluded and counted in `diagnostics`. Original `cost` and `costCurrency` are preserved; select `costInCatalogCurrency` and `costConversion` for the comparison amount and FX evidence. Currency conversion does not authorize swapping raw amounts between different currencies.

## Submit a durable update

Supply 1–2,000 simple-product or variant updates in one request. Each entry can atomically set price and cost. Include the queried `expectedUpdatedAt` to reject changes made after review. Identical duplicates collapse in requested order; conflicting duplicates are rejected.

```python theme={null}
accepted = client.bulk.start(
    idempotency_key=operation_key,
    updates=reviewed_updates,
    sync_to_marketplaces=True,
    verify=True,
)["data"]
operation_ids = accepted["operationIds"]
```

```typescript theme={null}
const accepted = await client.bulk.start({
  idempotencyKey: operationKey,
  updates: reviewedUpdates,
  syncToMarketplaces: true,
  verify: true,
});
const operationIds = accepted.data.operationIds;
```

Nested update keys stay camelCase in both languages: `productId`, `price`, `salePrice`, `currency`, `costPrice`, `costPriceCurrency`, and `expectedUpdatedAt`. Optional `targets: [{ platform, accountId }]` selects up to 25 exact connected stores for that update; omitted targets select all eligible listings. Setting `costPrice` to null clears it. Cost remains in Omni and never publishes to marketplaces. Existing eligible marketplace listings use the shared publishing and pricing rules when price sync is requested; this operation does not create new listings.

The default is `syncToMarketplaces: false` and `verify: true`. Requires `catalog:write`; status and state reads require `catalog:read`.

Reuse the same idempotency key with identical input after a transport failure. It retains the original targets and versions. Changed input with that key returns 409. Save operation IDs and let the submitting process finish: accepted work continues after disconnection. Per-target failures do not abort independent targets. Inspect saved receipts before retrying a failed target.

## Read progress and evidence

```python theme={null}
progress = client.bulk.status(operation_ids=operation_ids)["data"]
failures = client.bulk.results(
    operation_ids=operation_ids, status="failed", limit=25,
)["data"]
```

```typescript theme={null}
const progress = await client.bulk.status({ operationIds });
const failures = await client.bulk.results({
  operationIds,
  status: "failed",
  limit: 25,
});
```

Status accepts up to 50 operation IDs and returns ordered aggregate counts and phases. Pending work is incomplete. `success` requires every requested target to succeed; partial failure remains explicit. `verifiedCount` distinguishes confirmed states from writes submitted with verification disabled.

The outer status counts refer to operations. Each entry in `results` contains that operation's product counts.

Reports retain ordered per-target receipts, job IDs, errors and verification evidence. They return at most 100 rows per page across the requested operations. Continue with the numeric `nextCursor` and the same filters. Operation IDs belong in `bulk.status`, while ordinary job correlations retain their existing APIs.

For a new attempt after a terminal failure, review the current catalog values, use a new idempotency key, and select only the failed stores in `targets`. Reuse the saved absolute price/cost assignments when still correct; do not recalculate a swap from values already changed by the first operation. The old key continues to identify the original operation.

Delegated Computer requests automatically link to their authenticated chat. Linked operations appear in Runs and continue the conversation on completion, subject to current access, explicit stops and pending interactions. Other clients may supply an owned `sessionId` or retrieve status later.

## Durable verification

Use `commerce.start_verification(idempotency_key=..., verification={"targets": [...]})` in Python or `commerce.startVerification({ idempotencyKey, verification: { targets } })` in TypeScript for up to 2,000 product targets. The nested verification request uses the existing product verification contract. Read its returned operation IDs through `bulk.status` and `bulk.results`.

Targets must exist and be accessible at submission. Use the existing `commerce.verifyState` / `commerce.verify_state` API for already deleted products and fulfillment correlations.

Product price verification uses exact acknowledged marketplace prices matching the expected catalog amount and currency, including channel markups. Product, store, country and currency identities remain distinct. Missing evidence or a mismatched state remains a failure.

## CLI

```bash theme={null}
omni catalog query --json - < catalog-query.json
omni bulk start --json - < reviewed-updates.json
omni bulk status --json - < operation-ids.json
omni bulk results --json - < failed-results-request.json
omni commerce start-verification --json - < verification-request.json
```


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