Receiving email programmatically sounds like a one-afternoon task: open the message, read the subject, grab the body. Then the real messages arrive. A reply quotes the original in three encodings. An invoice attaches a PDF inside a multipart/mixed wrapper, nested inside a multipart/alternative for the HTML and plain-text versions. A sender in another region encodes the subject line in quoted-printable with a non-UTF-8 charset. Suddenly the afternoon is a sprint.
Why MIME is harder than it looks
MIME — Multipurpose Internet Mail Extensions — is a recursive structure. A single message can contain parts inside parts, each with its own content type, transfer encoding, and character set. The format has accumulated decades of real-world quirks that no specification fully captures.
- Nested multiparts. The body you want is rarely at the top level. You walk a tree and decide which leaf is the "real" content.
- Transfer encodings. Base64 and quoted-printable both have to be decoded correctly before the bytes mean anything.
- Character sets. UTF-8 is common but far from universal. Legacy clients still emit ISO-8859 variants and region-specific encodings.
- Inline vs. attached. An image referenced by a
cid:in the HTML is structurally an attachment, but you usually do not want it in your attachments list.
The parser is never done. Each new sender is a new edge case, and the edge cases never stop arriving.
What you actually want
Almost no product roadmap has "build a world-class MIME parser" on it. What teams want is the message, decoded and predictable, so they can route it, store it, or act on it. That is a transport problem, not a business problem — and it is a good candidate to push down into infrastructure.
With InletOps, every inbound message is parsed for you and delivered as a stable JSON object. Headers are normalized, the body is decoded, and attachments are extracted, scanned, and made available over signed URLs.
{ "event": "message.received", "to": "invoices@acme.com", "subject": "Invoice #1042 attached", "text": "Hi — please find…", "attachments": [{ "filename": "invoice-1042.pdf", "size": 184203 }] }
When you still need the raw bytes
Sometimes you do need the original. Forensics, signature verification, or archival all call for the untouched message. Good infrastructure keeps the parsed object convenient and exposes the raw MIME when you ask for it — so the common path is easy and the rare path is still possible.
The takeaway
Parsing email is undifferentiated heavy lifting. Receive a clean object by default, reach for raw MIME only when a specific job demands it, and spend your engineering time on the workflow that actually moves your business.