Skip to main content
Use the dedicated catalog endpoints when an integration needs to change commercial values:
productId may be a simple-product UUID or a variant UUID. For a product with variants, update each variant rather than the parent product. GET /api/v1/products/{productId} on the parent returns the variant UUIDs in variants.

Authentication and organization scope

These endpoints require a bearer credential with catalog:write. OmniCommerce derives organizationId from the credential. Do not include an organization ID in the request body.

Price and inventory: Omni only

Marketplace synchronization is opt-in. Omitting syncToMarketplaces, or setting it to false, changes the OmniCommerce catalog without writing to a marketplace.

Price and inventory: synchronize marketplaces

Set syncToMarketplaces to true to queue durable marketplace work. Without a targets array, OmniCommerce queues all enabled and published accounts attached to the product. To limit the write, pass exact account targets:
OmniCommerce validates every explicit { platform, accountId } pair against the product’s enabled, published marketplace accounts before changing the catalog. An unknown, disabled, or unpublished target rejects the entire request.

Cost: Omni only

Catalog cost is never pushed to marketplaces. Do not send syncToMarketplaces on the cost endpoints. Store the source amount and currency. Omni does not convert the catalog amount into the selling currency. When costPriceCurrency differs from the product selling currency and costPriceFxRate is omitted, Omni quotes FX and stores the quote on the product. Prefer the batch endpoint for jobs. Each item targets productId or sku (Omni products.sku). You may send both when they refer to the same product. Maximum 200 updates per request.
Single-product sibling:
A successful cost write stores product_data.costPrice, product_data.costPriceCurrency, and when currencies differ costPriceFxRate, costPriceFxFrom, costPriceFxTo, costPriceFxAsOf, and costPriceFxSource (frankfurter or manual). Approximate fallback rates are rejected; pass costPriceFxRate or retry. The batch response is 200 even when some rows fail. Top-level success is true only when every update succeeded. Duplicate product IDs or SKUs fail after the first occurrence. Unknown SKUs return SKU does not match an active, draft, or archived product.

List products, then write cost

To backfill cost for every listing on one marketplace, page the product list first, keep { id, sku }, then POST cost in chunks of 200.
sku is an exact products.sku match after trim. It is not the fuzzy q search. Repeat sku or comma-separate up to 50 values. Combined with marketplace and other filters using AND. Follow pagination.nextOffset until hasMore is false. limit max is 50. Use productId from the list on the cost write so you do not resolve SKU twice. API-key and OAuth requests take organizationId from the bearer credential. Do not send organizationId on these URLs.

Async response and job status

A marketplace price or inventory sync request returns 202 Accepted. jobIds contains the durable jobs, and targets shows the immediate queue status for each account.
Poll each returned job with:
Inventory returns one durable outbox job per marketplace account. Price updates return a durable batch job whose counters cover all target accounts. Cost writes return 200 and do not create marketplace jobs.

Webhook events

The local catalog transaction and outbound marketplace work are separate. A successful local value change emits:
  • product.price.changed for price, sale-price, currency, or catalog cost changes (changedFields includes costPrice for cost writes)
  • product.inventory.changed for on-hand quantity changes
  • product.updated for the same catalog transaction
Subscribe through the Webhooks API and see the normalized product webhook payloads. Marketplace job completion is tracked through the job endpoint; it does not create a second catalog-change webhook.

Source ownership safeguards

The endpoints keep the same catalog rules as the OmniCommerce workspace:
  • ERP-managed selling price or inventory must be changed in the ERP. Cost-only writes are allowed on ERP-managed products.
  • Multi-source inventory must be changed through its source/location workflow.
  • A sale price must remain below the list price.
  • Active promotion assignments may prevent direct sale-price changes.
Use GET /api/v1/products or GET /api/v1/catalog/items with catalog:read to discover product and variant UUIDs, SKUs, pricing guardrail inputs, promotion context, and exact published marketplace identities before writing.