Inventory API
Required scope: inventory:read (read) · inventory:write (write)
Stock Levels
Stock levels are included in the Products API response (which needs products:read):
current_stock— Total stock on handin_stock— Whether the product is in stocklow_stock_threshold— Threshold for low-stock alerts
For products with variations, each variation includes its own current_stock.
List Stock Adjustments
GET /api/v1/stock_adjustments
Required scope: inventory:read
Returns the stock adjustment ledger — every recorded movement, newest first, with the quantity before and after. This is the audit trail behind a stock number: if the count changed, one of these rows says why.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number (default: 1) |
per_page | integer | Results per page (default: 100, max: 100) |
product_id | integer | Only adjustments for this product |
warehouse_location_id | integer | Only adjustments at this stock location |
adjustment_type | string | Filter by type, e.g. sale, void, receive, count, inventory, spoilage, damage, transfer_in, transfer_out |
since | ISO 8601 | Adjustments created after this timestamp (exclusive) |
until | ISO 8601 | Adjustments created up to and including this timestamp |
since and until filter on when the adjustment was recorded. A value that cannot be parsed returns 422 Unprocessable Entity (since must be a valid timestamp).
Example
curl -H "X-API-Key: bpos_..." \
"https://yourstore.brotherpos.ca/api/v1/stock_adjustments?product_id=1&since=2026-08-01T00:00:00Z"
Response
{
"data": [
{
"id": 101,
"product_id": 1,
"product_name": "Blue Dream 3.5g",
"sku": "BD-35",
"adjustment_type": "receive",
"quantity_change": 26.0,
"quantity_before": 24.0,
"quantity_after": 50.0,
"reason": "Weekly shipment received",
"notes": null,
"user": { "id": 4, "name": "Dana R." },
"approved_by": null,
"warehouse_location": null,
"reconciliation_id": null,
"created_at": "2026-08-14T14:30:00.000Z"
}
],
"pagination": { "current_page": 1, "per_page": 100, "total_count": 37, "total_pages": 1 },
"meta": { "request_id": "...", "timestamp": "2026-08-19T12:00:00Z" }
}
| Field | Type | Notes |
|---|---|---|
quantity_change | number | Signed — negative for stock removed |
quantity_before / quantity_after | number | Stock on hand either side of the movement |
user | object or null | Who made the adjustment. Adjustments made through an API key show the admin who created the key. |
approved_by | object or null | Who approved it, where approval applies |
warehouse_location | object or null | { "id", "name" } of the stock location, when one was recorded |
reconciliation_id | integer or null | Set when the row came from a stock count reconciliation rather than a one-off adjustment |
since as a reconciliation cursorStore the timestamp of your last successful pull and pass it as since on the next run, so you only fetch new movements. See Recommended Sync Architecture.
Create a Stock Adjustment
POST /api/v1/stock_adjustments
Required scope: inventory:write
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
product_id | integer | yes | The product to adjust |
adjustment_type | string | yes | One of: receive, count, inventory, spoilage, damage, reweigh, moisture_loss |
quantity_change | decimal | yes, except for inventory | The quantity to add (positive) or remove (negative). Zero is rejected. |
counted_quantity | decimal | for inventory | The quantity actually counted. The API records the difference from current stock as the change. Must not be negative. |
warehouse_location_id | integer | no | The stock location the movement applies to (not allowed for bundle products) |
reason | string | no | Reason for the adjustment |
The parameters are sent at the top level of the body, not wrapped in an object.
Example
curl -X POST \
-H "X-API-Key: bpos_..." \
-H "Content-Type: application/json" \
-d '{
"product_id": 1,
"adjustment_type": "receive",
"quantity_change": 26.0,
"reason": "Weekly shipment received"
}' \
https://yourstore.brotherpos.ca/api/v1/stock_adjustments
Response
201 Created:
{
"data": {
"id": 101,
"product_id": 1,
"product_name": "Blue Dream 3.5g",
"adjustment_type": "receive",
"quantity_change": 26.0,
"quantity_before": 24.0,
"quantity_after": 50.0,
"reason": "Weekly shipment received",
"warehouse_location_id": null,
"warehouse_location_name": null,
"created_at": "2026-03-22T14:30:00.000Z"
},
"meta": { ... }
}
When the store tracks stock by location, the response also includes floor_stock and back_stock.
An unknown adjustment_type, a zero quantity_change, or a negative counted_quantity returns 422. An unknown product_id returns 404.
What's Next?
- Purchasing & Receiving — What was ordered, invoiced, and what actually arrived
- Products — Stock levels, and cost behind the
costs:readscope