Questions · Updated 2026-09-28
How do I send an email with an attachment?
Send an email with an attachment by adding attachments[] to POST /emails, each with filename, content (base64) or path (a URL fetched at send time), and content_type. GET /emails/{id}/attachments lists what was sent.
Send an email with an attachment by adding an attachments array to the body of POST /emails. Each entry has a filename, either content (the bytes as base64) or path (a URL that is fetched when the message is sent), and a content_type such as application/pdf. The same array goes on each item of POST /emails/batch, and POST /emails/preflight accepts it and checks it without sending anything.
The fields
filenameis the name the recipient downloads. Only the last path segment is kept. Without it, the name is taken from the end ofpath, and failing that the file is calledattachment.contentis base64. Content that does not decode is refused withinvalid_attachmentand the sentence "Attachment "…" content is not valid base64."pathis a URL. The bytes are fetched at send time, so the URL has to be reachable then.content_typeis a type and a subtype. Parameters are refused: the sentence is "Attachment content type must be a type and a subtype, like application/pdf."content_idmarks an inline image. Reference it from the HTML ascid:followed by that id.contentTypeandcontentIdare accepted as camelCase spellings of the last two.
An email carries at most 100 attachments and 40 MB of base64 in total; over either, the refusal is invalid_attachment. An entry with neither content nor path gets the catalogue message "Each attachment needs content (base64) or path." and the fix "Provide attachment.content or attachment.path in POST /emails." retryable is false on every one of these, so correct the body rather than resending it.
Before a domain is verified, the onboarding sender does not carry attachments. The POST /emails summary says that path allows "no cc/bcc/attachments/tracking/extra headers", and the refusal is onboarding_shape_refused: "The onboarding sender does not accept cc, bcc, attachments, tracking, or extra headers." Its fix is "Omit those fields, or verify a domain with POST /domains and send from that domain."
curl -sS -X GET https://api.agentisend.com/emails/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/attachments \
-H "Authorization: Bearer $AGENTISEND_API_KEY"200
{
"data": [],
"has_more": true,
"next_cursor": "string",
"object": "string"
}Reading back what was sent
GET /emails/{id}/attachments lists them. Its summary is "What this email carried. Ids are stable positions; bytes_available says whether the payload is still retrievable." Each row has id, filename, content_type, size_bytes, content_id, path and bytes_available. GET /emails/{id}/attachments/{aid} returns one file; the summary is "The bytes of one attachment, exactly as they were sent. Served as an inert download." GET /emails/{id}/mime is the whole message as it went out, attachments encoded inside it, which is what to read when a recipient says a file arrived corrupted.
A receiving server that refuses a message for its size or its attachment type produces a bounce in the policy class. Why did my email bounce? says how to read that class, and the fix there is to shrink the file or drop it.