LettrLabs API

Pagination

Which operations page, how the page cursor is numbered, and why there is no total count.

Three list operations page, one does not, and the paging is zero-based with no total count. Getting the first two facts wrong silently skips or repeats records.

Zero-based, and there is no total

pageNumber is an offset in pages starting at 0. The first page is pageNumber=0; passing 1 gives you the second page. A loop written as for (let p = 1; ...) skips the first page entirely and reports nothing wrong.

No list operation returns a total count, a page count, or a has-more flag. Detect the end by a short page: fewer items than pageSize means you have reached the last one.

async function* allOrders(key, pageSize = 100) {
  for (let pageNumber = 0; ; pageNumber++) {
    const response = await fetch(
      `https://app.lettrlabs.com/api/v1/order?pageNumber=${pageNumber}&pageSize=${pageSize}`,
      { headers: { "X-API-KEY": key } },
    );
    const { payload } = await response.json();
    const orders = payload.orders ?? [];

    yield* orders;
    if (orders.length < pageSize) return;
  }
}

The orders.length < pageSize check is the end condition: a page shorter than you asked for is the last one.

Records are ordered newest-first by creation date, and paging is by offset rather than by cursor. So an order created while you are part-way through a walk shifts everything down one place, and you can see the same record twice. For a reconciliation job, prefer filtering to a fixed set of order IDs over walking the whole list.

Which operations page

OperationParametersDefault page size
List orderspageNumber, pageSize100
List an order's recipientspageNumber, pageSize, plus query to filtersee the reference
List conversionsnone — returns everything

There is no maximum enforced on pageSize. A very large value will work until the response is big enough to time out, which surfaces as a 500 rather than as a clear error, so stay near the default and page rather than pulling everything at once.

Filtering instead of paging

For the order listing, filtering is usually better than walking. id accepts a comma-separated list, so if you track order IDs on your side you can fetch exactly the ones you care about:

GET /api/v1/order?id=48213,48214,48215

Filter values are matched by equality and are not validated: a misspelled status or product returns 200 with an empty list rather than an error. Copy values from the reference, where the accepted set for each filter is published.

On this page