Documentation menu
API reference
Messages
Captured emails.
List messages in an inbox
GET/v1/inboxes/{id}/messages
Newest first, as summaries (no body, headers or attachment list; fetch one message for those). Filters combine with AND.
Path parameters
- idstringrequiredInbox ID.
Query parameters
- qstringSearch. Free text matches subject, sender, recipients and body. Also supports
from:,to:,subject:,is:unread,is:read,is:tagged,tag:name,has:attachment,larger:1m,after:/before:, negation with-or!, and"exact phrases". - fromstringSender contains this text.
- tostringAny recipient contains this text.
- subjectstringSubject contains this text.
- sincestring (date-time)Only messages received at or after this time.
- limitintegerPage size.
- cursorstringThe
next_cursorfrom the previous page.
Returns a list of
- idstringrequired
- inbox_idstringrequired
- received_atstring (date-time)required
- envelope_fromstringrequiredThe SMTP
MAIL FROM. - recipientsarray of stringsrequiredThe SMTP
RCPT TOaddresses, including Bcc. - fromstringrequiredThe
Fromheader. - tostringrequiredThe
Toheader. - subjectstringrequired
- message_idstringrequiredThe
Message-IDheader. - sizeintegerrequiredSize in bytes.
- has_textbooleanrequired
- has_htmlbooleanrequired
- attachment_countintegerrequired
- link_countintegerrequired
- tlsbooleanrequiredWhether the sender used TLS.
- parse_errorstringSet when the message is not valid MIME. Parts may be missing.
- readbooleanrequired
- tagsarray of stringsrequired
Errors
curl "https://app.mailbench.dev/v1/inboxes/box_g3bekcev4z7i4psq/messages" \
-H "Authorization: Bearer $API_KEY"const res = await fetch("https://app.mailbench.dev/v1/inboxes/box_g3bekcev4z7i4psq/messages", {
headers: {
Authorization: `Bearer ${process.env.API_KEY}`,
},
});
const { data } = await res.json();import os, requests
res = requests.get(
"https://app.mailbench.dev/v1/inboxes/box_g3bekcev4z7i4psq/messages",
headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
)
data = res.json()["data"]{
"success": true,
"data": [
{
"id": "msg_htumcicppd26jek6",
"inbox_id": "box_g3bekcev4z7i4psq",
"received_at": "2026-10-12T10:00:00Z",
"envelope_from": "noreply@app.test",
"recipients": [
"sam@example.org"
],
"from": "App <noreply@app.test>",
"to": "Sam <sam@example.org>",
"subject": "Welcome aboard",
"message_id": "<8f2c1a@app.test>",
"size": 1432,
"has_text": true,
"has_html": true,
"attachment_count": 0,
"link_count": 2,
"tls": true,
"parse_error": "string",
"read": false,
"tags": [
"billing"
]
}
],
"next_cursor": "string"
}Stream new messages (server-sent events)
GET/v1/inboxes/{id}/events
Keeps the connection open and sends one message event per new email, with the
message summary as JSON in data and a cursor in id. Reconnect with
Last-Event-ID to resume without gaps. The server ends a stream after about
30 minutes; reconnect.
Path parameters
- idstringrequiredInbox ID.
Headers
- Last-Event-IDstring
Returns
An `text/event-stream`.
Errors
curl -N "https://app.mailbench.dev/v1/inboxes/box_g3bekcev4z7i4psq/events" \
-H "Authorization: Bearer $API_KEY"const res = await fetch("https://app.mailbench.dev/v1/inboxes/box_g3bekcev4z7i4psq/events", {
headers: {
Authorization: `Bearer ${process.env.API_KEY}`,
},
});
const body = await res.text();import os, requests
res = requests.get(
"https://app.mailbench.dev/v1/inboxes/box_g3bekcev4z7i4psq/events",
headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
)
body = res.textGet a message in full
GET/v1/messages/{id}
Includes text and HTML bodies, headers, extracted links, attachments and
short-lived signed URLs (files) that a browser can open without an
Authorization header.
Path parameters
- idstringrequiredMessage ID.
Returns
- idstringrequired
- inbox_idstringrequired
- received_atstring (date-time)required
- envelope_fromstringrequiredThe SMTP
MAIL FROM. - recipientsarray of stringsrequiredThe SMTP
RCPT TOaddresses, including Bcc. - fromstringrequiredThe
Fromheader. - tostringrequiredThe
Toheader. - subjectstringrequired
- message_idstringrequiredThe
Message-IDheader. - sizeintegerrequiredSize in bytes.
- has_textbooleanrequired
- has_htmlbooleanrequired
- attachment_countintegerrequired
- link_countintegerrequired
- tlsbooleanrequiredWhether the sender used TLS.
- parse_errorstringSet when the message is not valid MIME. Parts may be missing.
- readbooleanrequired
- tagsarray of stringsrequired
- textstring
- htmlstring
- linksarray of stringsrequired
- headersobject
- attachmentsarray of objectsrequired
Child attributes
- indexintegerrequired
- filenamestringrequired
- content_typestringrequired
- sizeintegerrequired
- urlstringrequiredPath to download it (needs your API key).
- thumb_urlstringPath to a thumbnail, for images.
- raw_urlstringrequiredPath to the raw
.eml. - html_urlstringPath to the HTML body, when there is one.
- filesobjectrequiredSigned, expiring URLs a browser can open without an
Authorizationheader.Child attributes
- rawstring (uri)required
- htmlstring (uri)
- attachmentsarray of stringsrequired
- thumbnailsarray of strings
- expires_atstring (date-time)required
- list_unsubscribeobjectParsed
List-Unsubscribeheaders, when present.Child attributes
- headerstring
- header_poststring
- linksarray of strings
- errorsstring
Errors
curl "https://app.mailbench.dev/v1/messages/msg_htumcicppd26jek6" \
-H "Authorization: Bearer $API_KEY"const res = await fetch("https://app.mailbench.dev/v1/messages/msg_htumcicppd26jek6", {
headers: {
Authorization: `Bearer ${process.env.API_KEY}`,
},
});
const { data } = await res.json();import os, requests
res = requests.get(
"https://app.mailbench.dev/v1/messages/msg_htumcicppd26jek6",
headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
)
data = res.json()["data"]{
"success": true,
"data": {
"id": "msg_htumcicppd26jek6",
"inbox_id": "box_g3bekcev4z7i4psq",
"received_at": "2026-10-12T10:00:00Z",
"envelope_from": "noreply@app.test",
"recipients": [
"sam@example.org"
],
"from": "App <noreply@app.test>",
"to": "Sam <sam@example.org>",
"subject": "Welcome aboard",
"message_id": "<8f2c1a@app.test>",
"size": 1432,
"has_text": true,
"has_html": true,
"attachment_count": 0,
"link_count": 2,
"tls": true,
"parse_error": "string",
"read": false,
"tags": [
"billing"
],
"text": "Click https://app.test/verify/abc123 to confirm your address.",
"html": "<p>Click <a href=\"https://app.test/verify/abc123\">here</a>.</p>",
"links": [
"https://app.test/verify/abc123"
],
"headers": {},
"attachments": [
{
"index": 0,
"filename": "invoice.pdf",
"content_type": "application/pdf",
"size": 48211,
"url": "string",
"thumb_url": "string"
}
],
"raw_url": "/v1/messages/msg_htumcicppd26jek6/raw",
"html_url": "/v1/messages/msg_htumcicppd26jek6/html",
"files": {
"raw": "https://example.com/hook",
"html": "<p>Click <a href=\"https://app.test/verify/abc123\">here</a>.</p>",
"attachments": [
"https://example.com/hook"
],
"thumbnails": [
"https://example.com/hook"
],
"expires_at": "2026-10-12T10:00:00Z"
},
"list_unsubscribe": {
"header": "string",
"header_post": "string",
"links": [
"https://app.test/verify/abc123"
],
"errors": "string"
}
}
}Delete a message
DELETE/v1/messages/{id}
Path parameters
- idstringrequiredMessage ID.
Returns
- deleted_messagesintegerrequired
Errors
curl -X DELETE "https://app.mailbench.dev/v1/messages/msg_htumcicppd26jek6" \
-H "Authorization: Bearer $API_KEY"const res = await fetch("https://app.mailbench.dev/v1/messages/msg_htumcicppd26jek6", {
method: "DELETE",
headers: {
Authorization: `Bearer ${process.env.API_KEY}`,
},
});
const { data } = await res.json();import os, requests
res = requests.delete(
"https://app.mailbench.dev/v1/messages/msg_htumcicppd26jek6",
headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
)
data = res.json()["data"]{
"success": true,
"data": {
"deleted_messages": 1
}
}Download the raw message (.eml)
GET/v1/messages/{id}/raw
Path parameters
- idstringrequiredMessage ID.
Returns
The original RFC 822 source.
Errors
curl "https://app.mailbench.dev/v1/messages/msg_htumcicppd26jek6/raw" \
-H "Authorization: Bearer $API_KEY"const res = await fetch("https://app.mailbench.dev/v1/messages/msg_htumcicppd26jek6/raw", {
headers: {
Authorization: `Bearer ${process.env.API_KEY}`,
},
});
const body = await res.text();import os, requests
res = requests.get(
"https://app.mailbench.dev/v1/messages/msg_htumcicppd26jek6/raw",
headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
)
body = res.textThe HTML body
GET/v1/messages/{id}/html
Served under a restrictive Content-Security-Policy (no scripts, opaque origin). 404 if the message has no HTML part.
Path parameters
- idstringrequiredMessage ID.
Returns
The HTML part.
Errors
curl "https://app.mailbench.dev/v1/messages/msg_htumcicppd26jek6/html" \
-H "Authorization: Bearer $API_KEY"const res = await fetch("https://app.mailbench.dev/v1/messages/msg_htumcicppd26jek6/html", {
headers: {
Authorization: `Bearer ${process.env.API_KEY}`,
},
});
const body = await res.text();import os, requests
res = requests.get(
"https://app.mailbench.dev/v1/messages/msg_htumcicppd26jek6/html",
headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
)
body = res.textLinks found in the message
GET/v1/messages/{id}/links
The http(s) links, extracted from the HTML and text parts.
Path parameters
- idstringrequiredMessage ID.
Returns
The links.
Errors
curl "https://app.mailbench.dev/v1/messages/msg_htumcicppd26jek6/links" \
-H "Authorization: Bearer $API_KEY"const res = await fetch("https://app.mailbench.dev/v1/messages/msg_htumcicppd26jek6/links", {
headers: {
Authorization: `Bearer ${process.env.API_KEY}`,
},
});
const { data } = await res.json();import os, requests
res = requests.get(
"https://app.mailbench.dev/v1/messages/msg_htumcicppd26jek6/links",
headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
)
data = res.json()["data"]{
"success": true,
"data": [
"https://example.com/hook"
]
}Download an attachment
GET/v1/messages/{id}/attachments/{index}
Path parameters
- idstringrequiredMessage ID.
- indexintegerrequiredPosition in the message's
attachmentsarray, starting at 0.
Returns
The file, with its original content type.
Errors
curl "https://app.mailbench.dev/v1/messages/msg_htumcicppd26jek6/attachments/<index>" \
-H "Authorization: Bearer $API_KEY"const res = await fetch("https://app.mailbench.dev/v1/messages/msg_htumcicppd26jek6/attachments/<index>", {
headers: {
Authorization: `Bearer ${process.env.API_KEY}`,
},
});
const body = await res.text();import os, requests
res = requests.get(
"https://app.mailbench.dev/v1/messages/msg_htumcicppd26jek6/attachments/<index>",
headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
)
body = res.textMark a message as read
PUT/v1/messages/{id}/read
Path parameters
- idstringrequiredMessage ID.
Returns
- idstringrequired
- readbooleanrequired
Errors
curl -X PUT "https://app.mailbench.dev/v1/messages/msg_htumcicppd26jek6/read" \
-H "Authorization: Bearer $API_KEY"const res = await fetch("https://app.mailbench.dev/v1/messages/msg_htumcicppd26jek6/read", {
method: "PUT",
headers: {
Authorization: `Bearer ${process.env.API_KEY}`,
},
});
const { data } = await res.json();import os, requests
res = requests.put(
"https://app.mailbench.dev/v1/messages/msg_htumcicppd26jek6/read",
headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
)
data = res.json()["data"]{
"success": true,
"data": {
"id": "string",
"read": true
}
}Mark a message as unread
DELETE/v1/messages/{id}/read
Path parameters
- idstringrequiredMessage ID.
Returns
- idstringrequired
- readbooleanrequired
Errors
curl -X DELETE "https://app.mailbench.dev/v1/messages/msg_htumcicppd26jek6/read" \
-H "Authorization: Bearer $API_KEY"const res = await fetch("https://app.mailbench.dev/v1/messages/msg_htumcicppd26jek6/read", {
method: "DELETE",
headers: {
Authorization: `Bearer ${process.env.API_KEY}`,
},
});
const { data } = await res.json();import os, requests
res = requests.delete(
"https://app.mailbench.dev/v1/messages/msg_htumcicppd26jek6/read",
headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
)
data = res.json()["data"]{
"success": true,
"data": {
"id": "string",
"read": true
}
}Act on many messages at once
POST/v1/messages/batch
Select messages either by ids or by a search query (optionally limited to
one inbox_id), then apply an action. tag and untag need tags.
Request body
- actionstringrequired
- idsarray of stringsMessages to act on. Alternative to
query. - querystringA search expression (see
q). Alternative toids. - inbox_idstringLimit a
queryto one inbox. - tagsarray of stringsRequired for
taganduntag.
Returns
- actionstringrequired
- affectedinteger (int64)required
Errors
curl -X POST "https://app.mailbench.dev/v1/messages/batch" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"action": "read", "ids": [ "string" ], "query": "string", "inbox_id": "string", "tags": [ "billing" ]}'const res = await fetch("https://app.mailbench.dev/v1/messages/batch", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"action": "read",
"ids": [
"string"
],
"query": "string",
"inbox_id": "string",
"tags": [
"billing"
]
}),
});
const { data } = await res.json();import os, requests
res = requests.post(
"https://app.mailbench.dev/v1/messages/batch",
headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
json={
"action": "read",
"ids": [
"string",
],
"query": "string",
"inbox_id": "string",
"tags": [
"billing",
],
},
)
data = res.json()["data"]{
"success": true,
"data": {
"action": "read",
"affected": 3
}
}Thumbnail of an image attachment
GET/v1/messages/{id}/attachments/{index}/thumb
Path parameters
- idstringrequiredMessage ID.
- indexintegerrequiredPosition in the message's
attachmentsarray, starting at 0.
Returns
A small PNG or JPEG.
Errors
curl "https://app.mailbench.dev/v1/messages/msg_htumcicppd26jek6/attachments/<index>/thumb" \
-H "Authorization: Bearer $API_KEY"const res = await fetch("https://app.mailbench.dev/v1/messages/msg_htumcicppd26jek6/attachments/<index>/thumb", {
headers: {
Authorization: `Bearer ${process.env.API_KEY}`,
},
});
const body = await res.text();import os, requests
res = requests.get(
"https://app.mailbench.dev/v1/messages/msg_htumcicppd26jek6/attachments/<index>/thumb",
headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
)
body = res.text