Base URL
https://app.dmu.email/api/v1
Authentication
Bearer dmk_… API key
Rate limit
120 requests a minute per key

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.