Mailbase
FeaturesPricingDocsBlogComparisonsChangelog
Sign inStart free
Home/Blog/Multipart Email: A Practical MIME Implementation Guide
Email infrastructureUpdated August 1, 20269 min read

Multipart Email: A Practical MIME Implementation Guide

A developer-focused guide to structuring multipart email so plain text, HTML, attachments, and inline resources survive real sending and receiving systems.

By Mailbase Team · Target keyword: multipart email
Designer working on layouts on a laptop — Multipart Email: A Practical MIME Implementation Guide
Photo from Unsplash
On this page
OverviewChoose a MIME container by the relationship between partsNest the MIME tree instead of flattening every partKeep the plain-text and HTML versions equivalentLet a library own boundaries, encoding, and part headersTest the message after transport, not only before itMake multipart structure part of the sending contractCommon MistakesSources & Further ReadingRelated guidesFAQRelated reading

Overview

Multipart email uses MIME containers to carry more than one representation or resource in a single message. The common case is multipart/alternative with a text/plain version followed by a text/html version of the same content. Attachments usually require an outer multipart/mixed container, while HTML that depends on inline resources can use multipart/related. The reliable implementation is a MIME tree with explicit relationships—not a flat list of text, HTML, images, and files.

Most applications should provide semantic inputs to a maintained email library or provider SDK and let it create boundaries, fold headers, and encode body parts. You still need to understand the resulting tree: provider abstractions can be misused, and the raw received message is the evidence when a client shows the wrong body, exposes an attachment unexpectedly, or drops an inline image.

Choose a MIME container by the relationship between parts

Glowing network cables converging into a switch — Choose a MIME container by the relationship between parts
Photo from Unsplash

The multipart subtype tells a recipient how sibling parts relate. In multipart/alternative, each child communicates the same information in a different representation. RFC 2046 orders those representations by increasing preference, with the richest preferred representation normally placed last; for typical email that means text/plain first and text/html second. A client can then choose the last format it supports rather than rendering both.

Multipart/mixed has different semantics: its children are independent items intended to be presented in order, which makes it the usual outer container for a body plus attachments. Multipart/related groups a root document with resources needed to display it, such as HTML and a content-ID image. Picking the wrong subtype can make a client show both alternatives, treat an inline asset as a downloadable file, or hide the intended body.

  • Use alternative only when the children convey the same message
  • Place text/plain before text/html inside multipart/alternative
  • Use mixed for files the recipient should receive independently
  • Use related only when a body part depends on the grouped resources
ContainerRelationshipTypical email use
multipart/alternativeEquivalent representationsPlain-text and HTML versions of one message
multipart/mixedIndependent ordered partsMessage body followed by one or more attachments
multipart/relatedRoot content plus dependent resourcesHTML that references inline images by Content-ID

Nest the MIME tree instead of flattening every part

Writing on a laptop at a quiet desk — Nest the MIME tree instead of flattening every part
Photo from Unsplash

A message with plain text, HTML, and a PDF is normally an outer multipart/mixed message. Its first child is a multipart/alternative container holding text/plain and text/html; its second child is the PDF attachment. The attachment is not another alternative because it does not communicate the same complete content as the message body.

If the HTML references an inline logo, the tree needs another relationship. One practical shape is outer multipart/mixed, then multipart/alternative for the body choices, with the HTML choice represented by a multipart/related container that includes the HTML root and its inline asset. MIME consumers differ at the edges, so use the shape generated by a proven library and confirm it in your target clients rather than hand-assembling a novel nesting order.

  1. Write down which parts are equivalent bodies, dependent resources, and independent attachments.
  2. Create the innermost body relationship first: usually text/plain and text/html alternatives.
  3. Group HTML-dependent resources with the HTML root when inline content is necessary.
  4. Wrap the completed body and independent files in multipart/mixed.
  5. Serialize with an email library, then inspect the received raw source.
RequirementRecommended shapeCommon mistake
Plain text plus HTMLalternative(text, html)Two unrelated top-level body parts
Plain text, HTML, and PDFmixed(alternative(text, html), pdf)Putting the PDF inside alternative
HTML with inline imagerelated(html, image)Remote URL marked as a MIME attachment
Alternatives, inline image, and PDFNested mixed, alternative, and related containersOne flat mixed list with ambiguous roles

