Attachments
Attach files to a send, reply, or forward, then list or download attachment parts from a
received message. The key needs the mailbox:send permission string to send attachments and
mailbox:read to list or download them. These names are stable wire values.
Sending attachments
Section titled “Sending attachments”Add an attachments array to a send, reply, or forward body. Each entry contains standard
base64 file bytes and optional filename and content_type. Extrovert builds the multipart MIME
message.
Attachments survive the Review Loop: a queued message keeps its files
(and its reply_to and custom headers) on the review row, and the approved send delivers them. A
redraft via submit_revision may replace them: supply attachments to swap the set, omit the field
to leave it untouched, or pass [] to clear it. The human reviews the message the recipient gets.
curl -sS -X POST "$EXTROVERT_API_BASE_URL/v1/inboxes/agent7%40extrovertmail.com/send" \ -H "Authorization: Bearer $EXTROVERT_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "to": ["ops@acme.test"], "subject": "report", "text": "Attached.", "intent": { "summary": "Send ops the weekly deploy report they asked for" }, "attachments": [ { "filename": "report.pdf", "content_type": "application/pdf", "content_base64": "JVBERi0…" } ] }'import { readFileSync } from "node:fs";
await inbox.send({ to: "ops@acme.test", subject: "report", text: "Attached.", intent: { summary: "Send ops the weekly deploy report they asked for" }, attachments: [ { filename: "report.pdf", content_type: "application/pdf", content_base64: readFileSync("report.pdf").toString("base64"), }, ],});{ "name": "send_email", "arguments": { "inbox": "agent7@extrovertmail.com", "to": ["ops@acme.test"], "subject": "report", "text": "Attached.", "intent": { "summary": "Send ops the weekly deploy report they asked for" }, "attachments": [ { "filename": "report.pdf", "content_type": "application/pdf", "content_base64": "JVBERi0…" } ] }}Listing and downloading
Section titled “Listing and downloading”A received message exposes attachment metadata first. Download the bytes using the part’s opaque
id.
| You want | Endpoint | SDK | MCP |
|---|---|---|---|
| List attachment metadata | GET …/messages/{id}/attachments | inbox.attachments(msgId) | list_attachments |
| Download one part’s bytes | GET …/messages/{id}/attachments/{attId} | inbox.attachment(msgId, attId) | get_attachment |
# 1. list: { items: [{ id, filename, content_type, size }], total }curl -sS "$EXTROVERT_API_BASE_URL/v1/inboxes/agent7%40extrovertmail.com/messages/msg_8Tz/attachments" \ -H "Authorization: Bearer $EXTROVERT_API_KEY"
# 2. download: raw bytes with Content-Type + Content-Disposition setcurl -sS "$EXTROVERT_API_BASE_URL/v1/inboxes/agent7%40extrovertmail.com/messages/msg_8Tz/attachments/att_1" \ -H "Authorization: Bearer $EXTROVERT_API_KEY" -o invoice.pdfThe REST download response returns raw bytes and sets Content-Type and Content-Disposition from
the part. The MCP get_attachment tool returns base64 content in its structured result. Neither path
requires parsing the raw MIME message.