Skip to main content
Many transactional emails need to include files — invoices after a purchase, receipts for payments, reports generated on demand, or contracts that need a signature. Lettr supports base64-encoded file attachments, so you can attach files directly in your API request.

Basic Attachment

Attach files using base64-encoded content:

Multiple Attachments

Inline Images

To show an attachment inside the body of the email instead of as a separate file, give the image attachment a content_id and reference it from your HTML with a cid: URL:
  • content_id only works on image attachments (a type starting with image/).
  • It can be up to 255 printable ASCII characters, without spaces or angle brackets. Don’t include the < > brackets you may see in raw MIME headers.
  • Each inline image in a request needs its own unique content_id.
  • Attachments without a content_id are delivered as regular attachments, as before.
A content_id that breaks these rules fails with a 422 validation error on attachments.N.content_id, and the email is not sent.

Over SMTP

When you send over SMTP, embedded images created by your mail library (for example, PHPMailer’s addEmbeddedImage() or Laravel’s $message->embed()) keep their Content-ID, so cid: references in your HTML display inline. You don’t need to change anything.

Hosted Images

You can also host the image at a public URL and reference that URL directly, which keeps the message smaller:
Many email clients block remote images by default and ask the recipient to “display images.” An alt attribute keeps the message readable when the image is blocked.

Attachment Limits

Large attachments can affect deliverability and may be blocked by recipient email servers. Consider using download links for large files.
Not every file belongs as an attachment. Consider which approach fits your use case: Use attachments for: invoices, receipts, tickets, and small documents the recipient needs to keep. Use download links for: large reports, media files, archives, and files that should expire after a set period.

Attachment Format

Attachments are included as base64-encoded content in the API request. Each attachment requires three fields:
  • name — The filename the recipient will see (max 255 characters)
  • data — The file content encoded as base64 (must not contain \r\n characters)
  • type — The MIME type of the file
An image attachment can also have an optional content_id to display it inline — see Inline Images.

Error Handling

When an attachment fails validation, the API returns an error and the email is not sent:
Validate file sizes and ensure base64 encoding does not contain \r\n characters before calling the API to avoid failed sends.

Common MIME Types