ListInventory returns what Zentail currently believes about the SKUs stocked in the caller's warehouses.
You call thisinventory:self
const url = 'https://api.zentail.com/v2/inventory';const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request GET \ --url https://api.zentail.com/v2/inventory \ --header 'Authorization: Bearer <token>'Two uses. It scopes a sweep — report only these SKUs rather than your whole catalog. And it lets a caller send only genuine differences, which on a large catalog is the difference between a viable poll loop and a pointless one.
Authorizations
Section titled “Authorizations”Parameters
Section titled “ Parameters ”Query Parameters
Section titled “Query Parameters”Optional: only SKUs whose Zentail-side quantity changed since this time. Omit for a full listing.
Leave empty for the first page; pass next_cursor thereafter.
Server-capped. Omit for the default.
Responses
Section titled “ Responses ”A successful response.
object
One entry per SKU-and-warehouse pair, so a SKU stocked in two of the caller’s warehouses appears twice. Empty when the filter matched nothing, which is not an error.
object
Zentail’s SKU for the product, and the value to send back on an InventoryUpdate. Mapping it to the integration’s own product code is the caller’s job; a mismatch here is the usual cause of UNKNOWN_SKU.
The caller’s own identifier for the warehouse, not Zentail’s internal id.
What Zentail currently believes is on hand.
When that belief was last updated, by anyone.
Empty when the page is the last one.
Examplegenerated
{ "items": [ { "sku": "example", "warehouseUniqueId": "example", "quantity": 1, "lastUpdatedTs": "2026-04-15T12:00:00Z" } ], "nextCursor": "example"}default
Section titled “default”An unexpected error response.
object
object
Examplegenerated
{ "code": 1, "message": "example", "details": [ { "@type": "example" } ]}