Keep the plain-text and HTML versions equivalent

The plain-text part is not a teaser that says 'view this email in HTML.' It should carry the same essential message, links, sender identity, and unsubscribe or preference controls as the HTML part. It may use simpler structure—headings as lines, readable full URLs, and compact spacing—but a recipient choosing text/plain should not lose the call to action or compliance path.

Generate both alternatives from one content model when possible. If the HTML template and text body are edited separately, they drift: prices differ, a link disappears, or one version retains obsolete legal copy. Store and version the source data, render both outputs in the same build step, and fail pre-send checks when required links or identifiers appear in only one representation.

  • Preserve the same promise and primary action in both versions
  • Include human-readable link context in plain text
  • Keep unsubscribe and sender information available without HTML
  • Do not mechanically strip tags and assume the result is readable
  • Version both rendered alternatives with the campaign or template

Let a library own boundaries, encoding, and part headers

Every multipart container needs a boundary parameter whose delimiter does not occur in its enclosed data. Each body part has its own Content-Type and may have a Content-Transfer-Encoding. RFC 2045 defines the MIME framing and transfer encodings used to move content safely through mail transport. These details are easy to get subtly wrong: line endings, boundary closure, header folding, non-ASCII text, and base64 wrapping can all produce a message that one parser accepts and another truncates.

Use a maintained MIME composer instead of string concatenation. Pass it Unicode text, HTML, filenames, media types, and disposition intent; do not pre-base64 content unless the library explicitly asks for it. For an attachment, provide a truthful media type and safe display filename. For an inline resource, assign a unique Content-ID and make the HTML cid: reference match it exactly. Never put user-supplied header text directly onto the wire without the library's validation because newline characters can turn data into injected headers.

  • Do not reuse a handwritten static boundary across messages
  • Do not encode content twice
  • Sanitize filenames and reject CR/LF in user-controlled header values
  • Keep attachment size policy outside the MIME serializer and enforce it before enqueueing
ConcernApplication suppliesMIME library should handle
Text and HTMLUnicode content and declared charset intentTransfer encoding and line formatting
Multipart boundaryContainer relationshipsUnique boundary generation and closing delimiters
AttachmentBytes, media type, safe filename, dispositionEncoding and header serialization
Inline resourceBytes, media type, unique Content-IDEncoding and MIME part construction

Test the message after transport, not only before it

A local snapshot proves what your application attempted to create. It does not prove what arrived. Providers may add tracking, rewrite links, insert headers, or transform content; gateways may scan attachments; clients choose different alternatives. Send fixtures through the production-like path to controlled mailboxes, download the raw received source, and compare its MIME tree with the intended structure.

Build a compact fixture matrix: text and HTML only; each representation independently readable; one PDF attachment; one inline image; Unicode subject, body, and filename; a long URL; an empty optional field; and a message near your own size limit. Verify visible rendering, attachment behavior, content IDs, links, reply behavior, authentication results, and that the plain-text version can be selected or extracted.

  • Reject malformed output before it enters a retry queue
  • Test with images disabled and with the HTML part unavailable
  • Open attachments in a safe test environment and verify their hashes before and after transport
  • Keep fixture messages free of customer data
  1. Parse the serialized message with a second MIME parser in automated tests.
  2. Assert container types, child order, charsets, dispositions, filenames, and Content-IDs.
  3. Round-trip representative fixtures through the real provider or SMTP path.
  4. Inspect raw source in multiple receiving systems and compare the visible result.
  5. Repeat tests when the template engine, MIME library, provider, or tracking layer changes.

Make multipart structure part of the sending contract

Document what your application promises the provider: whether the SDK accepts separate text and HTML fields, whether it composes raw MIME, how attachments are passed, what it does with inline images, and whether tracking modifies the HTML after composition. Store a template version and message identifier with each send so a malformed message can be traced to the renderer, library, and provider configuration that produced it.

Mailbase's relevant connection is at this workflow boundary. Teams can create MJML campaigns and templates, run pre-send checks, schedule durable sends, and inspect delivery or reply events. MIME serialization still belongs to the rendering and provider path. If you connect Mailbase to useSend or another sending system, verify the final received multipart message whenever that path, its SDK, or its tracking behavior changes.

  • Pin and review MIME-library changes like other infrastructure dependencies
  • Retest after enabling click tracking or changing providers
  • Log structure and identifiers, not sensitive body or attachment content
  • Keep rendering failures separate from provider delivery retries
