Set or adjust stock levels for up to 100 product/outlet lines in one all-or-nothing request
const url = 'https://api.oletapp.com/your-store/v1/inventory/batch';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"lines":[{"adjust":{"quantity":1,"reason_id":"2489E9AD-2EE2-8E00-8EC9-32D5F69181C0","unit_cost":1},"outlet_id":"2489E9AD-2EE2-8E00-8EC9-32D5F69181C0","product_id":"2489E9AD-2EE2-8E00-8EC9-32D5F69181C0","set":{"on_hand":1,"reason_id":"2489E9AD-2EE2-8E00-8EC9-32D5F69181C0","unit_cost":1},"sku":"example"}]}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://api.oletapp.com/your-store/v1/inventory/batch \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "lines": [ { "adjust": { "quantity": 1, "reason_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "unit_cost": 1 }, "outlet_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "product_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "set": { "on_hand": 1, "reason_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "unit_cost": 1 }, "sku": "example" } ] }'Each line names exactly one of set (absolute, same rules as PUT /products/{id}/inventory/{outlet_id}) or adjust (relative, same rules as POST /inventory/adjustments), and exactly one of product_id or sku.
-
skumatchesproduct.skucase-insensitively among live products only, never a barcode. Everyskuin the batch is resolved in ONE query before the transaction; an unknownskufails the whole batch. -
No duplicate
product_id/outlet_idpair is allowed anywhere in the batch, including anskuline resolving to the same product/outlet as aproduct_idline. -
Rows are locked in a stable order and the whole batch commits or nothing does: one bad line fails the whole request and writes zero rows.
-
Idempotency-Keyis REQUIRED: a retried batch replayed without one could apply its relativeadjustlines twice, moving stock again. -
400 VALIDATION_FAILED: a line named zero or both ofset/adjust, zero or both ofproduct_id/sku, or duplicated aproduct_id/outlet_idpair. -
422 UNPROCESSABLE: one or moreskuvalues did not match a live product, naminglines.N. -
422 INSUFFICIENT_STOCK: anadjustline would take stock below zero, naminglines.N. -
422 REASON_NOT_ALLOWED: a line names a reason that is a system reason or is turned off, naminglines.N. A reason must be enabled and must not be a system reason. -
422 OUTLET_DELETED: a line names an outlet that has been deleted. Nothing is written.
A set or adjust line may carry unit_cost (integer cents, optional). On a set line it becomes the average cost for the outlet whatever the direction, including when on_hand is unchanged; left out, the current average is kept, or the supply price when there is none. On an adjust line it is blended into the average when stock goes up and ignored otherwise.
Requires scope: inventory:write
Authorizations
Section titled “Authorizations”Request Body
Section titled “Request Body”object
Examplegenerated
{ "lines": [ { "adjust": { "quantity": 1, "reason_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "unit_cost": 1 }, "outlet_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "product_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "set": { "on_hand": 1, "reason_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "unit_cost": 1 }, "sku": "example" } ]}Responses
Section titled “Responses”Set or adjust stock levels for up to 100 product/outlet lines in one all-or-nothing request
object
object
True only on an idempotency replay.
Echoed only when the line was given by sku.
Examplegenerated
{ "data": [ { "changed": true, "delta": 1, "on_hand": 1, "outlet_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "previous": 1, "product_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "replayed": true, "sku": "example" } ]}default
Section titled “default”An error response.
object
object
A machine-readable error code, e.g. VALIDATION_FAILED.
object
A plain-English sentence describing what went wrong.
Example
{ "error": { "code": "UNAUTHORIZED" }}