Skip to main content
Every list returns the same envelope, whatever it is listing:
Two query parameters control it, and they are the same everywhere:
Read total when you need to size a job before you start it, and hasMore to know when to stop. Do not infer the end of a list from a short page: a filtered page can be short and still have more behind it.

Ordering

Every list has a fixed order, and only one of them lets you change it. Paging is only stable because the order is.

Filtering

Most lists take limit and offset and nothing else. Six take a filter, measured against the published OpenAPI document on 2026-09-06: Chronology events is the exception on purpose: a timeline is the one surface here you narrow rather than page. It takes dateFrom, dateTo, eventTypes, categories, significance, documentId, isAiExtracted, minConfidence, searchQuery, party and primaryOnly, and it is the only list with sortBy and sortOrder. Nothing else has a search, a date range, a status filter or a sort parameter, and that is a deliberate cut rather than an omission. If you need “every matter touched since yesterday”, page the list and filter client-side, or hold your own index keyed on the ids we return.

Why offsets and not cursors

Cursor pagination is better under concurrent writes, and it was deliberately left out. It is a second contract to keep stable, it makes “how many are there” impossible to answer cheaply, and the lists here are firm-sized rather than internet-sized. The tradeoff you inherit: if rows are created while you are paging, a deep offset can skip or repeat a row. For a nightly sync over a few thousand matters that is invisible. If it is not invisible for your workload, page fastest-first with a large limit and reconcile on ids rather than on position.
Last modified on September 6, 2026