OwnerResponsibilityEvidence
Content/templateEquivalent text and HTML, required linksVersioned render fixtures
ApplicationCorrect relationships and safe attachment inputsParsed MIME-tree tests
Library/providerStandards-based serialization and transportRaw sent and received samples
Email operationsClient QA and change monitoringSeed-test checklist and incident notes

Common Mistakes

  • Choosing a tool before deciding who owns deliverability.
  • Treating DNS authentication as a one-time checkbox instead of an operating baseline.
  • Mixing product-critical transactional email with experimental marketing sends, with no clear boundary.
  • Trusting headline metrics (like open rate) that privacy proxies now inflate.

Sources & Further Reading

Official docs for current setup details, pricing, and API behavior — verify specifics there, since they change.

RFC 2045: MIME message body format
RFC 2046: MIME media types
RFC 2387: multipart/related MIME type

Related guides

More on multipart email and the surrounding email infrastructure workflow:

Mailbase API docs
API token docs
transactional email for SaaS
email API vs SMTP
SMTP relay for SaaS
AWS SES email stack
how to start an email newsletter
Try Mailbase free
Send 200 emails a month on us. Paid plans start at €9 — or bring your own useSend for €5.
See plans

FAQ

What is a multipart email?

A multipart email is a MIME message whose body contains multiple parts. The parts may be equivalent representations such as plain text and HTML, independent items such as attachments, or a root document and dependent inline resources.

What is the correct order for plain text and HTML email parts?

Inside multipart/alternative, place text/plain first and text/html second. RFC 2046 defines the alternatives in increasing order of faithfulness so a recipient can choose the last representation it supports.

What is the difference between multipart/alternative and multipart/mixed?

Multipart/alternative contains different representations of the same information, while multipart/mixed contains independent ordered parts. A body with an attachment commonly uses mixed outside and an alternative text-and-HTML body inside.

Should developers build raw MIME strings by hand?

Usually no. Use a maintained MIME library or a provider SDK that accepts structured text, HTML, attachment, and inline-resource inputs. Then parse and inspect the serialized and received message so the abstraction remains testable.

Do multipart emails need a plain-text part?

For a message offering both HTML and text representations, a meaningful text/plain alternative improves compatibility, accessibility, debugging, and recipient choice. It should preserve the essential content, links, sender identity, and opt-out controls rather than merely pointing to the HTML version.

Related reading

Transactional email7 min read
Transactional Email for SaaS: The Practical Guide
A practical guide to transactional email for SaaS: what counts as transactional, choosing an API or SMTP provider, templates, deliverability, idempotency, and the operations that keep critical mail flowing.
Deliverability7 min read
Email API vs SMTP: Which Should You Use?
Email API vs SMTP compared for SaaS: how each works, reliability, speed, debugging, features, and portability — plus why many teams use both.
Transactional email7 min read
SMTP Relay for SaaS Apps: What to Use and Why
What an SMTP relay is, when a SaaS app should use one, how it differs from an email API, the providers to consider, and the DNS and production tradeoffs.
Transactional email7 min read
AWS SES Email Stack for SaaS Builders
How to think about Amazon SES as part of a SaaS email stack: what SES is and isn't, the layers you build on top of it, the sandbox/SNS setup, and where it fits versus a full API.
Newsletters8 min read
How to Start an Email Newsletter (Step by Step)
Everything you need to launch a newsletter that people actually read — niche, platform, domain setup, first subscribers, and a sustainable sending rhythm.
Email infrastructure9 min read
Email Webhook Events: A Practical Processing Guide
A practical email webhook events playbook for building idempotent ingestion, clean event models, suppression updates, and reliable analytics.
Mailbase
Product
FeaturesPricinguseSend integrationChangelog
Learn
BlogDocsAPI referenceResources
Compare
ComparisonsAlternatives
Guides
Transactional email servicesSelf-hosted useSend stackSelf-hosted email marketingSPF, DKIM & DMARCEmail deliverability
Legal
TermsPrivacy
© 2026 Mailbase · french-webEmail workflow for builders.