Email Attachments

Attach files to outbound emails. SES v2 handles delivery via raw MIME.

Request

POST /api/v1/emails
{
  "from": "hi@yourdomain.com",
  "to": ["user@example.com"],
  "subject": "Invoice",
  "html": "<p>See attached.</p>",
  "attachments": [
    {
      "filename": "invoice.pdf",
      "content": "<base64-encoded-bytes>",
      "content_type": "application/pdf"
    }
  ]
}

Rules

Field Rules
filename 1–255 chars
content base64. Raw bytes decoded server-side, then re-encoded into MIME.
content_type Defaults to application/octet-stream.
Max count 10 per email

Implementation

Source: src/lib/providers/email.ts. When attachments.length > 0, the send path switches from SendEmailCommand(Simple) to SendEmailCommand(Raw) and builds a multipart MIME body with buildRawMime():

  • Outer boundary: multipart/mixed.
  • Inner multipart/alternative for text + html.
  • Each attachment as a separate part with Content-Disposition: attachment.

Size

SES has a 10 MB raw message cap — base64 encoding inflates ~33%, so attachments should be well under 7 MB total before encoding. No runtime cap is enforced in-app; requests over AWS limits will fail with a 500 INTERNAL_ERROR.

Test mode

Test keys skip the SES call entirely. Attachments are accepted by validation, stored on the messages row (currently only the first toEmail is stored), but no MIME is built.