Retrieve a message
One message with its body. Retrieving it is what marks it seen.
Runs the real call against your workspace, with your own key.
GET /temp-mail/inboxes/{id}/messages/{messageId}
One message with its body. Retrieving it is what marks it seen.
The inbox token
export OE=https://api.openemail.ukexport INBOX="Authorization: Bearer oe_inbox_kQ8v…"Every call below carries the token POST /temp-mail/inboxes returned, in the same Authorization: Bearer header an API key uses. The address itself authorises nothing, and that separation is the point of the feature rather than a formality: a disposable address is handed to the party you are keeping at arm’s length the moment it is issued.
The id in the path has to name the same inbox the token does. The token alone identifies one, so this is belt and braces, but it means a caller that muddles two inboxes gets a 404 instead of quietly reading the wrong mail.
Example
The row is fetched first and is scoped to the inbox, then the body. Going straight to storage on a caller-supplied id would let anybody holding a message id read any inbox, because a storage key is not a permission.
curl "$OE/temp-mail/inboxes/tinb_9c2f41ab7d3e4c118a0f5d72/messages/tmail_4b81c07d2fa9418e93c6a13f" \ -H "$INBOX"{ "object": "temp_message", "id": "tmail_4b81c07d2fa9418e93c6a13f", "from": { "name": "Acme", "email": "[email protected]" }, "to": "[email protected]", "subject": "Confirm your email", "snippet": "Your code is 481923…", "spam": false, "seen": true, "attachmentCount": 1, "sizeBytes": 8241, "receivedAt": "2026-09-01T10:31:04.000Z", "message": { "decodedBody": "<p>Your code is 481923</p>", "…": "…" }, "truncated": false}Render message.decodedBody. body and processedHtml are empty strings on a locally-ingested message, which is every message that can reach a disposable inbox. Reading either of those and finding nothing is the mistake this note exists to prevent.
message is the same object the real mailbox stores, passed through without projection: the shape IS the storage schema, and a hand-written field list here would be a second description of it that goes stale. It is also attacker-supplied HTML, so render it out of your own origin.
truncated means the body was cut at 2 MB. The message is otherwise intact; nothing was dropped.
A row whose stored body has already been swept answers 404 with "that message has already been cleared" rather than failing three frames later on a parse.