Docs / Invoicing
Inventory#
Inventory is tracked per Product and active physical branch. The authoritative balance fields areonHand, reserved, and available, where available = max(0, onHand - reserved). This page covers the Inventory API, invoice and POS stock behavior, and recovery procedures.
Overview#
Balances show On Hand, Reserved, Available, and stock condition by active physical branch.
Movements record manual Quantity In and Quantity Out for tracked Products.
Stocktakes apply physical counts to branch balances.
Suppliers can be attached to incoming movements.
Activity records manual changes, counts, and automated sales.
Authentication#
All /api/v1/inventory endpoints are admin REST endpoints. Send the headers described inInvoices . Read endpoints require invoices.view; write and recovery endpoints require invoices.manage. The merchant scope comes from the authenticated request. A locationId used for an inventory operation must be an active physical branch UUID owned by that merchant. Quantities support up to three decimal places.
The matching requests are in Admin API / Invoicing / Inventory in the Postman collection.
Common errors#
Inventory endpoints#
List inventory balances#
Endpoint#
GET /api/v1/inventory/balances
curl -X GET "https://uat.auxcore.net/api/v1/inventory/balances?productId=PRODUCT_ID" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "X-Tenant-ID: your-tenant-id"
Query parameters#
Response#
200 OK: data[] contains productId, locationId, onHand, reserved, available, andstockCondition. Product-scoped responses include aggregate meta.totals.
{
"success" : true ,
"data" : [ {
"productId" : "PRODUCT_ID" , "locationId" : "LOCATION_ID" , "onHand" : 20 ,
"reserved" : 3 , "available" : 17 , "stockCondition" : "in_stock"
} ] ,
"meta" : { "total" : 1 , "totals" : { "onHand" : 20 , "reserved" : 3 , "available" : 17 } }
}
Errors#
Create a stock movement#
Endpoint#
POST /api/v1/inventory/movements
curl -X POST "https://uat.auxcore.net/api/v1/inventory/movements" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "X-Tenant-ID: your-tenant-id" \
-H "Content-Type: application/json" \
-d '{"type":"quantity_in","locationId":"LOCATION_ID","date":"2026-10-28","reason":"Supplier delivery","lines":[{"productId":"PRODUCT_ID","quantity":12.5}]}'
Request#
{
"type" : "quantity_in" ,
"locationId" : "2d8b4e17-ec2e-41f2-b6e9-6a32c5fd1780" ,
"date" : "2026-10-28" ,
"reason" : "Supplier delivery" ,
"supplierId" : "supplier-uuid" ,
"idempotencyKey" : "delivery:po-1042" ,
"lines" : [ { "productId" : "product-uuid" , "quantity" : 12.5 } ]
}
Response#
201 Created: data contains the saved movement and lines.
{
"success" : true ,
"data" : {
"movement" : { "id" : "MOVEMENT_ID" , "type" : "quantity_in" , "locationId" : "LOCATION_ID" , "reason" : "Supplier delivery" } ,
"lines" : [ { "productId" : "PRODUCT_ID" , "quantity" : 12.5 , "before" : 0 , "after" : 12.5 } ]
}
}
Errors#
List stock movements#
Endpoint#
GET /api/v1/inventory/movements
curl -X GET "https://uat.auxcore.net/api/v1/inventory/movements?productId=PRODUCT_ID&page=1&limit=10" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "X-Tenant-ID: your-tenant-id"
Query parameters#
Response#
200 OK: data is the movement list; meta contains page, limit, and total.
{ "success" : true , "data" : [ ] , "meta" : { "page" : 1 , "limit" : 10 , "total" : 0 } }
Get a stock movement#
Endpoint#
GET /api/v1/inventory/movements/:id
curl -X GET "https://uat.auxcore.net/api/v1/inventory/movements/MOVEMENT_ID" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "X-Tenant-ID: your-tenant-id"
Response#
200 OK: data contains the movement and its lines.
{ "success" : true , "data" : { "movement" : { "id" : "MOVEMENT_ID" } , "lines" : [ ] } }
Errors#
Count stock#
Endpoint#
POST /api/v1/inventory/stocktakes
curl -X POST "https://uat.auxcore.net/api/v1/inventory/stocktakes" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "X-Tenant-ID: your-tenant-id" \
-H "Content-Type: application/json" \
-d '{"locationId":"LOCATION_ID","name":"Monthly count","date":"2026-10-28","lines":[{"productId":"PRODUCT_ID","counted":25}]}'
Request#
Creation applies the count immediately; counted cannot be below Reserved.
Response#
201 Created: data contains the completed stocktake and lines.
{
"success" : true ,
"data" : {
"stocktake" : { "id" : "STOCKTAKE_ID" , "status" : "completed" , "locationId" : "LOCATION_ID" } ,
"lines" : [ { "productId" : "PRODUCT_ID" , "expected" : 20 , "counted" : 25 , "difference" : 5 } ]
}
}
Errors#
List stocktakes#
Endpoint#
GET /api/v1/inventory/stocktakes
curl -X GET "https://uat.auxcore.net/api/v1/inventory/stocktakes?locationId=LOCATION_ID&page=1&limit=10" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "X-Tenant-ID: your-tenant-id"
Query parameters#
Response#
200 OK: data is the stocktake list; meta contains page, limit, and total.
{ "success" : true , "data" : [ ] , "meta" : { "page" : 1 , "limit" : 10 , "total" : 0 } }
Get a stocktake#
Endpoint#
GET /api/v1/inventory/stocktakes/:id
curl -X GET "https://uat.auxcore.net/api/v1/inventory/stocktakes/STOCKTAKE_ID" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "X-Tenant-ID: your-tenant-id"
Response#
200 OK: data contains the stocktake and its lines.
{ "success" : true , "data" : { "stocktake" : { "id" : "STOCKTAKE_ID" } , "lines" : [ ] } }
Errors#
Complete a stocktake#
Endpoint#
POST /api/v1/inventory/stocktakes/:id/complete
curl -X POST "https://uat.auxcore.net/api/v1/inventory/stocktakes/STOCKTAKE_ID/complete" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "X-Tenant-ID: your-tenant-id" \
-H "Content-Type: application/json" \
-d '{"lines":[{"productId":"PRODUCT_ID","counted":25}]}'
Request#
Response#
200 OK: data contains the completed stocktake and lines.
{ "success" : true , "data" : { "stocktake" : { "id" : "STOCKTAKE_ID" , "status" : "completed" } , "lines" : [ ] } }
Errors#
Suppliers#
Create a supplier#
Endpoint#
POST /api/v1/inventory/suppliers
curl -X POST "https://uat.auxcore.net/api/v1/inventory/suppliers" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "X-Tenant-ID: your-tenant-id" \
-H "Content-Type: application/json" \
-d '{"name":"Example Supply Co","email":"orders@example.com","phone":"5550100"}'
Request#
Response#
201 Created: data is the created supplier.
{ "success" : true , "data" : { "id" : "SUPPLIER_ID" , "name" : "Example Supply Co" , "email" : "orders@example.com" , "phone" : "5550100" } }
Errors#
List suppliers#
Endpoint#
GET /api/v1/inventory/suppliers
curl -X GET "https://uat.auxcore.net/api/v1/inventory/suppliers?search=Example&page=1&limit=10" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "X-Tenant-ID: your-tenant-id"
Query parameters#
Response#
200 OK: data is the supplier list; meta contains page, limit, and total.
{ "success" : true , "data" : [ ] , "meta" : { "page" : 1 , "limit" : 10 , "total" : 0 } }
Get a supplier#
Endpoint#
GET /api/v1/inventory/suppliers/:id
curl -X GET "https://uat.auxcore.net/api/v1/inventory/suppliers/SUPPLIER_ID" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "X-Tenant-ID: your-tenant-id"
Response#
200 OK: data is the scoped supplier.
{ "success" : true , "data" : { "id" : "SUPPLIER_ID" , "name" : "Example Supply Co" , "email" : "orders@example.com" } }
Errors#
Update a supplier#
Endpoint#
PUT /api/v1/inventory/suppliers/:id
curl -X PUT "https://uat.auxcore.net/api/v1/inventory/suppliers/SUPPLIER_ID" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "X-Tenant-ID: your-tenant-id" \
-H "Content-Type: application/json" \
-d '{"phone":"5550101"}'
Request#
Response#
200 OK: data is the updated supplier.
{ "success" : true , "data" : { "id" : "SUPPLIER_ID" , "name" : "Example Supply Co" , "phone" : "5550101" } }
Errors#
Delete a supplier#
Endpoint#
DELETE /api/v1/inventory/suppliers/:id
curl -X DELETE "https://uat.auxcore.net/api/v1/inventory/suppliers/SUPPLIER_ID" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "X-Tenant-ID: your-tenant-id"
Response#
200 OK: { "success": true, "data": { "id": "supplier-uuid" } }.
Errors#
Read inventory activity#
Endpoint#
GET /api/v1/inventory/activity
curl -X GET "https://uat.auxcore.net/api/v1/inventory/activity?productId=PRODUCT_ID&locationId=LOCATION_ID&page=1&limit=10" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "X-Tenant-ID: your-tenant-id"
Query parameters#
Response#
200 OK: data is the activity list; meta contains page, limit, and total.
{ "success" : true , "data" : [ ] , "meta" : { "page" : 1 , "limit" : 10 , "total" : 0 } }