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/alternativefor 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.