List Stock Movements
Returns a paginated list of stock movements.
Required license
This endpoint requires the Stock management add-on.
Request
GET /api/oauth/v2/resource/wares/movements
Header
| Header | Value |
|---|---|
Authorization | Bearer {access_token} |
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
offset | integer | No | Start position (default: 0) |
limit | integer | No | Number of results (default: 50, max: 200) |
wareId | string (UUID) | No | Filter by a specific ware |
type | string | No | Comma-separated list of movement types (see below) |
direction | string | No | in or out |
from | string (ISO 8601) | No | Only movements on or after this movement date |
until | string (ISO 8601) | No | Only movements on or before this movement date. A date without a time (e.g. 2026-06-30) counts through end of day (23:59:59) |
createdSince | string (ISO 8601) | No | Incremental sync window, start bound |
createdUntil | string (ISO 8601) | No | Incremental sync window, end bound |
Note:
from/untilbound the business date range of a movement,createdSince/createdUntilbound an incremental sync window. Both pairs technically filter the same movement date, but stay independently usable and combine: they are AND-combined, so the narrowest bound wins.fromafteruntilreturns400 validation_error.updatedSince,updatedUntil, anddeletedSinceare not supported on this endpoint and are silently ignored.
Response
Success (200 OK)
Example: outflow from an invoice
{
"data": [
{
"id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"date": "2026-08-20T09:14:00+02:00",
"type": "out_invoice",
"customTypeName": null,
"direction": "out",
"amount": -2,
"stockOld": 26,
"stockNew": 24,
"notice": null,
"ware": "c3d4e5f6-a7b8-9012-cdef-012345678901",
"consumer": null,
"createdBy": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
],
"meta": {
"total": 318,
"offset": 0,
"limit": 50
}
}Example: outflow with a consumer
{
"data": [
{
"id": "e5f6a7b8-c9d0-1234-efab-234567890123",
"date": "2026-08-21T10:05:00+02:00",
"type": "out_customer",
"customTypeName": null,
"direction": "out",
"amount": -1,
"stockOld": 5,
"stockNew": 4,
"notice": null,
"ware": "c3d4e5f6-a7b8-9012-cdef-012345678901",
"consumer": "f0e1d2c3-b4a5-6789-fedc-ba9876543210",
"createdBy": null
}
],
"meta": {
"total": 318,
"offset": 0,
"limit": 50
}
}Response fields
| Field | Type | Description |
|---|---|---|
data | Array | List of stock movements |
data[].id | string (UUID) | Unique ID of the movement |
data[].date | string (ISO 8601) | Date and time of the movement |
data[].type | string | One of the movement types above |
data[].customTypeName | string | null | Display name of a company-specific type. Only set for in_custom / out_custom |
data[].direction | string | in or out |
data[].amount | number | Signed. Equals stockNew - stockOld. Outgoing movements are negative |
data[].stockOld | number | Stock before the movement |
data[].stockNew | number | Stock after the movement |
data[].notice | string | null | Free-text note |
data[].ware | string (UUID) | null | ID of the affected ware, loadable via Get Ware |
data[].consumer | string (UUID) | null | ID of the consumer this movement is attributed to, if applicable |
data[].createdBy | string (UUID) | null | ID of the user who created the movement |
meta.total | integer | Total number of movements |
meta.offset | integer | Current start position |
meta.limit | integer | Number of returned entries |
Note on
amount:amountis signed — outgoing movements are negative. Summingamountacross incoming and outgoing movements without accounting for the sign produces a wrong total.
Note on
inventory: For typeinventory, the direction comes from comparingstockNewagainststockOld— an inventory correction can go either way, the type name alone does not tell you the direction.
Movement types
| Type | Description |
|---|---|
in | Regular stock inflow |
in_invoice_storno | Inflow from a reversed invoice |
in_custom | Company-specific inflow type |
in_purchase | Inflow from a completed purchase order |
inventory | Inventory correction (can be either direction, see below) |
out_invoice | Outflow from an invoice |
out_customer | Outflow assigned to a customer |
out_loss | Outflow due to loss (e.g. breakage, expiry) |
out_other | Other outflow |
out_custom | Company-specific outflow type |
Company-specific types are normalized to in_custom or out_custom. Their original display name is returned in customTypeName.
curl -X GET "https://my.offisy.at/api/oauth/v2/resource/wares/movements?offset=0&limit=50&wareId=b2c3d4e5-f6a7-8901-bcde-f01234567890&type=beispiel&direction=beispiel&from=beispiel&until=beispiel&createdSince=beispiel&createdUntil=beispiel" \
-H "Authorization: Bearer {access_token}"Possible errors
| Status | Code | Description |
|---|---|---|
| 400 | validation_error | Invalid type / direction / wareId value |
| 400 | validation_error | from, until, createdSince, or createdUntil is not a valid ISO 8601 date or date/time |
| 400 | validation_error | from is after until |
| 401 | invalid_client | Invalid or missing access token |
| 403 | insufficient_scope | Scope wares not present, or Stock management add-on not licensed |
| 404 | not_found | Ware for wareId not found or not permitted |