Pagination

ListPromise, Page, and autoPagingIterator. Cursor-based pagination across every list endpoint.

Every mb.<resource>.list(...) method returns a ListPromise<T>. A thenable that resolves to the first page when awaited, with an autoPagingIterator() for walking every page.

Page Shape

import { Page } from "@medblocks/connect";

class Page<T> {
  readonly data: T[];
  readonly has_more: boolean;
  readonly next_cursor: string | null;
}

data is the items on the current page. has_more is true when at least one more page exists. next_cursor is the cursor for the next starting_after request (or null when terminal).

Awaiting The First Page

server/scripts/first-page.ts
const page = await mb.patients.list({ limit: 50 });

for (const patient of page.data) {
  console.log(patient.id);
}

if (page.has_more) {
  console.log("more available at cursor:", page.next_cursor);
}

autoPagingIterator

for await walks every page automatically. The SDK calls fetchPage(cursor) until has_more is false or next_cursor is null.

server/scripts/all-patients.ts
let count = 0;
for await (const patient of mb.patients.list({ limit: 100 }).autoPagingIterator()) {
  count += 1;
  // process patient...
}
console.log(`${count} patients total`);

This pattern works across every paginated resource:

for await (const flow of mb.patients.listPatientFlows("user_42").autoPagingIterator()) { /* ... */ }
for await (const ehr of mb.connections.list({ q: "epic" }).autoPagingIterator()) { /* ... */ }
for await (const ep of mb.webhooks.list({ status: "active" }).autoPagingIterator()) { /* ... */ }
for await (const evt of mb.webhooks.listEvents("wh_*").autoPagingIterator()) { /* ... */ }

Manual Cursor Walks

If you need full control. For example, to checkpoint progress in durable storage. Drive the cursor yourself by re-calling list with starting_after.

server/scripts/walk-with-checkpoint.ts
let cursor: string | null = await checkpoint.read();

while (true) {
  const page = await mb.patients.list({ limit: 100, starting_after: cursor ?? undefined });
  for (const p of page.data) await process(p);
  if (!page.has_more || !page.next_cursor) break;
  cursor = page.next_cursor;
  await checkpoint.write(cursor);
}

Limits And Defaults

ParamDefaultRange
limit101 – 100
starting_afternoneCursor returned by a previous page’s next_cursor

Some lists accept additional filters (status, type, q). See each resource page for the per-endpoint list.

Caching The First Page

A ListPromise caches its first page internally, so multiple awaits do not refetch:

const lp = mb.patients.list({ limit: 50 });
const a = await lp;
const b = await lp;
// only one network request was made

autoPagingIterator() uses the same cached first page and then fetches subsequent pages as it walks.