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.
| Parameter | Type | Required | Description |
|---|---|---|---|
filename | string | Required | The filename shown to the recipient. |
content | base64 string | Required | The file body, base64-encoded. |
content_type | MIME type | Required | e.g. application/pdf, image/png. |
disposition | string | Optional | Either 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_id | string | Optional | A 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.
{
"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:
| Parameter | Type | Required | Description |
|---|---|---|---|
Per attachment | limit | Optional | 5 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 message | limit | Optional | 20 MB of attachment data per message — all files combined, decoded. |
Per send | limit | Optional | 30 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 -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" }
]
}'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",
}],
});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
$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',
]],
]);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"
}]
)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"),
}},
})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"))));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",
}},
});{
"id": "msg_01HBYE7K9Z4PMQDR3W",
"status": "queued",
"created_at": "2026-05-10T09:42:18Z",
"to": ["alex@example.com"],
"attachments": [{ "filename": "invoice.pdf", "size": 20481 }]
}