Attachments

Attach files to a message by passing them base64-encoded.

Attachments

Attach files to a message by passing them base64-encoded in the request body. Up to 5 MB decoded per file and 20 MB of attachment data per message (all files combined), with 30 GB in total per send — see Size limits below.

ParameterTypeRequiredDescription
filenamestringRequiredThe filename shown to the recipient.
contentbase64 stringRequiredThe file body, base64-encoded.
content_typeMIME typeRequirede.g. application/pdf, image/png.
dispositionstringOptionalEither attachment (the default — a file the recipient downloads) or inline to embed the part in the message body, e.g. an image referenced from your HTML. Inline parts are delivered as multipart/related.
content_idstringOptionalA CID token for an inline attachment, referenced from your HTML as cid:<content_id>. Must not include angle brackets and must match the cid: reference exactly (case-sensitive). Set it alongside "disposition": "inline".

Inline images (CID)

To embed an image in the body rather than attach it as a file, send it with "disposition": "inline" and a content_id, then reference that id from your HTML as <img src="cid:logo">. The content_id must match the cid: reference exactly and carry no angle brackets. wemail builds the multipart/related message for you.

jsonPOST /v3/messages
{
  "from": "you@yourdomain.com",
  "to": [
    "recipient@example.com"
  ],
  "subject": "Your receipt",
  "html": "<p>Thanks for your order!</p>\n<img src=\"cid:logo\" alt=\"Acme\">",
  "attachments": [
    {
      "filename": "logo.png",
      "content": "iVBORw0KGgoAAAANSUhEUg…",
      "content_type": "image/png",
      "disposition": "inline",
      "content_id": "logo"
    }
  ]
}

Size limits

Two limits apply, on both POST /v3/messages and POST /v3/messages/batch:

ParameterTypeRequiredDescription
Per attachmentlimitOptional5 MB per file, measured on the decoded bytes (not the base64 text). Larger files: upload once via POST /v3/uploads and put the returned link in your HTML.
Per messagelimitOptional20 MB of attachment data per message — all files combined, decoded.
Per sendlimitOptional30 GB of total attachment volume per API call, i.e. attachment size × number of recipients.

The per-send limit exists because email has no deduplication: even though you upload the attachments once, every recipient receives their own full copy, so a bulk send physically delivers attachment size × recipients. A 2.5 MB attachment set sent to 5,000 recipients delivers 12.5 GB of mail. Calls whose total would exceed 30 GB are rejected with a 400 validation_error before anything is sent or charged.

Code examples

cURL
curl -X POST https://api.wemail.io/v3/messages \
  -H "Authorization: Bearer afn_live_pK7…b9aF" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "billing@updates.acme.io",
    "to":   ["alex@example.com"],
    "subject": "Your May invoice",
    "html": "<p>Invoice attached.</p>",
    "attachments": [
      { "filename": "invoice.pdf", "content": "JVBERi0xLjQK…", "content_type": "application/pdf" }
    ]
  }'
Node.js
import { readFileSync } from "node:fs";
import { WemailClient } from "@wemail/sdk";
const wemail = new WemailClient(process.env.WEMAIL_API_KEY);

await wemail.sendMessage({
  from:    "billing@updates.acme.io",
  to:      ["alex@example.com"],
  subject: "Your May invoice",
  html:    "<p>Invoice attached.</p>",
  attachments: [{
    filename: "invoice.pdf",
    content: readFileSync("invoice.pdf").toString("base64"),
    contentType: "application/pdf",
  }],
});
Python
import base64
from wemail.client import WemailClient

wemail = WemailClient(api_key=os.environ["WEMAIL_API_KEY"])

pdf = base64.b64encode(open("invoice.pdf", "rb").read()).decode()
wemail.send_message({
    "from": "billing@updates.acme.io",
    "to": ["alex@example.com"],
    "subject": "Your May invoice",
    "html": "<p>Invoice attached.</p>",
    "attachments": [{"filename": "invoice.pdf", "content": pdf, "content_type": "application/pdf"}],
})
PHP
<?php
$wemail = new \Wemail\WemailClient(getenv('WEMAIL_API_KEY'));
$wemail->sendMessage([
    'from'    => 'billing@updates.acme.io',
    'to'      => ['alex@example.com'],
    'subject' => 'Your May invoice',
    'html'    => '<p>Invoice attached.</p>',
    'attachments' => [[
        'filename' => 'invoice.pdf',
        'content'  => base64_encode(file_get_contents('invoice.pdf')),
        'content_type' => 'application/pdf',
    ]],
]);
Ruby
require "base64"
wemail = Wemail::Client.new(api_key: ENV["WEMAIL_API_KEY"])
wemail.send_message(
  from: "billing@updates.acme.io",
  to:   ["alex@example.com"],
  subject: "Your May invoice",
  html: "<p>Invoice attached.</p>",
  attachments: [{
    filename: "invoice.pdf",
    content: Base64.strict_encode64(File.read("invoice.pdf")),
    content_type: "application/pdf"
  }]
)
Go
client, err := wemail.NewClient(os.Getenv("WEMAIL_API_KEY"))
data, _ := os.ReadFile("invoice.pdf")
client.SendMessage(wemail.SendMessageRequest{
    From:    "billing@updates.acme.io",
    To:      []string{"alex@example.com"},
    Subject: "Your May invoice",
    Html:    wemail.PtrString("<p>Invoice attached.</p>"),
    Attachments: []wemail.SendMessageRequestAttachmentsInner{{
        Filename:    "invoice.pdf",
        Content:     base64.StdEncoding.EncodeToString(data),
        ContentType: wemail.PtrString("application/pdf"),
    }},
})
Java
WemailClient wemail = new WemailClient(System.getenv("WEMAIL_API_KEY"));
byte[] data = Files.readAllBytes(Path.of("invoice.pdf"));
wemail.sendMessage(new SendMessageRequest()
    .from("billing@updates.acme.io")
    .to(List.of("alex@example.com"))
    .subject("Your May invoice")
    .html("<p>Invoice attached.</p>")
    .attachments(List.of(new SendMessageRequestAttachmentsInner()
        .filename("invoice.pdf")
        .content(Base64.getEncoder().encodeToString(data))
        .contentType("application/pdf"))));
.NET
var wemail = new WemailClient(Environment.GetEnvironmentVariable("WEMAIL_API_KEY"));
var bytes = File.ReadAllBytes("invoice.pdf");
await wemail.SendMessageAsync(new SendMessageRequest {
  From = "billing@updates.acme.io",
  To = new List<string> { "alex@example.com" },
  Subject = "Your May invoice",
  Html = "<p>Invoice attached.</p>",
  Attachments = new List<SendMessageRequestAttachmentsInner> { new SendMessageRequestAttachmentsInner {
    Filename = "invoice.pdf",
    Content = Convert.ToBase64String(bytes),
    ContentType = "application/pdf",
  }},
});
ResponseExample response
{
  "id": "msg_01HBYE7K9Z4PMQDR3W",
  "status": "queued",
  "created_at": "2026-05-10T09:42:18Z",
  "to": ["alex@example.com"],
  "attachments": [{ "filename": "invoice.pdf", "size": 20481 }]
}