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:
import fs from 'fs';

const fileContent = fs.readFileSync('invoice.pdf');
const base64Content = fileContent.toString('base64');

await lettr.emails.send({
  from: 'you@example.com',
  to: ['recipient@example.com'],
  subject: 'Your Invoice',
  html: '<p>Please find your invoice attached.</p>',
  attachments: [
    {
      name: 'invoice.pdf',
      data: base64Content,
      type: 'application/pdf'
    }
  ]
});

Multiple Attachments

await lettr.emails.send({
  from: 'you@example.com',
  to: ['recipient@example.com'],
  subject: 'Project Files',
  html: '<p>Here are the requested files.</p>',
  attachments: [
    {
      name: 'report.pdf',
      data: reportBase64,
      type: 'application/pdf'
    },
    {
      name: 'data.xlsx',
      data: excelBase64,
      type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
    },
    {
      name: 'image.png',
      data: imageBase64,
      type: 'image/png'
    }
  ]
});

Inline Images

Embed images directly in your email HTML:
await lettr.emails.send({
  from: 'you@example.com',
  to: ['recipient@example.com'],
  subject: 'Email with Image',
  html: '<p>Check out this image:</p><img src="cid:logo" />',
  attachments: [
    {
      name: 'logo.png',
      data: logoBase64,
      type: 'image/png'
    }
  ]
});

Attachment Limits

LimitValue
Max total size (after Base64 encoding)5 MB
Max attachment name length255 characters
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:
FactorAttachmentDownload Link
File sizeBest for files under 10 MBBetter for large files
Offline accessRecipient has the file immediatelyRequires internet to download
DeliverabilityLarge attachments may be blockedNo impact on email delivery
TrackingNo download trackingCan track link clicks
ExpirationFile persists in recipient’s inboxLink can expire for security
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
attachments: [{ name: 'invoice.pdf', data: base64String, type: 'application/pdf' }]

Error Handling

When an attachment fails validation, the API returns an error and the email is not sent:
{
  "error_code": "validation_error",
  "message": "The given data was invalid.",
  "errors": {
    "attachments.0.data": ["The attachments.0.data field must be a valid base64 string."],
    "attachments.0.name": ["The attachments.0.name field is required."]
  }
}
Validate file sizes and ensure base64 encoding does not contain \r\n characters before calling the API to avoid failed sends.

Common MIME Types

ExtensionMIME Type
.pdfapplication/pdf
.docapplication/msword
.docxapplication/vnd.openxmlformats-officedocument.wordprocessingml.document
.xlsapplication/vnd.ms-excel
.xlsxapplication/vnd.openxmlformats-officedocument.spreadsheetml.sheet
.pngimage/png
.jpgimage/jpeg
.gifimage/gif
.zipapplication/zip
.csvtext/csv