Inventory

Push price and stock by SKU with per-SKU results, read your catalogue, and find where each SKU is listed on the marketplaces.

Reading the catalogue needs InventoryRead; pushing price and stock needs InventoryWrite.

POST /api/inventory/price-quantity

Applies price and stock from your system, keyed by SKU. This is the endpoint for an ERP or warehouse system acting as the source of truth.

{
  "Items": [
    { "Sku": "WIDGET-1", "Price": 19.99, "Quantity": 42 },
    { "Sku": "WIDGET-2", "Quantity": 0 }
  ],
  "PropagateToListings": true
}
  • Up to 500 items per request.
  • Omitting Price or Quantity means "not provided", never "set to zero". Send the field only when you are changing it.
  • A SKU repeated in one request collapses to its last occurrence before anything is written.

The changes are applied before the response returns, so you are told what happened to each SKU:

{
  "Results": [
    { "Sku": "WIDGET-1", "Result": "Updated" },
    { "Sku": "WIDGET-2", "Result": "Unchanged" },
    { "Sku": "NOPE",     "Result": "NotFound" }
  ],
  "Updated": 1, "Unchanged": 1, "NotFound": 1, "Ambiguous": 0, "Failed": 0,
  "JobIds": ["6a73..."]
}
ResultMeans
UpdatedMatched, and at least one value differed and was written.
UnchangedMatched, but everything you sent already equalled what we hold. Not an error — this is what a nightly full-catalogue push looks like.
NotFoundNo product carries that SKU. Reported, never silently dropped.
AmbiguousMore than one product carries that SKU and none matched its exact casing.
FailedMatched, but the write failed. The rest of the batch still applied.

JobIds are the marketplace pushes this triggered. The values are already saved by the time you get the response — the jobs are the outbound half. Follow them with the jobs endpoint.

Set PropagateToListings false to change the stored values without scheduling any outbound write — useful for back-filling data the marketplaces already hold.

POST /api/products/List

Your catalogue, with the marketplace listings each SKU has.

{ "Sku": "WIDGET-1", "Limit": 50, "Offset": 0 }

All optional. Limit defaults to 50, maximum 200. Page with Offset against the returned TotalCount.

GET /api/products/{sku}

One product by SKU — the identifier your own system already holds, and the same key the price and quantity sync matches on. Matching is case-insensitive.

{
  "Product": {
    "Sku": "WIDGET-1",
    "Quantity": 42,
    "Listings": [
      {
        "Platform": "Amazon",
        "Country": "UnitedKingdom",
        "ListingId": "B0TEST12345",
        "ExternalSku": "AMZ-001",
        "ListingUrl": "https://www.amazon.co.uk/dp/B0TEST12345"
      }
    ]
  }
}

Listings is the durable map of where a SKU already exists. It is what makes an update revise the listing that is there rather than create a second one, and it is what to reconcile your own records against. A SKU listed nowhere yet returns an empty array — that is normal, not an error.

If several products differ only in the case of their SKU and none matches yours exactly, you get 409 conflict rather than a guess.

What is not here yet

Creating and updating products through the API is not available. Products are created by the import pipeline and in the app. When that changes it will be documented here — we would rather leave the gap visible than describe an endpoint you cannot call.