Inventory API
The Carriyo Inventory API manages stock levels across your fulfillment locations and tracks inventory changes over time. Submit inventory events to update per-location quantities, and query current positions by inventory key or product.
Idempotency
Write endpoints accept an optional Idempotency-Key request header for safe request replay when your integration retries after uncertain network outcomes. Replayed responses include Idempotent-Replayed: true. See Idempotency for the full contract.
Inventory
Stock addressed by an inventory key, held as one inventory position per location. Products that carry the same key share the same stock; a product without a key is not stock-managed. Positions are created and updated by inventory events rather than written directly.
Related: How inventory keys, positions and reservations work
7 operations · 0 objects
/inventory/inventory-key/{inventory-key}Get inventory by inventory key
Retrieves the current stock levels of an inventory key across all locations, keyed by location ID.
Errors
404— the inventory key has no inventory position at any location.
Related: How products carry the inventory key
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| inventory-key | string | Yes | The inventory key. |
Headers
| Name | Value | Required | Description |
|---|---|---|---|
| Authorization | Bearer YOUR-ACCESS-TOKEN | Yes | OAuth 2.0 bearer token obtained from `POST /oauth/token`. |
| x-api-key | YOUR-API-KEY | Yes | Your tenant's API key, issued in the Carriyo Dashboard. Required on every request except `POST /oauth/token`. |
| tenant-id | YOUR-TENANT-ID | Yes | Your Carriyo tenant ID, shown in the Carriyo Dashboard. Required on every request except `POST /oauth/token`. |
Responses
inventory-responseerror-responseNeed the full machine-readable spec? Download the OpenAPI document →
/inventory/product-id/{product-id}Get inventory by product ID
Retrieves the current stock levels of the product's inventory key across all locations, keyed by location ID.
Errors
404— the product has noinventory_key.404— the inventory key has no inventory position at any location.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| product-id | string | Yes | The unique identifier of the product. |
Headers
| Name | Value | Required | Description |
|---|---|---|---|
| Authorization | Bearer YOUR-ACCESS-TOKEN | Yes | OAuth 2.0 bearer token obtained from `POST /oauth/token`. |
| x-api-key | YOUR-API-KEY | Yes | Your tenant's API key, issued in the Carriyo Dashboard. Required on every request except `POST /oauth/token`. |
| tenant-id | YOUR-TENANT-ID | Yes | Your Carriyo tenant ID, shown in the Carriyo Dashboard. Required on every request except `POST /oauth/token`. |
Responses
inventory-responseerror-responseNeed the full machine-readable spec? Download the OpenAPI document →
/inventory/product-ref/{product-ref}Get inventory by product reference
Retrieves the current stock levels of the inventory key of the product you reference, across all locations, keyed by location ID.
Behavior
Product references are unique per merchant, so merchant is required.
Errors
400—merchantmissing.404— the product has noinventory_key.404— the inventory key has no inventory position at any location.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| product-ref | string | Yes | Your reference for the product. |
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| merchant | string | Yes | The merchant the product reference belongs to. |
Headers
| Name | Value | Required | Description |
|---|---|---|---|
| Authorization | Bearer YOUR-ACCESS-TOKEN | Yes | OAuth 2.0 bearer token obtained from `POST /oauth/token`. |
| x-api-key | YOUR-API-KEY | Yes | Your tenant's API key, issued in the Carriyo Dashboard. Required on every request except `POST /oauth/token`. |
| tenant-id | YOUR-TENANT-ID | Yes | Your Carriyo tenant ID, shown in the Carriyo Dashboard. Required on every request except `POST /oauth/token`. |
Responses
inventory-responseerror-responseerror-responseNeed the full machine-readable spec? Download the OpenAPI document →
/inventory/inventory-key/{inventory-key}/reservationsGet reservations by inventory key
Retrieves the open reservations held against an inventory key.
Behavior
Reservations are held per location and order, and back each position's reserved counter. A reservation is open while it holds a non-zero quantity: fulfillment and cancellation reduce it and then delete the row, and there is no status field. Rows are oldest first, paged with page_num and rows_per_page (10 per page by default); only the oldest 500 are reachable. location_id narrows the read to one location.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| inventory-key | string | Yes | The inventory key. |
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| location_id | string | No | Narrow the results to one location. |
| page_num | integer | No | The page to return, starting at 1. |
| rows_per_page | integer | No | How many rows per page. |
Headers
| Name | Value | Required | Description |
|---|---|---|---|
| Authorization | Bearer YOUR-ACCESS-TOKEN | Yes | OAuth 2.0 bearer token obtained from `POST /oauth/token`. |
| x-api-key | YOUR-API-KEY | Yes | Your tenant's API key, issued in the Carriyo Dashboard. Required on every request except `POST /oauth/token`. |
| tenant-id | YOUR-TENANT-ID | Yes | Your Carriyo tenant ID, shown in the Carriyo Dashboard. Required on every request except `POST /oauth/token`. |
Responses
Need the full machine-readable spec? Download the OpenAPI document →
/inventory/product-id/{product-id}/reservationsGet reservations by product ID
Retrieves the open reservations held against the product's inventory key.
Behavior
Reservations are held per location and order, and back each position's reserved counter. A reservation is open while it holds a non-zero quantity: fulfillment and cancellation reduce it and then delete the row, and there is no status field. Rows are oldest first, paged with page_num and rows_per_page (10 per page by default); only the oldest 500 are reachable. location_id narrows the read to one location.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| product-id | string | Yes | The unique identifier of the product. |
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| location_id | string | No | Narrow the results to one location. |
| page_num | integer | No | The page to return, starting at 1. |
| rows_per_page | integer | No | How many rows per page. |
Headers
| Name | Value | Required | Description |
|---|---|---|---|
| Authorization | Bearer YOUR-ACCESS-TOKEN | Yes | OAuth 2.0 bearer token obtained from `POST /oauth/token`. |
| x-api-key | YOUR-API-KEY | Yes | Your tenant's API key, issued in the Carriyo Dashboard. Required on every request except `POST /oauth/token`. |
| tenant-id | YOUR-TENANT-ID | Yes | Your Carriyo tenant ID, shown in the Carriyo Dashboard. Required on every request except `POST /oauth/token`. |
Responses
reservation-pageerror-responseNeed the full machine-readable spec? Download the OpenAPI document →
/inventory/product-ref/{product-ref}/reservationsGet reservations by product reference
Retrieves the open reservations held against the inventory key of the product you reference.
Behavior
Product references are unique per merchant, so merchant is required.
Reservations are held per location and order, and back each position's reserved counter. A reservation is open while it holds a non-zero quantity: fulfillment and cancellation reduce it and then delete the row, and there is no status field. Rows are oldest first, paged with page_num and rows_per_page (10 per page by default); only the oldest 500 are reachable. location_id narrows the read to one location.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| product-ref | string | Yes | Your reference for the product. |
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| merchant | string | Yes | The merchant the product reference belongs to. |
| location_id | string | No | Narrow the results to one location. |
| page_num | integer | No | The page to return, starting at 1. |
| rows_per_page | integer | No | How many rows per page. |
Headers
| Name | Value | Required | Description |
|---|---|---|---|
| Authorization | Bearer YOUR-ACCESS-TOKEN | Yes | OAuth 2.0 bearer token obtained from `POST /oauth/token`. |
| x-api-key | YOUR-API-KEY | Yes | Your tenant's API key, issued in the Carriyo Dashboard. Required on every request except `POST /oauth/token`. |
| tenant-id | YOUR-TENANT-ID | Yes | Your Carriyo tenant ID, shown in the Carriyo Dashboard. Required on every request except `POST /oauth/token`. |
Responses
reservation-pageerror-responseerror-responseNeed the full machine-readable spec? Download the OpenAPI document →
/inventory/inventory-key/{inventory-key}/location-id/{location-id}Delete inventory
Permanently deletes the inventory position of an inventory key at one location, along with its reservations.
Behavior
Position. The position is gone: reading it returns 404 until the next inventory event for that inventory key and location recreates it. The event history is not deleted, so the history for the inventory key still returns the events that preceded the deletion.
Reservations. Every reservation held at that location is deleted with the position. The orders holding them are not updated.
Webhook. An inventory webhook with operation: DELETE fires when the tenant has an active inventory webhook.
Related: How inventory keys, positions and reservations work
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| inventory-key | string | Yes | The inventory key. |
| location-id | string | Yes | The unique identifier of the location. |
Headers
| Name | Value | Required | Description |
|---|---|---|---|
| Authorization | Bearer YOUR-ACCESS-TOKEN | Yes | OAuth 2.0 bearer token obtained from `POST /oauth/token`. |
| x-api-key | YOUR-API-KEY | Yes | Your tenant's API key, issued in the Carriyo Dashboard. Required on every request except `POST /oauth/token`. |
| tenant-id | YOUR-TENANT-ID | Yes | Your Carriyo tenant ID, shown in the Carriyo Dashboard. Required on every request except `POST /oauth/token`. |
Responses
error-responseNeed the full machine-readable spec? Download the OpenAPI document →
Inventory Events
The event history behind every stock level: each event either sets an absolute quantity or applies a signed delta to one inventory key at one location.
Related: How an event changes stock, and when a batch is safe to resend
4 operations · 0 objects
/inventory-events/request-id/{request-id}Get inventory events by request ID
Returns the events submitted under one bulk import request, in sequence order.
Behavior
status reports the batch as a whole:
processingwhile any row is still queued.completedonce every row is accounted for.
Rows are in sequence order within the batch. APPLIED, REJECTED and UNCHANGED rows are all included; rows left out of the event history by skip_unchanged=true are not. A REJECTED row carries its reason in error_message.
Rows the import call rejected on validation never reach the event history; they are reported only in the import response. Once the status is completed, an accepted row with no event was unchanged and imported with skip_unchanged=true.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| request-id | string | Yes | The request ID returned from the bulk import operation. |
Headers
| Name | Value | Required | Description |
|---|---|---|---|
| Authorization | Bearer YOUR-ACCESS-TOKEN | Yes | OAuth 2.0 bearer token obtained from `POST /oauth/token`. |
| x-api-key | YOUR-API-KEY | Yes | Your tenant's API key, issued in the Carriyo Dashboard. Required on every request except `POST /oauth/token`. |
| tenant-id | YOUR-TENANT-ID | Yes | Your Carriyo tenant ID, shown in the Carriyo Dashboard. Required on every request except `POST /oauth/token`. |
Responses
get-inventory-events-responseerror-responseNeed the full machine-readable spec? Download the OpenAPI document →
/inventory-events/inventory-key/{inventory-key}Get inventory events by inventory key
Retrieves the event history of an inventory key, newest first.
Behavior
Rows are newest first, paged with page_num and rows_per_page (10 per page by default); only the newest 500 events are reachable. APPLIED, REJECTED and UNCHANGED rows are all included; rows left out of the event history by skip_unchanged=true are not. location_id narrows the read to one location.
Errors
404— the inventory key has no events.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| inventory-key | string | Yes | The inventory key. |
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| location_id | string | No | Narrow the results to one location. |
| page_num | integer | No | The page to return, starting at 1. |
| rows_per_page | integer | No | How many rows per page. |
Headers
| Name | Value | Required | Description |
|---|---|---|---|
| Authorization | Bearer YOUR-ACCESS-TOKEN | Yes | OAuth 2.0 bearer token obtained from `POST /oauth/token`. |
| x-api-key | YOUR-API-KEY | Yes | Your tenant's API key, issued in the Carriyo Dashboard. Required on every request except `POST /oauth/token`. |
| tenant-id | YOUR-TENANT-ID | Yes | Your Carriyo tenant ID, shown in the Carriyo Dashboard. Required on every request except `POST /oauth/token`. |
Responses
inventory-event-pageerror-responseNeed the full machine-readable spec? Download the OpenAPI document →
/inventory-events/product-id/{product-id}Get inventory events by product ID
Retrieves the event history of the product's inventory key, newest first.
Behavior
Rows are newest first, paged with page_num and rows_per_page (10 per page by default); only the newest 500 events are reachable. APPLIED, REJECTED and UNCHANGED rows are all included; rows left out of the event history by skip_unchanged=true are not. location_id narrows the read to one location.
Errors
404— the product has noinventory_key.404— the inventory key has no events.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| product-id | string | Yes | The unique identifier of the product. |
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| location_id | string | No | Narrow the results to one location. |
| page_num | integer | No | The page to return, starting at 1. |
| rows_per_page | integer | No | How many rows per page. |
Headers
| Name | Value | Required | Description |
|---|---|---|---|
| Authorization | Bearer YOUR-ACCESS-TOKEN | Yes | OAuth 2.0 bearer token obtained from `POST /oauth/token`. |
| x-api-key | YOUR-API-KEY | Yes | Your tenant's API key, issued in the Carriyo Dashboard. Required on every request except `POST /oauth/token`. |
| tenant-id | YOUR-TENANT-ID | Yes | Your Carriyo tenant ID, shown in the Carriyo Dashboard. Required on every request except `POST /oauth/token`. |
Responses
inventory-event-pageerror-responseNeed the full machine-readable spec? Download the OpenAPI document →
/inventory-events/bulk/importBulk import inventory events
Submits a batch of inventory events that set or adjust stock at your locations.
Behavior
What to send
Every batch needs a request-id header that has not been used before. Send an Idempotency-Key as well: a retry that repeats both headers returns the stored response instead of a refusal. Each event addresses one inventory position: one inventory key at one location.
inventory_keynames the key. Product keys are refused here; they stay on the read endpoints.location_idorlocation_codenames the location, and at least one is required. A code must match exactly one location, and when both keys are sent they must name the same location.- The location must be inventory-enabled.
Resolution never guesses: an ambiguous or conflicting key rejects the event rather than applying it to a position you did not name.
Event types
Only the snapshot, adjustment and movement types may be sent.
Snapshot. Sets absolute values:
SNAPSHOTsets both counts; requireson_handandunavailable.SNAPSHOT_ONHANDsetson_handonly; requireson_hand.SNAPSHOT_UNAVAILABLEsetsunavailableonly; requiresunavailable.
Adjustment. Applies a signed delta:
INVENTORY_ADJUSTMENT_ONHANDadjustson_hand; requireson_hand.INVENTORY_ADJUSTMENT_UNAVAILABLEadjustsunavailable; requiresunavailable.
Movement. Applies a signed delta for a stock movement:
RETURNadjustsunavailablefor returned items; requiresunavailable.TRANSFER_IN,TRANSFER_OUT,SALEandPO_RECEIPTadjuston_hand,unavailableor both; each requires at least one of them.
The movement types apply the value exactly as sent, so a SALE or TRANSFER_OUT that reduces stock must carry a negative number.
The order, shipment and return-request types (ORDER_RESERVATION, ORDER_UPDATE, ORDER_CANCELLATION, ORDER_FULFILLMENT, ORDER_UNFULFILLED, ORDER_RETURN, SHIPMENT_SHIPPED, RETURN_REQUEST_REVERSE_SHIPMENT_DELIVERED, RETURN_REQUEST_MARKED_AS_RECEIVED) are written by Carriyo as orders move. A row sending one is rejected; the rest of the batch continues.
Validation
A row that fails validation is rejected on its own and the batch continues; a problem with the request itself refuses the whole batch, as listed under Errors.
- A quantity outside -1,000,000 to 1,000,000, or neither quantity supplied, rejects the row.
event_timestampmissing, older than 14 days, or more than two minutes ahead of the Carriyo server clock rejects the row.- A missing
inventory_key, or anyproduct_id,product_reformerchantpresent, rejects the row. - A missing or unsupported
event_type, or a field combination wrong for the type, rejects the row. - An unknown location, a disagreeing
location_idandlocation_code, an ambiguous code, or a location that is not inventory-enabled rejects the row.
Processing
Rows are queued and applied asynchronously, in event_timestamp order. Each comes back processing (accepted and queued) or rejected with a reason, and the batch's progress is readable by request id. If queuing fails, accepted rows flip to rejected and the request-id is released for reuse.
- Snapshot rows for the same position and type are collapsed to the one with the newest
event_timestamp; the others are rejected as older snapshots. - Snapshot rows naming the same position with different snapshot types are all rejected.
- Movement rows are never collapsed: each one applies.
An inventory key and location with no position yet gets one from its first event, with every counter at 0, so a movement on a new position applies its delta from 0. Across batches, a snapshot older than a count already applied to the position is rejected; a snapshot older than movements applied after it is re-based on those movements and applied; a movement older than a count already applied is rejected as already included.
Each row that changes a counter fires one inventory webhook, with operation CREATE when the row created the position and UPDATE otherwise, when the tenant has an active inventory webhook.
Resubmitting a snapshot batch converges on the same counts. Resubmitting adjustment or movement rows applies them again, so read a failed batch by its request id before resending it.
Unchanged rows
A row leaves the position unchanged when it is a snapshot equal to the stored counts or a zero movement. Such a row is recorded with status UNCHANGED and never fires a webhook. With skip_unchanged=true it is left out of the event history as well; the row is still counted and the request still completes.
Errors
400— therequest-idheader is missing.400— therequest-idhas been used before; the whole request is lost, valid rows included.400— the body is empty.400— the body is malformed JSON.400— the batch exceeds 500 rows; the message isbulk import cannot exceed 500 rows.
Related: How an event changes stock, and when a batch is safe to resend
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| skip_unchanged | boolean | No | When `true`, rows that leave the position's counters unchanged are not recorded as events. They are still counted towards batch completion but appear neither in the event history nor in webhooks. An unchanged row is not written at all, so it does not refresh the position's ordering timestamps the way a recorded `UNCHANGED` event does. When `false` (the default), such rows are recorded with status `UNCHANGED`. |
Headers
| Name | Value | Required | Description |
|---|---|---|---|
| Authorization | Bearer YOUR-ACCESS-TOKEN | Yes | OAuth 2.0 bearer token obtained from `POST /oauth/token`. |
| x-api-key | YOUR-API-KEY | Yes | Your tenant's API key, issued in the Carriyo Dashboard. Required on every request except `POST /oauth/token`. |
| tenant-id | YOUR-TENANT-ID | Yes | Your Carriyo tenant ID, shown in the Carriyo Dashboard. Required on every request except `POST /oauth/token`. |
| Content-Type | application/json | Yes | Media type of the request body. |
Header parameters
| Name | Type | Required | Description |
|---|---|---|---|
| Idempotency-Key | string | No | Optional client-generated key that identifies one logical operation. Reuse the same key when retrying with the same payload. Replays the stored response. See [Idempotency](/api/idempotency/). |
| request-id | string | Yes | A unique request ID for this batch (required). - Must be unique across all previous requests - Use this to track processing status via the Get Events by Request ID endpoint - Cannot be reused once accepted - if you need to retry, use a new request ID |
Request body
application/jsonrequiredAn array of inventory-event-request. Each item has the following fields:
- The code of the location, as an alternative to
location_id. Carriyo resolves it to the matching inventory-enabled location in your tenant. The code must match exactly one location. If two or more locations share the code, the event is rejected as ambiguous — sendlocation_idinstead. - The type of inventory event: -
SNAPSHOT- Set absolute values for both on_hand and unavailable -SNAPSHOT_ONHAND- Set absolute value for on_hand only -SNAPSHOT_UNAVAILABLE- Set absolute value for unavailable only -INVENTORY_ADJUSTMENT_ONHAND- Adjust on_hand by delta (+/-) -INVENTORY_ADJUSTMENT_UNAVAILABLE- Adjust unavailable by delta (+/-) -RETURN- Record returned items as a signed delta to unavailable (unavailable only) -TRANSFER_IN- Stock transfer into location, as a signed delta to on_hand and/or unavailable -TRANSFER_OUT- Stock transfer out of location, as a signed delta to on_hand and/or unavailable -SALE- Record sales as a signed delta to on_hand and/or unavailable -PO_RECEIPT- Purchase order receipt as a signed delta to on_hand and/or unavailable Deltas are applied exactly as sent, so aSALEorTRANSFER_OUTthat reduces stock must carry a negative value. Carriyo writes these types itself as orders, shipments and returns move; a row sending one is rejected withevent_type <value> is not supported in bulk import: -ORDER_RESERVATION-ORDER_UPDATE-ORDER_CANCELLATION-ORDER_FULFILLMENT-ORDER_UNFULFILLED-ORDER_RETURN-SHIPMENT_SHIPPED-RETURN_REQUEST_REVERSE_SHIPMENT_DELIVERED-RETURN_REQUEST_MARKED_AS_RECEIVEDValues:SNAPSHOTSNAPSHOT_ONHANDSNAPSHOT_UNAVAILABLEINVENTORY_ADJUSTMENT_ONHANDINVENTORY_ADJUSTMENT_UNAVAILABLERETURNTRANSFER_INTRANSFER_OUTSALEPO_RECEIPT
Responses
inventory-event-bulk-responseerror-responseNeed the full machine-readable spec? Download the OpenAPI document →