Skip to main content

Pagination

Lists are the one place we don't strip the envelope. Every list() call returns { data, pagination, hasMore } because the page metadata is part of the answer, not metadata about it.

List shape

Page params

Pass page and pageSize on any list call. Defaults: page 1, pageSize 20, max pageSize 100.

paginate.js
// First page
const { data, pagination, hasMore } = await cstar.tickets.list({
  status: 'open',
  page: 1,
  pageSize: 20
});

console.log(`Page ${pagination.page} — ${data.length} of ${pagination.total} tickets`);

if (hasMore) {
  // Fetch the next page
  const next = await cstar.tickets.list({ status: 'open', page: 2, pageSize: 20 });
}

Walk every page

hasMore is the loop sentinel. Drive a while loop off it instead of comparing computed totals — pagination math drifts if rows are written between requests.

walk-all.js
async function* allTickets(filter) {
  let page = 1;
  while (true) {
    const { data, hasMore } = await cstar.tickets.list({ ...filter, page, pageSize: 100 });
    yield* data;
    if (!hasMore) return;
    page += 1;
  }
}

for await (const ticket of allTickets({ status: 'open' })) {
  await mirrorToWarehouse(ticket);
}

Pagination on lastMeta

The same pagination object also lands on cstar.lastMeta.pagination after every list call, so middleware that wraps the SDK can grab it without re-reading the response shape.

Next up