Inventory API
REST endpoints for inventory in SKUFlow: 11 operations with parameters, request and response fields, permissions and curl examples.
Base URL: https://app.skuflow.ai/api. Every call needs Authorization: Bearer skf_… (Authentication); {organizationId} ($ORGANIZATION_ID in the examples) is your business's id.
| Operation | Endpoint | Risk |
|---|---|---|
| List stock locations | GET /organizations/{organizationId}/inventory/locations | read |
| Create a warehouse | POST /organizations/{organizationId}/inventory/locations | write |
| Get a location with its stock | GET /organizations/{organizationId}/inventory/locations/{locationId} | read |
| Update a location | PATCH /organizations/{organizationId}/inventory/locations/{locationId} | write |
| Delete a location | DELETE /organizations/{organizationId}/inventory/locations/{locationId} | sensitive |
| List stock levels | GET /organizations/{organizationId}/inventory/stock | read |
| The stock ledger | GET /organizations/{organizationId}/inventory/movements | read |
| Set a reorder point | PATCH /organizations/{organizationId}/inventory/levels | write |
| Adjust stock | POST /organizations/{organizationId}/inventory/adjustments | write |
| Record a stock count | POST /organizations/{organizationId}/inventory/counts | write |
| Transfer stock between locations | POST /organizations/{organizationId}/inventory/transfers | write |
List stock locations
GET /organizations/{organizationId}/inventory/locations
Warehouses (stock locations) with item, low-stock and negative counts (and stock value with costing.read). Read-only.
| Permission | inventory.read (Owner, Admin, Staff, Member) |
| Risk | read, OAuth scope skuflow.read. Read: reads only. |
| MCP tool | inventoryLocations_list (toolset pricebook) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
includeInactive | query | boolean or enum | No |
Example
curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/inventory/locations" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
An array of objects:
| Field | Type | Description |
|---|---|---|
id | string | |
organizationId | string | |
name | string | |
address | string or null | |
isDefault | boolean | |
active | boolean | |
createdAt | string (date-time) | |
updatedAt | string (date-time) | |
itemCount | integer | Items with stock (or negative stock) here. |
lowCount | integer | Items at or below their reorder point, or negative. |
negativeCount | integer | |
stockValueCents | integer | Integer cents. Present only for roles with costing.read. |
Create a warehouse
POST /organizations/{organizationId}/inventory/locations
Adds a warehouse (stock location). The first one becomes the default. Returns the location.
| Permission | inventory.manage (Owner, Admin, Staff) |
| Risk | write, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it. |
| MCP tool | inventoryLocations_create (toolset pricebook) |
| Plan | Inventory and purchasing: the Pro plan and up. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Up to 200 characters. |
address | string or null | No | Up to 500 characters. |
isDefault | boolean | No | The default warehouse, listed first and preselected for purchase orders. Only one is. |
active | boolean | No | Retired locations (false) are hidden. |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/inventory/locations" \
-H "Authorization: Bearer $SKUFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Dana Whitfield"}'Response
201: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | |
organizationId | string | |
name | string | |
address | string or null | |
isDefault | boolean | |
active | boolean | |
createdAt | string (date-time) | |
updatedAt | string (date-time) |
Get a location with its stock
GET /organizations/{organizationId}/inventory/locations/{locationId}
One warehouse with every stock level there (status, reorder point, suggested order). Read-only.
| Permission | inventory.read (Owner, Admin, Staff, Member) |
| Risk | read, OAuth scope skuflow.read. Read: reads only. |
| MCP tool | inventoryLocations_get (toolset pricebook) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
locationId | path | string | Yes |
Example
curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/inventory/locations/{locationId}" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | |
organizationId | string | |
name | string | |
address | string or null | |
isDefault | boolean | |
active | boolean | |
createdAt | string (date-time) | |
updatedAt | string (date-time) | |
levels | array of object | |
levels[].id | string | |
levels[].organizationId | string | |
levels[].itemId | string | |
levels[].locationId | string | |
levels[].onHand | number | |
levels[].reorderPoint | number or null | |
levels[].reorderQty | number or null | |
levels[].updatedAt | string (date-time) | |
levels[].item | object | |
levels[].item.id | string | |
levels[].item.code | string or null | |
levels[].item.name | string | |
levels[].item.unit | string | |
levels[].item.kind | string | |
levels[].item.costCents | integer | Integer cents. Present only for roles with costing.read. |
levels[].item.vendorId | string or null | |
levels[].item.vendor | object or null | |
levels[].item.categoryId | string or null | |
levels[].location | object | |
levels[].location.id | string | |
levels[].location.name | string | |
levels[].status | enum | NEGATIVE below zero (allowed, flagged), OUT at 0, LOW at or below the reorder point. One of NEGATIVE, OUT, LOW, OK. |
levels[].low | boolean | |
levels[].suggestedQuantity | number | What to order when low: the reorder quantity, else enough to clear the point. |
levels[].stockValueCents | integer | Integer cents. Present only for roles with costing.read. |
lowCount | integer | |
stockValueCents | integer | Integer cents. Present only for roles with costing.read. |
Update a location
PATCH /organizations/{organizationId}/inventory/locations/{locationId}
Renames it, changes its address, makes it the default warehouse, or retires it (active: false). Returns it.
| Permission | inventory.manage (Owner, Admin, Staff) |
| Risk | write, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it. |
| MCP tool | inventoryLocations_update (toolset pricebook) |
| Plan | Inventory and purchasing: the Pro plan and up. |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
locationId | path | string | Yes |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | No | Up to 200 characters. |
address | string or null | No | Up to 500 characters. |
isDefault | boolean | No | The default warehouse, listed first and preselected for purchase orders. Only one is. |
active | boolean | No | Retired locations (false) are hidden. |
Example
curl -X PATCH "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/inventory/locations/{locationId}" \
-H "Authorization: Bearer $SKUFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Dana Whitfield","address":"string","isDefault":true}'Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | |
organizationId | string | |
name | string | |
address | string or null | |
isDefault | boolean | |
active | boolean | |
createdAt | string (date-time) | |
updatedAt | string (date-time) |
Delete a location
DELETE /organizations/{organizationId}/inventory/locations/{locationId}
Destructive: deletes a location that never held stock or received an order (409 otherwise: retire it with active: false, the ledger is kept).
| Permission | inventory.manage (Owner, Admin, Staff) |
| Risk | sensitive, OAuth scope skuflow.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access. |
| MCP tool | inventoryLocations_delete (toolset pricebook) |
| Plan | Inventory and purchasing: the Pro plan and up. |
| Approval | Over MCP, this tool always waits for your approval in SKUFlow. See Approvals. |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
locationId | path | string | Yes |
Example
curl -X DELETE "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/inventory/locations/{locationId}" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
ok | true |
List stock levels
GET /organizations/{organizationId}/inventory/stock
Stock per item and location, filtered by location, item or text; lowOnly is the Low stock view (at or below the reorder point, or negative). Paged with a total. Read-only.
| Permission | inventory.read (Owner, Admin, Staff, Member) |
| Risk | read, OAuth scope skuflow.read. Read: reads only. |
| MCP tool | inventory_stock (toolset pricebook, in the default set) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
locationId | query | string | No | |
itemId | query | string | No | |
query | query | string | No | Free-text search over the list's names, numbers and contact details. Up to 200 characters. |
lowOnly | query | boolean or enum | No | |
limit | query | integer | No | Page size, 1–200. Default 50. |
offset | query | integer | No | Rows to skip; the answer's total counts every match. Default 0. |
Example
curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/inventory/stock" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
items | array of object | |
items[].id | string | |
items[].organizationId | string | |
items[].itemId | string | |
items[].locationId | string | |
items[].onHand | number | |
items[].reorderPoint | number or null | |
items[].reorderQty | number or null | |
items[].updatedAt | string (date-time) | |
items[].item | object | |
items[].item.id | string | |
items[].item.code | string or null | |
items[].item.name | string | |
items[].item.unit | string | |
items[].item.kind | string | |
items[].item.costCents | integer | Integer cents. Present only for roles with costing.read. |
items[].item.vendorId | string or null | |
items[].item.vendor | object or null | |
items[].item.categoryId | string or null | |
items[].location | object | |
items[].location.id | string | |
items[].location.name | string | |
items[].status | enum | NEGATIVE below zero (allowed, flagged), OUT at 0, LOW at or below the reorder point. One of NEGATIVE, OUT, LOW, OK. |
items[].low | boolean | |
items[].suggestedQuantity | number | What to order when low: the reorder quantity, else enough to clear the point. |
items[].stockValueCents | integer | Integer cents. Present only for roles with costing.read. |
total | integer |
The stock ledger
GET /organizations/{organizationId}/inventory/movements
Stock movements newest first, filtered by item, location, purchase order or kind; each with the signed quantity and the balance after. Append-only. Read-only.
| Permission | inventory.read (Owner, Admin, Staff, Member) |
| Risk | read, OAuth scope skuflow.read. Read: reads only. |
| MCP tool | inventory_movements (toolset pricebook) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
itemId | query | string | No | |
locationId | query | string | No | |
purchaseOrderId | query | string | No | |
kind | query | enum | No | RECEIVE (purchase receipt), TRANSFER_OUT / TRANSFER_IN (the two halves of a transfer), USE (consumed in production or sold), RETURN (back into stock), ADJUST (correction or count). One of RECEIVE, TRANSFER_OUT, TRANSFER_IN, USE, RETURN, ADJUST. |
limit | query | integer | No | Page size, 1–200. Default 50. |
offset | query | integer | No | Rows to skip; the answer's total counts every match. Default 0. |
Example
curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/inventory/movements" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
items | array of object | |
items[].id | string | |
items[].itemId | string | |
items[].locationId | string | |
items[].kind | enum | RECEIVE (purchase receipt), TRANSFER_OUT / TRANSFER_IN (the two halves of a transfer), USE (consumed in production or sold), RETURN (back into stock), ADJUST (correction or count). One of RECEIVE, TRANSFER_OUT, TRANSFER_IN, USE, RETURN, ADJUST. |
items[].quantity | number | Signed: positive into the location, negative out of it. |
items[].balanceAfter | number | The location's on-hand after this movement. |
items[].costCents | integer | Integer cents. Present only for roles with costing.read. |
items[].purchaseOrderId | string or null | |
items[].transferId | string or null | |
items[].userId | string or null | |
items[].reason | string or null | |
items[].createdAt | string (date-time) | |
items[].item | object | |
items[].item.id | string | |
items[].item.code | string or null | |
items[].item.name | string | |
items[].item.unit | string | |
items[].location | object | |
items[].location.id | string | |
items[].location.name | string | |
items[].purchaseOrder | object or null | |
items[].purchaseOrder.id | string | |
items[].purchaseOrder.identifier | string | |
total | integer |
Set a reorder point
PATCH /organizations/{organizationId}/inventory/levels
Sets the reorder point and reorder quantity of an item at a location (null clears them). Stock is not changed (use adjustments). Returns the level.
| Permission | inventory.manage (Owner, Admin, Staff) |
| Risk | write, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it. |
| MCP tool | inventory_setLevel (toolset pricebook) |
| Plan | Inventory and purchasing: the Pro plan and up. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
itemId | string | Yes | A stocked MATERIAL item (GET /pricebook/items). |
locationId | string | Yes | |
reorderPoint | number or null | No | Low at or below this. 0–1000000. |
reorderQty | number or null | No | How many to order. 0–1000000. |
Example
curl -X PATCH "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/inventory/levels" \
-H "Authorization: Bearer $SKUFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"itemId":"item_id","locationId":"location_id"}'Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | |
organizationId | string | |
itemId | string | |
locationId | string | |
onHand | number | |
reorderPoint | number or null | |
reorderQty | number or null | |
updatedAt | string (date-time) | |
item | object | |
item.id | string | |
item.code | string or null | |
item.name | string | |
item.unit | string | |
item.kind | string | |
item.costCents | integer | Integer cents. Present only for roles with costing.read. |
item.vendorId | string or null | |
item.vendor | object or null | |
item.vendor.id | string | |
item.vendor.name | string | |
item.categoryId | string or null | |
location | object | |
location.id | string | |
location.name | string | |
status | enum | NEGATIVE below zero (allowed, flagged), OUT at 0, LOW at or below the reorder point. One of NEGATIVE, OUT, LOW, OK. |
low | boolean | |
suggestedQuantity | number | What to order when low: the reorder quantity, else enough to clear the point. |
stockValueCents | integer | Integer cents. Present only for roles with costing.read. |
Adjust stock
POST /organizations/{organizationId}/inventory/adjustments
Adds (positive) or removes (negative) stock at a location with a reason (damage, found, correction): an ADJUST movement in the ledger. Negative stock is allowed and flagged. Returns the movement and the new level.
| Permission | inventory.manage (Owner, Admin, Staff) |
| Risk | write, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it. |
| MCP tool | inventory_adjust (toolset pricebook) |
| Plan | Inventory and purchasing: the Pro plan and up. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
itemId | string | Yes | |
locationId | string | Yes | |
quantity | number | Yes | Units of the item; may be fractional. -1000000–1000000. |
reason | string | Yes | Why (required). Up to 1000 characters. |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/inventory/adjustments" \
-H "Authorization: Bearer $SKUFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"itemId":"item_id","locationId":"location_id","quantity":1,"reason":"string"}'Response
201: the answer's fields
| Field | Type | Description |
|---|---|---|
movement | object | |
movement.id | string | |
movement.itemId | string | |
movement.locationId | string | |
movement.kind | enum | RECEIVE (purchase receipt), TRANSFER_OUT / TRANSFER_IN (the two halves of a transfer), USE (consumed in production or sold), RETURN (back into stock), ADJUST (correction or count). One of RECEIVE, TRANSFER_OUT, TRANSFER_IN, USE, RETURN, ADJUST. |
movement.quantity | number | Signed: positive into the location, negative out of it. |
movement.balanceAfter | number | The location's on-hand after this movement. |
movement.costCents | integer | Integer cents. Present only for roles with costing.read. |
movement.purchaseOrderId | string or null | |
movement.transferId | string or null | |
movement.userId | string or null | |
movement.reason | string or null | |
movement.createdAt | string (date-time) | |
level | object | |
level.itemId | string | |
level.locationId | string | |
level.onHand | number | |
negative | boolean | The location is below zero now (allowed, flagged). |
Record a stock count
POST /organizations/{organizationId}/inventory/counts
Sets each counted item at a location to what was counted (an ADJUST movement for each difference; unchanged items are not moved). Returns what changed.
| Permission | inventory.manage (Owner, Admin, Staff) |
| Risk | write, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it. |
| MCP tool | inventory_count (toolset pricebook) |
| Plan | Inventory and purchasing: the Pro plan and up. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
locationId | string | Yes | |
counts | array of object | Yes | Up to 1000 items. |
counts[].itemId | string | Yes | |
counts[].counted | number | Yes | -1000000–1000000. |
reason | string or null | No | Defaults to "Stock count". Up to 1000 characters. |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/inventory/counts" \
-H "Authorization: Bearer $SKUFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"locationId":"location_id","counts":[{"itemId":"item_id","counted":1}]}'Response
201: the answer's fields
| Field | Type | Description |
|---|---|---|
counted | integer | |
adjusted | integer | |
lines | array of object | |
lines[].itemId | string | |
lines[].before | number | |
lines[].counted | number | |
lines[].adjustment | number |
Transfer stock between locations
POST /organizations/{organizationId}/inventory/transfers
Moves stock from one location to another (one warehouse restocking another): a TRANSFER_OUT and a TRANSFER_IN per line, sharing a transferId, in one transaction. The source may go negative (flagged). Returns the new levels.
| Permission | inventory.manage (Owner, Admin, Staff) |
| Risk | write, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it. |
| MCP tool | inventory_transfer (toolset pricebook) |
| Plan | Inventory and purchasing: the Pro plan and up. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
fromLocationId | string | Yes | |
toLocationId | string | Yes | |
lines | array of object | Yes | Up to 500 items. |
lines[].itemId | string | Yes | |
lines[].quantity | number | Yes | At most 1000000. |
reason | string or null | No | Up to 1000 characters. |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/inventory/transfers" \
-H "Authorization: Bearer $SKUFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"fromLocationId":"fromLocation_id","toLocationId":"toLocation_id","lines":[{"itemId":"item_id","quantity":1}]}'Response
201: the answer's fields
| Field | Type | Description |
|---|---|---|
transferId | string | |
lines | array of object | |
lines[].itemId | string | |
lines[].quantity | number | |
lines[].fromOnHand | number | |
lines[].toOnHand | number |