Attachments
Upload, attach, and download files on email messages.
Upload flow
Outbound attachments use a two-step process:
- Upload — POST a file to
/v1/attachmentsas multipart form data. You get back an attachment ID. - Attach — Include the attachment ID(s) in the
attachmentsarray when sending a message viaPOST /v1/mailboxes/:id/messages.
Inbound attachments are extracted automatically by the JMAP poller: bytes are uploaded to R2, an Attachment row is linked to the inbound Message, and a fresh presigned download_url is included in every message.received webhook/SSE event. See Inbound attachments for the schema, the size/count caps, and the inline image rewrite example.
Downloading attachments
Fetch attachment metadata and a presigned download URL via GET /v1/attachments/:id. The presigned URL is valid for 24 hours and points directly to Cloudflare R2 storage. See the Attachments API reference.
Size limits
- Outbound: max file size per attachment 25 MB; max total attachment size 25 MB per message; max 10 attachments per outbound message.
- Inbound: max file size per attachment 25 MB; max 20 attachments per inbound message. Over-cap parts are dropped and the message row is flagged with
attachmentsDropped: true. - Storage counts toward your account's storage quota
Images in email
For outgoing messages, use the documented attachment upload flow when including an image as a file. A hosted image referenced in bodyHtml depends on the recipient client loading remote content. Provide meaningful alternative text and keep essential information in bodyText as well.
Incoming messages may contain Content-ID images or other MIME structure. Support for retrieving an incoming inline image does not establish that the outbound send API accepts arbitrary CID embedding fields. Check the current messages API before adding parameters.
Treat filenames and MIME declarations as untrusted. Retrieve fresh attachment download URLs and process files within your application's size and safety controls.