Endpoint details
All paths are relative to /api/index.php/v1/nextinventory. Scope is what the token must
hold. The token owner's role must also allow the action (for example transactions.checkout
to check items out). The OpenAPI document
has every field.
Items
| Method | Path | Scope | Notes |
|---|---|---|---|
| GET | /items |
items:read |
Filters: search, category_id, warehouse_id, item_type, low_stock=1, published |
| POST | /items |
items:write |
Required: title, item_type (asset, consumable, sellable), category_id, stock_quantity, low_stock_threshold (0 for none) |
| GET | /items/{id} |
items:read |
Includes custom_fields |
| PATCH | /items/{id} |
items:write |
Only the fields sent |
| DELETE | /items/{id} |
items:delete |
|
| GET | /items/{id}/transactions |
transactions:read |
That item's ledger |
| GET | /items/{id}/cost-layers |
items:read |
FIFO/LIFO layers and value |
| POST | /items/{id}/image |
items:write |
multipart/form-data, field image. Replaces the image, makes thumbnails |
| DELETE | /items/{id}/image |
items:write |
Removes the image |
Barcode and SKU lookup
| Method | Path | Scope | Notes |
|---|---|---|---|
| GET | /lookup/barcode?barcode=… |
lookups:read |
Exact match on a published item; 404 if none |
| GET | /lookup/sku?sku=… |
lookups:read |
Exact match; 404 if none |
| GET | /lookup/search?q=… |
lookups:read |
Up to 10 matches on title, SKU, barcode, serial |
Categories, warehouses, recipients, units
Each has the same six endpoints. Replace categories with warehouses, recipients or units,
and the scope area to match.
| Method | Path | Scope |
|---|---|---|
| GET | /categories |
categories:read |
| POST | /categories |
categories:write |
| GET | /categories/{id} |
categories:read |
| PATCH | /categories/{id} |
categories:write |
| DELETE | /categories/{id} |
categories:delete |
| POST | /categories/{id}/status |
categories:write, body { "published": true } |
Extras: GET /warehouses/{id}/inventory (items in one warehouse) and
GET /units/{id}/conversion-chain. GET /warehouses/{id} and GET /recipients/{id} include
their custom_fields as an object of field name to value.
Custom fields
| Method | Path | Scope | Notes |
|---|---|---|---|
| GET | /custom-fields?context=item |
customfields:read |
The published definitions for item, warehouse or recipient: name, label, type, options, required |
Write a value as cf_<name> on the entity's POST or PATCH.
Stock movements
| Method | Path | Scope | Notes |
|---|---|---|---|
| GET | /stock-movement-types |
stock:read |
The types the token owner may record |
| GET | /stock-movements |
stock:read |
Filters: movement_type, is_draft, warehouse_id, recipient_id, date_from, date_to |
| POST | /stock-movements |
stock:write |
See below |
| GET | /stock-movements/{id} |
stock:read |
With its lines |
| DELETE | /stock-movements/{id} |
stock:write |
Drafts only |
| POST | /stock-movements/{id}/finalize |
stock:write |
Applies the stock change |
movement_type is one of:
| Type | Effect | Item types | Role permission |
|---|---|---|---|
check_in |
+ stock | assets | transactions.checkin |
check_out |
− stock; needs recipient_id |
assets | transactions.checkout |
add_stock |
+ stock | consumables, sellables | transactions.add_stock |
remove_stock |
− stock | consumables, sellables | transactions.remove_stock |
A movement that would take an item below zero is refused with 400, and so is finalizing one.
cost_per_unit on a line sets the cost layer for an increase under FIFO/LIFO; without it the
item's unit price is used.
{
"movement_type": "check_out",
"is_draft": false,
"movement_date": "2026-11-11",
"warehouse_id": 1,
"recipient_id": 5,
"details": "Laptop for new starter",
"items": [ { "item_id": 23, "quantity": 1 } ]
}
Transactions (the ledger)
| Method | Path | Scope |
|---|---|---|
| GET | /transactions |
transactions:read |
| GET | /transactions/{id} |
transactions:read |
Read-only. Rows from one movement, transfer or adjustment share a batch_id.
Transfers and adjustments
| Method | Path | Scope |
|---|---|---|
| GET | /transfers |
transfers:read |
| POST | /transfers |
transfers:write |
| GET | /transfers/{id} |
transfers:read |
| DELETE | /transfers/{id} |
transfers:write (drafts only) |
| POST | /transfers/{id}/finalize |
transfers:write |
| GET | /adjustment-types |
adjustments:read |
| GET / POST | /adjustments |
adjustments:read / adjustments:write |
| GET / DELETE | /adjustments/{id} |
adjustments:read / adjustments:write |
| POST | /adjustments/{id}/finalize |
adjustments:write |
Both need the matching app on in App Manager and the role permission
inventory.manage_transfers or inventory.manage_adjustments.
Reports
All GET, scope reports:read, role permission reports.view:
/reports/stock-valuation, /reports/low-stock, /reports/stock-by-warehouse,
/reports/stock-by-type, /reports/stock-movement, /reports/transaction-trends,
/reports/kpi-trends, /reports/top-performers, /reports/category-drilldown?category_id=…,
/reports/cogs, /reports/inventory-aging.
Report bodies have the shape the Reports screen uses. They may gain fields in minor versions.
Not available to tokens
Settings, roles, App Manager, demo data, notifications, creating or editing custom-field definitions, CSV exports, and API tokens and webhooks themselves stay with a signed-in administrator.