Docs/Sending email

Attachments & inline images

A message can carry files. Add them as downloadable attachments, or mark one inline and reference it from the HTML body so it renders in place.

Attach a file

attachments is an array on POST /v1/email. Each entry is one file, with the content base64-encoded:

curl https://api.anypost.com/v1/email \
  -H "Authorization: Bearer $ANYPOST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "Acme <[email protected]>",
    "to": ["[email protected]"],
    "subject": "Your invoice",
    "html": "<p>Invoice #1190 is attached.</p>",
    "attachments": [
      {
        "filename": "invoice-1190.pdf",
        "content_type": "application/pdf",
        "content": "JVBERi0xLjQKJeLjz9MK..."
      }
    ]
  }'

The recipient sees invoice-1190.pdf as a download. Pass the raw file bytes (a Uint8Array or Node Buffer) as content and the SDK base64-encodes them; pass an already-encoded string and it is sent as-is.

The attachment object

FieldRequiredDescription
filenameYesName shown to the recipient, 1 to 255 characters. Path components and any NUL, CR, or LF are stripped; a name that strips to empty is rejected.
contentYesThe file bytes, base64-encoded.
content_typeNoMIME type, as type/subtype. Defaults to application/octet-stream; an unrecognized value falls back to the same.
content_idNoMarks the attachment inline and names it for a cid: reference. Omit it for an ordinary download.

Encoding the content

content is the raw file, base64-encoded. Encode it before building the request body:

base64 -i invoice-1190.pdf      # macOS
base64 -w0 invoice-1190.pdf     # Linux

Base64 inflates the data by about a third, and the whole request body is capped at 5 MB. That puts the practical ceiling for one file's raw size near 3.5 MB, lower once other fields and any further attachments are counted. A request over the body limit is rejected with 413 before any processing.

Inline images

To show an image inside the HTML body rather than as a download, give the attachment a content_id and reference that ID from the body with a cid: URL:

curl https://api.anypost.com/v1/email \
  -H "Authorization: Bearer $ANYPOST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "Acme <[email protected]>",
    "to": ["[email protected]"],
    "subject": "Welcome to Acme",
    "html": "<p><img src=\"cid:logo-1\" alt=\"Acme\"></p><p>Glad you are here.</p>",
    "attachments": [
      {
        "filename": "logo.png",
        "content_type": "image/png",
        "content_id": "logo-1",
        "content": "iVBORw0KGgoAAAANSUhEUg..."
      }
    ]
  }'

The content_id value and the cid: reference must match. Angle brackets and CR/LF are stripped from content_id before the message is built, so write it bare: logo-1, not <logo-1>.

An attachment with a content_id is marked inline; one without is offered as a download. The same file can only be one or the other in a given message.

Limits

LimitValue
Attachments per message20
Filename length255 characters
Request body5 MB total, base64-encoded

The 5 MB ceiling covers the entire request: every attachment, the body, and all other fields together.

Attachments in a batch

In a batch send, an attachment list set in defaults is appended to each entry's own list. When every message in the batch carries the same file, put it in defaults.attachments so its bytes count once against the 5 MB body limit instead of once per entry.

Where to go next