Appearance
Movements
1 read, no writes, on train 2026-11. Scopes: movements:read.
| Operation | Method | Scope | Path |
|---|---|---|---|
| The stock ledger | GET | movements:read | /api/v1/inventory/movements |
The stock ledger
GET /api/v1/inventory/movements
Scopes: movements:read
Every plus and minus of stock, newest first, each naming the document that caused it: a receipt, a count, a fulfilment, a return, an adjustment, a transfer leg, the opening the ledger started from, or a correction the nightly sweep booked against a source that disagreed.
| Optional | In | What it is |
|---|---|---|
variant_id | query | The product. Required unless a document is named. |
location_id | query | The warehouse. Required unless a document is named. |
document_type | query | One of ledger_opening, purchase_order_delivery, transfer_order_delivery, stocktake, fulfilment_request, channel_fulfilment, return, |
document_id | query | The document's own id, as text. Sent with document_type. |
kind | query | Comma-separated movement kinds to filter to: opening, receipt, fulfilment, return, adjustment, transfer_out, transfer_in, stocktake, |
since | query | Only movements that occurred at or after this instant. |
until | query | Only movements that occurred at or before this instant. |
offset | query | How many movements to skip, for paging through a long ledger. |
limit | query | How many movements to return, newest first. |
Tightly-Version | header | The date train to answer on. |
bash
curl "https://api.app.tightly.io/api/v1/inventory/movements" \
-H "Authorization: Bearer $TIGHTLY_API_KEY"What it answers
json
{
"data": {
"filtered_max_size": 13,
"max_size": 13,
"offset": 0,
"rows": [
{
"actor": null,
"document": {
"id": "31",
"name": "RET-00000031",
"type": "return"
},
"document_line_id": "54",
"evidence": null,
"id": 9013,
"kind": "return",
"landed_unit_cost": {
"cents": null,
"currency": null,
"reason": "Not measured",
"usd": null
},
"location_id": "loc-lb",
"location_name": "Long Beach",
"occurred_at": "2026-09-05T02:14:00+00:00",
"quantity_delta": 2,
"recorded_at": "2026-09-05T02:14:03+00:00",
"reverses_movement_id": null,
"sequence": 1,
"sku": "MAR-TOP-M",
"source_system": "shopify",
"unit_cost": {
"cents": 1200,
"currency": "USD",
"reason": null,
"usd": 12
},
"variant_id": "fx-v-mar-top-m"
}
…
]
}
}What it refuses
- 400
filter_needs_a_pair_or_a_document: "A movements read names a product and a warehouse, or a document; this one names neither." The filter names neither a product and a warehouse nor a document (filter_needs_a_pair_or_a_document), or a kind, document type, instant (since,until) or page bound could not be read. - 401
key_invalid: "The API key is not valid." No usable key: malformed, unknown, revoked, expired or stopped. - 403
scope_missing: "This key cannot read Movements." The key does not hold Movements (scope_missing). - 429