---
title: "The stock ledger, newest first"
method: GET
path: "/api/v1/inventory/movements"
tags: ["movements"]
---

# The stock ledger, newest first

`GET /api/v1/inventory/movements`

## Request

- Base URL: `https://api.app.tightly.io`
- URL: `https://api.app.tightly.io/api/v1/inventory/movements`
- Auth: HTTP bearer

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.

With no filter the page is the organisation's latest movements across every product and warehouse. Name a product and a warehouse, a document (`document_type` with `document_id`), a kind or a window to narrow it; every filter narrows the ledger itself, so `filtered_max_size` counts the matching rows.

Sums are the point. The rows for one product at one warehouse sum to that pair's on hand, which is what `get_position` serves as one figure. `evidence` rides a `sync_correction` alone, where it carries the source's snapshot, the ledger's sum and how many nights running they disagreed.

Nothing writes here, ever. A movement is written by the document that moved the stock; correcting one is a reversing movement against it, not an edit.

Scope: `movements:read`.

## Query parameters

- `variant_id` string
- `location_id` string
- `document_type` string
- `document_id` string
- `kind` string
- `since` string, date-time
- `until` string, date-time
- `offset` integer
- `limit` integer

## Headers

- `Tightly-Version` string

## Response `200`

A page of the ledger, newest first.

- object
  - `data` object
    - `filtered_max_size` integer
    - `max_size` integer
    - `offset` integer
    - `rows` object[]
    - `size` integer
  - `message` object: severity, service and desc.

## Other responses

- `400`: A kind, document type, instant (`since`, `until`) or page bound could not be read.
- `401`: No usable key: malformed, unknown, revoked, expired or stopped.
- `403`: The key does not hold Movements (`scope_missing`).
- `429`: The key has spent its allowance for this minute. 600 reads and 120 writes a minute, counted per key, refused calls included. `Retry-After` says how long to wait.
- `503`: The database is briefly out of reach, which is what a failover or a full connection pool looks like from outside. Wait the seconds `Retry-After` names and send the request again. A read is safe to repeat. A write is not, because the connection was lost in the middle of it, so read the object back before sending it a second time. Branch on the status rather than on `code`, which is `POSTGRES_UNAVAILABLE` from one of the two seams that raise this and `SERVICE_UNAVAILABLE` from the other.

---

[API](https://skmtc.dev/tightly/apis/tightly-api.md) · [All operations](https://skmtc.dev/tightly/apis/tightly-api/llms.txt) · [OpenAPI document](https://skmtc.dev/tightly/apis/tightly-api/revisions/199f7eb35afb?raw)
