Attachments API
Upload files and download attachments from messages.
POST /v1/attachments
Upload a file as multipart form data. Max file size: 25 MB. Requires full-access API key. Scoped (mailbox-restricted) keys cannot upload attachments.
curl -X POST https://api.robotomail.com/v1/attachments \
-H "Authorization: Bearer $ROBOTOMAIL_API_KEY" \
-F "file=@report.pdf"{
"id": "a7b8c9d0-bcde-4f01-2345-777777777777",
"filename": "report.pdf",
"sizeBytes": 204800
}Include the returned id in the attachments array when sending a message.
Errors
400— No file provided403— Scoped API key (full access required)413— File exceeds 25 MB or storage limit exceeded
GET /v1/attachments/:id
Get attachment metadata and a presigned download URL (valid for 24 hours). Works for both outbound uploads and inbound message attachments — inbound attachments are owned by the recipient (the user who owns the receiving mailbox), so the same access check applies. Mailbox-scoped API keys can only access attachments linked to a message in an in-scope mailbox. Unattached uploads return 404 for scoped keys.
For inbound messages with inline images, this endpoint is the REST way to fetch a fresh presigned URL per attachment when rewriting cid: URLs in the HTML body. See Inbound attachments for the full inline image rewrite example.
{
"id": "a7b8c9d0-bcde-4f01-2345-777777777777",
"messageId": "b2c3d4e5-6789-4abc-def0-222222222222",
"userId": "u1234",
"filename": "report.pdf",
"contentType": "application/pdf",
"sizeBytes": 204800,
"r2Key": "u1234/inbound/a7b8c9d0.../report.pdf",
"contentId": null,
"createdAt": "2026-04-09T12:00:00.000Z",
"url": "https://r2.cloudflarestorage.com/...?signed-24h"
}contentId— for inline images, theContent-IDheader value (without angle brackets). Match this againstcid:fooreferences in the HTML body.nullfor normal attachments and outbound uploads.messageId— the parentMessagerow this attachment is linked to.nullfor orphaned uploads not yet attached to a sent message.r2Key— internal storage key (returned for backwards compat — do not depend on its shape).url— presigned R2 URL, valid for 24 hours from the moment of this request. To get a fresh URL after expiry, call this endpoint again.
Errors
402—INBOUND_LIMIT_EXCEEDED: the attachment is linked to an inbound message that was received while the account was over its monthly inbound cap. Outbound uploads and attachments on under-limit inbound messages are unaffected. See 402INBOUND_LIMIT_EXCEEDED404— Attachment not found, or (for scoped keys) not linked to an in-scope mailbox
DELETE /v1/attachments/:id
Delete an attachment. Frees the storage from your account quota. Mailbox-scoped API keys can only delete attachments linked to a message in an in-scope mailbox.
{ "deleted": true }