Skip to main content
Attachments on inbound emails are not delivered as separate files or download links. Every inbound email reaches your forwarding URL as one JSON payload, and the files are inside the complete raw message in content.email_rfc822. To get them, decode that field if needed and parse it with a MIME library in your handler. Lettr does not store attachments, so there is nothing to download later. Whatever your code does not keep when it handles the delivery is gone.

Where Attachments Live

Your forwarding URL receives a JSON array of events, each with a msys.relay_message object (see Email Parsing for every field). The fields that matter for attachments are:
The text and html fields only carry the message body. There is no attachments field in the payload.
The whole message, attachments included, arrives in a single request body. Make sure your web server and framework accept request bodies as large as the biggest email you want to receive. Express’s express.json(), for example, rejects bodies over 100 KB unless you raise its limit.

Extracting Attachments

The steps are the same in every language:
  1. Loop over the events in the JSON array.
  2. Read content.email_rfc822 and base64-decode it if content.email_rfc822_is_base64 is true.
  3. Parse the raw message with a MIME library and read its attachment parts.
Python’s iter_attachments() only looks at the top level of the message. Inline images usually sit deeper, inside a multipart/related part, so use message.walk() to find them (see Inline Images). mailparser and mail-mime-parser return both regular attachments and inline images.

Respond First, Process Later

Answer the delivery with a 2xx as soon as you have the payload, and do slow work such as uploads, virus scans and file conversion in a background job. The same email can be delivered more than once, so key whatever you store on the email’s Message-ID header to avoid saving the same files twice.

Storing Attachments

Store every file you want to keep in your own storage while you handle the delivery. Use a key you generate yourself rather than the sender’s filename, and keep the original filename as metadata.

Save to Local Filesystem

Save to Cloud Storage (AWS S3)

Save to Cloud Storage (Google Cloud)

Validating Attachments

Lettr passes on whatever the sender attached, so deciding which files you accept is up to your code. Check the type and size of each file before you process it, using limits that suit your application.

Security Considerations

Filenames, content types and file contents all come from the sender. Never trust them. Validate and sanitize before you store, open or serve a file.

Virus Scanning

Scan files for malware in your handler before storing them, for example with ClamAV:

File Type Verification

The Content-Type of an attachment is whatever the sender’s mail client wrote. Check the actual bytes against it:

Inline Images

Images embedded in an HTML email (logos, signatures, pasted screenshots) are MIME parts with a Content-ID header. The HTML body refers to them as cid: URLs, for example <img src="cid:logo@example.com">, so content.html in the payload contains those references but not the images. You find the images in email_rfc822. With mailparser, inline images are part of parsed.attachments. Each has cid set and related: true. By default simpleParser also rewrites the cid: links in parsed.html into data: URLs, so the HTML displays on its own. To store the images and point the HTML at your own copies, keep the links and replace them yourself:
In Python, walk the whole message to find parts with a Content-ID:

Processing Specific File Types

Once you have an attachment’s bytes, process them with whatever library fits. The examples below use mailparser attachments, where attachment.content is a Buffer.

PDF Documents

Images

CSV Files

Complete Example

An Express endpoint that acknowledges the delivery right away and a worker that extracts PDF and image attachments, deduplicates on Message-ID, and uploads the files to S3:

Email Parsing

Every field in the inbound payload

Security

Security best practices

Best Practices

Inbound best practices

Sending Attachments

Attach files to outgoing emails