Skip to main content
Two endpoints: what is attached, and the file itself. Both take the same mailbox (required) and folder parameters as the message endpoints. Required permission for both: Attachments → Read (attachments:read)
Inline parts are not attachments. A signature logo, a tracking pixel, anything the HTML references with cid: — those are part of the rendered body and are left out of these endpoints.Listing them would turn every marketing email into a pile of phantom downloads, and an integration saving “all attachments” would fill a disk with spacer GIFs.

List attachments

Metadata only — deciding whether to fetch a 12 MB PDF should not require fetching it. The same array appears on GET /v1/messages/{uid}, so if you are already reading the message you do not need this call. index is this list’s own ordering, stable for as long as the message is: MIME parts do not reorder themselves. It is what the download endpoint takes.

Download an attachment

Returns the raw bytes, not JSON.

The content type is ours, not the sender’s

Every byte here describes something a stranger emailed you. A part declaring itself text/html or image/svg+xml and served back verbatim is a script that runs wherever it is opened. So the declared type is only honoured when it is plainly inert — images, audio, video, text/plain, application/pdf. Everything else is served as application/octet-stream, with nosniff so a browser cannot guess its way around the decision. The file itself is unchanged; only the label is. If you need the sender’s declared type, read content_type from the listing above — that one is reported as-is.

X-Ruber-File-Risk

Present when the filename’s extension is one that executes: .exe, .js, .lnk, .iso and similar get executable; macro-bearing Office formats get macro. It is a header rather than a refusal. Ruber’s mail plane already scans inbound mail with ClamAV and rejects what it recognises, so this is a second layer for what a scanner cannot catch. The web app uses the same judgement to warn a person before they download; warning a program in prose achieves nothing, and refusing the download would break the legitimate case of an integration archiving everything that arrives. So the judgement travels as a header your code can act on, and the file still comes. Do not execute what arrives here, and be careful about writing it to a path derived from filename — the name comes from the sender and may contain separators or traversal sequences.

Errors

Errors are JSON even though a successful response is not. See Errors for the full response shape.