docs
v1 Pricing Dashboard
Concepts / attachments

Attachments

Invoices, tickets, calendar invites, generated PDFs — when your app emails files, your tests can assert on them. Metadata rides on every message; bytes are one request away.

Metadata on the message

Every message detail carries an attachments array — metadata only, so listing stays fast no matter what's attached:

message.attachments
[
  {
    "filename": "invoice-0042.pdf",
    "content_type": "application/pdf",
    "size": 48213,
    "inline": false
  },
  {
    "filename": "logo.png",
    "content_type": "image/png",
    "size": 8122,
    "inline": true
  }
]

inline: true marks parts embedded in the HTML by Content-ID — typically logos and images the email renders in place — so a test asserting "the receipt has exactly one PDF" can filter them out. Up to 50 attachments are listed per message; size is the decoded size in bytes, and content_type is what the sender declared, not what we verified.

Downloading bytes

GET /v1/messages/{id}/attachments/{index} returns the decoded bytes of one attachment, where index is the position in the metadata array (0-based). Both SDKs wrap this in a download helper, and the dashboard's extracted rail offers the same downloads per message.

Downloads are deliberately blunt: always application/octet-stream, always Content-Disposition: attachment with a sanitized filename, always nosniff. Email is hostile input — an HTML or SVG "attachment" must download as a file, never render on our origin, no matter what content type the sender claimed. Verify checksums and parse contents in your test code, where it's safe.

tip Asserting a generated PDF is correct? Compare a checksum or parse it in the test — don't assert on size alone. PDF generators pad nondeterministically, and size-only assertions rot.

Limits

The whole message — body plus all attachments, as transmitted — is capped at 10 MB at SMTP time, which bounds any single attachment below that. Attachment bytes live in the message's raw MIME and share its retention: when the message expires or is deleted, the attachments go with it.

Over MCP

For AI agents on the MCP server, attachments up to 1 MiB return inline as base64 in the tool result; larger ones return a pointer to the REST download URL instead — an agent context window is the wrong place for a 9 MB PDF.

Next

Messages
Where attachments live and expire.
Extraction
OTPs and links from the same message.
Quickstart: pytest
A suite to put downloads in.
Was this page useful? yes no Concepts: Webhooks →
ON THIS PAGE
edit this page ↗
report an issue ↗