Skip to content

Messages

See Reading mail and Sending mail.

EndpointWhat it does
GET /inboxes/:id/messagesMail for one address, newest first, paginated with limit and cursor. Pick a folder with folder: inbox (the default), sent, junk, trash or starred. Returns messages, nextCursor, and total and unread for the whole folder.
GET /messagesMail across several of your addresses in one page, newest first. Name them in inboxIds, comma-separated, up to 500. Takes folder, limit and cursor like the one-address list, and newer, a <receivedAt>~<id> marker for a message you already have, to fetch only what arrived after it; more is then true if more than a page did. Returns messages, nextCursor, more, and counts: total and unread for the whole folder per address, leaving out addresses with none. One request and one read per message returned, however many addresses it spans.
GET /messages/recentThe account’s newest mail in the inbox folder, across every address. limit defaults to 6, at most 50.
GET /messages/:idOne sealed message, in whatever folder it is. Session or API key.
GET /messages/:id/attachments/:indexOne sealed attachment. A paired device can fetch attachments at its own addresses.
POST /messages/:id/readMark as read, or unread with { "read": false }.
POST /messages/:id/starStar, or unstar with { "starred": false }.
POST /messages/:id/moveMove to a folder with { "folder": … }: inbox, junk, trash, or restore to take it out of the trash to where it was. Returns ok and the new folder. Sent mail can only go to the trash and back.
DELETE /messages/:idDelete one message now, with its attachments.
POST /messages/empty-trashDelete everything in the trash now. Returns ok and how many were deleted.
POST /messages/sweepDelete this account’s expired mail now. Returns how many were deleted.
POST /messages/sendSend mail from an address you own. Returns sent, the messageId header it went out with, and sentCopyId, the Sent copy, which is null when no copy was kept. Up to 10 attachments, 3.5 MB between them, and 5 MB for the whole message; program and script files (.exe, .js, .jar and the like) are refused with 400 attachment_blocked. See Sending mail for the fields and who may send.
POST /messagesDeliver a message you sealed yourself to one of your addresses. Takes a client-generated id (msg_…), inboxId, the sealed content, sizeBytes, and optionally messageIdHash, receivedAt and keyEpoch (0 by default, never past the address’s keyEpoch). receivedAt must be an ISO time, 400 invalid_field otherwise, and a time later than now is stored as now. sizeBytes is at least 1024 and cannot be much larger than content. A repeated messageIdHash on the same address is 409 duplicate. Counts toward the monthly allowance. Returns id, inboxId, receivedAt, read and sizeBytes, and held: true while the address is paused.
GET /workers/messagesThe calling device’s mail, up to 200. Takes folder like the address list, and inboxId or inboxIds, id, before, newer, after, since and wait; see Devices. Device credential only.

Read, star, move, delete, empty-trash and attachment downloads work with a session, an API key, or the device credential of the device that holds the address. A device reaches only the mail at its own addresses; anything else is 404.

A message returns:

{
"id": "msg_91be02c4a7d1",
"inboxId": "ibx_k3v9x2mq7a",
"receivedAt": "2026-09-18T09:14:03.000Z",
"read": false,
"sizeBytes": 18432,
"folder": "inbox",
"starred": false,
"keyEpoch": 0,
"content": { "…": "sealed" }
}

A message in the Sent folder also has sentVia: app (a session), api (an API key), device, agent or member (a team member). keyEpoch is the key epoch it was sealed under.

© Northlab Studios Ltd, trading as Mailcycle. Registered in England and Wales, company no. 17462734. Registered office: 167-169 Great Portland Street, London W1W 5PF.