MailFlatDocs
Documentation/Common test cases/Attachments

Testing email attachments

Every file on a message comes back as metadata you can assert on, and the bytes download from one endpoint — so a PDF invoice test is two calls, not a MIME parser.

How it works

Incoming mail is unpacked for you: each attached file lands in the attachments array with its filename, MIME type and size. The list carries metadata only, because a message with one 5 MB file would otherwise make every inbox listing 5 MB heavier. The bytes live behind their own endpoint and come back exactly as the sender encoded them.

See what arrived

The SDKs do not type this field yet, so read it off raw — the untouched API payload every message carries.
msg = inbox.wait_for_message(timeout=30)
att = msg.raw["attachments"][0]
assert att["filename"] == "invoice.pdf"
assert att["content_type"] == "application/pdf"

Download the file

One GET, and the response body is the file itself — same bytes the sender attached, with the original Content-Type.
import os, requests
 
url = (f"https://mailflat.net/api/v1/inboxes/{inbox.address}"
f"/messages/{msg.raw['id']}/attachments/{att['id']}")
pdf = requests.get(url, headers={"X-API-Key": os.environ["MAILFLAT_API_KEY"]}).content
assert pdf.startswith(b"%PDF")

Files we did not keep

A single file over 5 MB, or more than 10 MB across one message, is recorded but not stored. The entry stays so you can tell an oversized file apart from one that never arrived.
curl
curl -s "$MAILFLAT_API/inboxes/$ADDRESS/latest" \
-H "X-API-Key: $MAILFLAT_API_KEY" | jq '.email.attachments[] | {filename, truncated}'
# { "filename": "backup.zip", "truncated": true }
 
# Downloading a truncated attachment answers plainly rather than sending 0 bytes:
# { "detail": "Attachment was too large to store" }

Worth knowing

Encrypted inboxes hand back an envelope, not a file
On an end-to-end encrypted inbox the server cannot read the file, so the download endpoint returns the encrypted envelope and your own key has to open it. Filename, type and size stay readable — they sit at the same level as the sender address, which is worth knowing before you attach something whose name gives it away.