Skip to content
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

  • idstringrequired
    Inbox ID.

Query parameters

  • qstring
    Search. 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".
  • fromstring
    Sender contains this text.
  • tostring
    Any recipient contains this text.
  • subjectstring
    Subject contains this text.
  • sincestring (date-time)
    Only messages received at or after this time.
  • limitinteger
    Page size.
    Default 50.
  • cursorstring
    The next_cursor from the previous page.

Returns a list of

  • idstringrequired
  • inbox_idstringrequired
  • received_atstring (date-time)required
  • envelope_fromstringrequired
    The SMTP MAIL FROM.
  • recipientsarray of stringsrequired
    The SMTP RCPT TO addresses, including Bcc.
  • fromstringrequired
    The From header.
  • tostringrequired
    The To header.
  • subjectstringrequired
  • message_idstringrequired
    The Message-ID header.
  • sizeintegerrequired
    Size in bytes.
  • has_textbooleanrequired
  • has_htmlbooleanrequired
  • attachment_countintegerrequired
  • link_countintegerrequired
  • tlsbooleanrequired
    Whether the sender used TLS.
  • parse_errorstring
    Set when the message is not valid MIME. Parts may be missing.
  • readbooleanrequired
  • tagsarray of stringsrequired

Errors

400The request was malformed or a value was invalid.
401Missing or invalid API key.
404No such object in this workspace.
429Too many requests. Wait `Retry-After` seconds.
curl / JavaScript / Python
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"]
Response 200
{
  "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

  • idstringrequired
    Inbox ID.

Headers

  • Last-Event-IDstring

Returns

An `text/event-stream`.

Errors

400The request was malformed or a value was invalid.
401Missing or invalid API key.
404No such object in this workspace.
429Too many requests. Wait `Retry-After` seconds.
curl / JavaScript / Python
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.text

Get 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

  • idstringrequired
    Message ID.

Returns

  • idstringrequired
  • inbox_idstringrequired
  • received_atstring (date-time)required
  • envelope_fromstringrequired
    The SMTP MAIL FROM.
  • recipientsarray of stringsrequired
    The SMTP RCPT TO addresses, including Bcc.
  • fromstringrequired
    The From header.
  • tostringrequired
    The To header.
  • subjectstringrequired
  • message_idstringrequired
    The Message-ID header.
  • sizeintegerrequired
    Size in bytes.
  • has_textbooleanrequired
  • has_htmlbooleanrequired
  • attachment_countintegerrequired
  • link_countintegerrequired
  • tlsbooleanrequired
    Whether the sender used TLS.
  • parse_errorstring
    Set 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
    • urlstringrequired
      Path to download it (needs your API key).
    • thumb_urlstring
      Path to a thumbnail, for images.
  • raw_urlstringrequired
    Path to the raw .eml.
  • html_urlstring
    Path to the HTML body, when there is one.
  • filesobjectrequired
    Signed, expiring URLs a browser can open without an Authorization header.
    Child attributes
    • rawstring (uri)required
    • htmlstring (uri)
    • attachmentsarray of stringsrequired
    • thumbnailsarray of strings
    • expires_atstring (date-time)required
  • list_unsubscribeobject
    Parsed List-Unsubscribe headers, when present.
    Child attributes
    • headerstring
    • header_poststring
    • linksarray of strings
    • errorsstring

Errors

401Missing or invalid API key.
404No such object in this workspace.
429Too many requests. Wait `Retry-After` seconds.
curl / JavaScript / Python
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"]
Response 200
{
  "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

  • idstringrequired
    Message ID.

Returns

  • deleted_messagesintegerrequired

Errors

401Missing or invalid API key.
403The key is read-only, or the action needs a dashboard session.
404No such object in this workspace.
429Too many requests. Wait `Retry-After` seconds.
curl / JavaScript / Python
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"]
Response 200
{
  "success": true,
  "data": {
    "deleted_messages": 1
  }
}

Download the raw message (.eml)

GET/v1/messages/{id}/raw

Path parameters

  • idstringrequired
    Message ID.

Returns

The original RFC 822 source.

Errors

401Missing or invalid API key.
404No such object in this workspace.
429Too many requests. Wait `Retry-After` seconds.
curl / JavaScript / Python
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.text

The 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

  • idstringrequired
    Message ID.

Returns

The HTML part.

Errors

401Missing or invalid API key.
404No such object in this workspace.
429Too many requests. Wait `Retry-After` seconds.
curl / JavaScript / Python
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.text

Download an attachment

GET/v1/messages/{id}/attachments/{index}

Path parameters

  • idstringrequired
    Message ID.
  • indexintegerrequired
    Position in the message's attachments array, starting at 0.

Returns

The file, with its original content type.

Errors

400The request was malformed or a value was invalid.
401Missing or invalid API key.
404No such object in this workspace.
429Too many requests. Wait `Retry-After` seconds.
curl / JavaScript / Python
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.text

Mark a message as read

PUT/v1/messages/{id}/read

Path parameters

  • idstringrequired
    Message ID.

Returns

  • idstringrequired
  • readbooleanrequired

Errors

401Missing or invalid API key.
403The key is read-only, or the action needs a dashboard session.
404No such object in this workspace.
429Too many requests. Wait `Retry-After` seconds.
curl / JavaScript / Python
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"]
Response 200
{
  "success": true,
  "data": {
    "id": "string",
    "read": true
  }
}

Mark a message as unread

DELETE/v1/messages/{id}/read

Path parameters

  • idstringrequired
    Message ID.

Returns

  • idstringrequired
  • readbooleanrequired

Errors

401Missing or invalid API key.
403The key is read-only, or the action needs a dashboard session.
404No such object in this workspace.
429Too many requests. Wait `Retry-After` seconds.
curl / JavaScript / Python
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"]
Response 200
{
  "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
    One of read, unread, delete, tag, untag.
  • idsarray of strings
    Messages to act on. Alternative to query.
  • querystring
    A search expression (see q). Alternative to ids.
  • inbox_idstring
    Limit a query to one inbox.
  • tagsarray of strings
    Required for tag and untag.

Returns

  • actionstringrequired
  • affectedinteger (int64)required

Errors

400The request was malformed or a value was invalid.
401Missing or invalid API key.
403The key is read-only, or the action needs a dashboard session.
429Too many requests. Wait `Retry-After` seconds.
curl / JavaScript / Python
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"]
Response 200
{
  "success": true,
  "data": {
    "action": "read",
    "affected": 3
  }
}

Thumbnail of an image attachment

GET/v1/messages/{id}/attachments/{index}/thumb

Path parameters

  • idstringrequired
    Message ID.
  • indexintegerrequired
    Position in the message's attachments array, starting at 0.

Returns

A small PNG or JPEG.

Errors

400The request was malformed or a value was invalid.
401Missing or invalid API key.
404No such object in this workspace.
429Too many requests. Wait `Retry-After` seconds.
curl / JavaScript / Python
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