Pagination

Page through list operations with limit and cursor, or let the SDK's paginate helper follow the cursors for you.

List operations answer a page of items and a nextCursor. Pass the cursor back to read the next page until it is null.

List envelopes

Listings answer one of two envelopes:

EnvelopeUsed by
{ items, nextCursor }Paged lists: accounts, messages, threads, the outbox, calendar events, contacts, templates, webhook attempts and more.
{ items }Small bounded lists, answered whole: mailboxes, calendars, contact folders, suppression lists, webhook endpoints, mail merge results.

Read the next page

Pass nextCursor back as cursor. It is null on the last page.

curl "https://api.workwae.com/v1/accounts?limit=200" \
  -H "Authorization: Bearer $WORKWAE_API_KEY"
# { "items": [...], "nextCursor": "eyJ..." }

curl "https://api.workwae.com/v1/accounts?limit=200&cursor=eyJ..." \
  -H "Authorization: Bearer $WORKWAE_API_KEY"
# { "items": [...], "nextCursor": null }
  • A cursor is opaque. Do not build or edit one.
  • A cursor belongs to its listing and its filters: pass the same filters with it.
  • A cursor the listing did not issue answers 400 invalid_cursor.

Page size

limit sets the page size. Where an operation names no other size, the default is 50 and the maximum 200.

ListingDefaultMaximum
Most listings50200
Threads25100
Message search25100
Calendar events100500
Contacts100500
Webhook delivery attempts50500
Organization directory entries100200
Scheduling links1001,000

Each operation's reference entry states its range.

Iterate with the SDK

The TypeScript SDK follows cursors for you. Pass the list method itself, so the item type and filters come from the API contract.

TypeScript
import { pages, paginate } from "@workwae/sdk";

// Every item, following nextCursor to the last page.
for await (const account of paginate(workwae.accounts.list, { limit: 200 })) {
  console.log(account.id);
}

// Page by page, e.g. to checkpoint the cursor.
for await (const page of pages(workwae.messages.list, { accountId, unread: true })) {
  await saveCursor(page.nextCursor);
}

Both helpers accept a third { signal } argument, forwarded to every call they make.

The change feed

GET /v1/changes uses the same envelope but never ends: its nextCursor is always set, and an empty page means you are caught up. Read it with the SDK's changes helper; see Change feed.

On this page