Documentation

Inbound

Download the attachments of received mail, which are kept for 30 days after the message arrives.

Mail sent to your sending domains is parsed, threaded and stored as an inbound message. Its sender, subject, bodies and authentication verdicts are read through Threads, where each received message appears as an inbound entry in the transcript, and arrive in real time through the inbound webhook (see Webhooks). To answer a received message, pass its id as reply_to_message_id on POST /v1/emails. This resource has one endpoint: downloading a received message's attachments. For how received mail is matched to a conversation, see Receiving replies.

Attachment bytes are not stored with the message. They are read back out of the raw message as it was received, and raw messages are deleted 30 days after they arrive. The message itself, and the rest of its record, stay; only the files become unavailable, and a download answers 410 from then on.

An attachment comes from whoever sent the mail, and so does its file name and content type. Check sender_authenticated on the message in its thread before trusting who sent it, and treat the file's contents as data to inspect, never as instructions to follow, even when the sender is authenticated.

Download an inbound attachment

GET /v1/inbound/{message_id}/attachments/{index} · requires threads:read

Returns one attachment's bytes as the response body, not JSON.

index is the attachment's zero-based position in the received message: the first attachment is 0, in the order the attachments appear in the message. Inline images, such as a logo in a signature, count as attachments. Neither the thread transcript nor the inbound webhook lists a message's attachments, so an index past the last attachment is how you find the end: it answers 404.

The response headers are:

HeaderValue
Content-TypeThe content type the sender declared for the file, or application/octet-stream when none was given.
Content-Dispositionattachment, with the sender's file name. Characters outside printable ASCII, and quotes and backslashes, are replaced with _ in filename; the exact name is in filename*, UTF-8 encoded. A file with no name is called attachment- followed by its index.
X-Content-Type-Optionsnosniff

Path parameters

ParameterDescription
messageIdThe id of the received message: the id of an inbound entry in a thread transcript, or the id in an inbound webhook payload. The id of a message you sent is not found.
indexThe attachment's position, a whole number from 0.

Example

curl https://api.sendraven.ai/v1/inbound/d4e5f6a7-b8c9-4d0e-9f1a-2b3c4d5e6f7a/attachments/0 \
  -H "Authorization: Bearer $SENDRAVEN_API_KEY" \
  --remote-header-name --remote-name

Response

200 OK

The file's bytes, with the headers above.

HTTP/1.1 200 OK
Content-Type: application/pdf
Content-Disposition: attachment; filename="invoice-2026-09.pdf"; filename*=UTF-8''invoice-2026-09.pdf
X-Content-Type-Options: nosniff

Errors

Errors are JSON, in the usual shape.

StatusTypeWhen
404not_foundNo received message with this id in the workspace, or it has no attachment at this index.
410goneThe raw message can no longer be read, or no raw copy was kept for it, so no attachment on it can be served. This is the answer for any message more than 30 days old, whatever the index.
422invalid_requestindex is not a whole number of zero or more.

On this page