Skip to content
ShopAssist Docs
InstallOther sites (Generic)

Catalog Push API

Push products, categories, locations, stock and pages from your server in idempotent batches, including full replace_all runs.

Applies to: GenericView as Markdown

The Catalog Push API lets your server send catalog changes as they happen. It is available on every plan.

Authentication

Create an API key in Developers → API keys with the scope catalog:write, restricted to the store. Send it as Authorization: Bearer sa_live_… from your server only; never put it in a browser. See authentication.

Endpoints

POST/v1/stores/{store_id}/catalog/products:batchScope catalog:write

POST/v1/stores/{store_id}/catalog/products:deleteScope catalog:write

POST/v1/stores/{store_id}/catalog/categories:batchScope catalog:write

POST/v1/stores/{store_id}/catalog/locations:batchScope catalog:write

POST/v1/stores/{store_id}/catalog/inventory:batchScope catalog:write

POST/v1/stores/{store_id}/catalog/pages:batchScope catalog:write

Field reference: API reference → Catalog Push API. The locations:batch and inventory:batch endpoints also work for Magento, WooCommerce and PrestaShop stores that send store stock by feed.

Batches

  • At most 500 items per batch and 5 MB per request; 120 batches per minute per store.
  • Every batch needs an Idempotency-Key header. Retrying with the same key returns the original response; reusing a key with a different body fails with 422 idempotency_key_reused. Generate a new key for each new batch and reuse it only for retries of that batch.
  • The answer is 202 Accepted with accepted, rejected (index and error per invalid item) and a sync_run_id. Valid items are processed even when others are rejected.
  • Batches of one store are applied in the order they were received.
curl -X POST "https://api.shopassist.coec.dk/v1/stores/sto_.../catalog/products:batch" \
  -H "Authorization: Bearer $SHOPASSIST_API_KEY" \
  -H "Idempotency-Key: 7f9c3a12-batch-0001" \
  -H "Content-Type: application/json" \
  -d '{"products":[{"external_id":"SHIRT-42","title":"Linen shirt","url":"https://shop.example.com/products/linen-shirt",
       "variants":[{"external_id":"SHIRT-42-BLUE","sku":"SHIRT-42-BLUE","price":{"amount":"499.00","currency":"DKK"},"available_qty":12}]}]}'

Prices are decimal strings in the store currency. Product URLs must be HTTPS on one of your allowed domains (url_not_allowed otherwise).

Full replace runs

To replace the whole catalog (products you no longer send are removed), push all products as one run:

  • every batch carries mode: "replace_all", the same run_id (up to 64 characters, A–Z a–z 0–9 _ -) and a batch_index starting at 0;
  • the last batch carries is_last_batch: true.

When all batches up to the last index have arrived, ShopAssist removes products that were not in the run. If that would remove more than half of the catalog, it stops and asks for confirmation in the dashboard. A run that is incomplete six hours after its first batch fails and removes nothing (push_run_incomplete). A batch for a finished run is refused (409 conflict, reason run_closed).

Errors

ResponseMeaning
202 with rejected[]Some items were invalid: validation_error, currency_mismatch, duplicate_external_id, too_many_variants, url_not_allowed
409 conflict (feed_authoritative)A full primary feed is enabled for this store
409 conflict (run_closed)The replace_all run already finished
403 forbidden (test_key)Test keys cannot write
429 rate_limitedWait for Retry-After seconds

All error codes: API errors.

Order reports

To attribute revenue to conversations, report placed orders (no personal data, no order status) with the orders:report scope:

POST/v1/stores/{store_id}/orders:reportScope orders:report

See assisted revenue and attribution.

Last updated on

On this page