Skip to content

Pagination ​

Tables paginate with offset and limit. There are no cursors.

bash
curl "https://api.app.tightly.io/api/v1/inventory/table?offset=0&limit=100" \
  -H "Authorization: Bearer $TIGHTLY_API_KEY"

What comes back ​

json
{
  "data": {
    "rows": [],
    "size": 100,
    "offset": 0,
    "filtered_max_size": 4120
  }
}
FieldWhat it is
rowsThe page.
sizeHow many rows this page carries.
offsetThe offset this page was read at, echoed back.
filtered_max_sizeHow many rows the whole filtered set holds. This is the total to walk to.

Some tables also return filtered_max_unique_size, which is the count after a distinct. Where both are present, walk against the one that matches the grain you asked for.

Walking a whole table ​

js
async function* everyRow(url, key, pageSize = 100) {
  let offset = 0
  let total = Infinity

  while (offset < total) {
    const response = await fetch(`${url}?offset=${offset}&limit=${pageSize}`, {
      headers: { Authorization: `Bearer ${key}` },
    })
    const { data } = await response.json()

    total = data.filtered_max_size
    yield * data.rows
    if (data.rows.length === 0) break
    offset += data.rows.length
  }
}

Two details that matter:

  • Advance by rows.length, not by pageSize. An operation may return fewer rows than asked for, and advancing by the request would skip whatever it held back.
  • Stop on an empty page as well as on the total. The table is live: rows can be deleted between two pages, and a walk anchored only on the first total can run past the end.

A walk over a table that is changing under you will see the change. If you need a consistent view of a large table, read it in one page where the size allows, or take the export.

The caps ​

CapValueWhat happens at it
limit10,000 across the APIA larger limit is refused.
offsetBelow 2,147,483,647A larger offset is refused.
Export rows100,000An export that would exceed it is refused, never truncated.

Per-operation defaults and maxima are stated on each operation in the reference, and they are what a walk should be sized against. Nine reads take the global cap of 10,000 in one page - products, variants, suppliers, supplier contacts, both stocktake tables, the stock ledger, invoices and EDI documents - so a catalogue or a count can be read whole rather than walked. Three cap at 500: the sales order list, the product catalogue's PIM read and the product filters. Everything else that states a maximum caps at 100, and most of those default to a page of 8.

The export cap refuses rather than truncates on purpose: somebody handed 100,000 of 150,000 rows with no warning has wrong data and no way to know it.

Filtering before you paginate ​

Most tables take filter_args, a JSON array of {key, operation, value}:

bash
curl -G "https://api.app.tightly.io/api/v1/inventory/table" \
  -H "Authorization: Bearer $TIGHTLY_API_KEY" \
  --data-urlencode 'filter_args=[{"key":"tags","operation":"in","value":["stocked_out","understocked"]}]' \
  --data-urlencode 'limit=100'

Each table publishes its own allowlist of keys and operations on the operation's schema in the reference, and refuses any key that is not on it. Filtering server-side is nearly always cheaper than walking the table and filtering in your own process, and it spends far less of your rate limit.

Several tables also serve a .../filters operation that returns the values and ranges the table can be filtered on, which is the honest way to build a filter without hard-coding a list that changes.

Sorting ​

Where an operation supports sorting it takes sort_args: a comma-separated list of columns, each prefixed with - for descending or + (or nothing) for ascending. The columns an operation sorts on are named on the operation.

bash
curl -G "https://api.app.tightly.io/api/v1/organizations/$ORG/purchase-orders" \
  -H "Authorization: Bearer $TIGHTLY_API_KEY" \
  --data-urlencode 'sort_args=+name,-expected_delivery_date'

There is no default order guarantee across pages for an operation that does not name one, so a walk that must be stable should ask for a sort.

Tightly API, version 2026-11.