Pagination
A list that can be long comes a page at a time, with a cursor for the next page. That’s the whole contract: follow nextCursor until it’s null.
Following a cursor
Response
{
"data": [ … ],
"nextCursor": "2026-09-26T15:42:10.000Z|a41c93f0"
}Pass nextCursor back unchanged as cursor to get the next page. Treat it as opaque: don’t take it apart or make one up, because what’s inside may change.
limit sets the size of a page, from 1 to 200, and is 50 if you leave it out. A value out of range is refused rather than capped, because a capped page would look like the last one.
JavaScript
let cursor = null
do {
const url = new URL('https://app.dmu.email/api/v1/threads')
url.searchParams.set('view', 'inbox')
if (cursor) url.searchParams.set('cursor', cursor)
const response = await fetch(url, { headers: { Authorization: `Bearer ${key}` } })
const page = await response.json()
for (const thread of page.data) handle(thread)
cursor = page.nextCursor
} while (cursor)Which lists page
Only List threads pages today. The other lists, of mailboxes, labels, drafts, saved replies and the rest, are short enough to come back whole, without a nextCursor.
A search with q returns one page of the best matches with nextCursor null, because results ranked by relevance have no “next”. A q of labels alone pages like a view.