Attachments
Choose the source of the bytes
| You already have | Use | Supply |
|---|---|---|
| Bytes in memory | BufferAttachment | content: Buffer |
| Base64-encoded bytes | Base64Attachment | content: string and encoding: "base64" |
| A file available to the implementation | PathAttachment | path |
| A file reachable by the implementation | UrlAttachment | url |
Paths are server-side paths, not paths on the recipient's computer. Use trusted or validated paths and URLs; do not let untrusted input select arbitrary local files or internal network addresses. Check provider size limits before sending.
Attachment Types
BufferAttachment
Use BufferAttachment when you have file data in memory as a Node.js Buffer. This is common when generating files dynamically or reading from streams.
import { Send, type BufferAttachment } from "@antelopejs/interface-email";
const reportBuffer = Buffer.from(
"Quarterly report\nRevenue: 12500 EUR\n",
"utf8",
);
const attachment: BufferAttachment = {
filename: "report.txt",
contentType: "text/plain",
content: reportBuffer,
};
await Send({
to: "[email protected]",
subject: "Your Report",
text: "Please find the attached report.",
attachments: [attachment],
});
Base64Attachment
Use Base64Attachment when you have file data encoded as a base64 string. Set the encoding field to "base64" to distinguish it from a BufferAttachment.
import { Send, Base64Attachment } from "@antelopejs/interface-email";
const attachment: Base64Attachment = {
filename: "notes.txt",
contentType: "text/plain",
content: "SGVsbG8h", // Base64 for "Hello!"
encoding: "base64",
};
await Send({
to: "[email protected]",
subject: "Meeting Notes",
text: "Notes attached.",
attachments: [attachment],
});
PathAttachment
Use PathAttachment to attach a file from the local filesystem by its path. The email provider reads the file at send time.
import { Send, PathAttachment } from "@antelopejs/interface-email";
const attachment: PathAttachment = {
filename: "data-export.csv",
contentType: "text/csv",
path: "/tmp/exports/data-export-2026.csv",
};
await Send({
to: "[email protected]",
subject: "Data Export",
text: "The requested export is attached.",
attachments: [attachment],
});
UrlAttachment
Use UrlAttachment to attach a file from a remote URL. The email provider fetches the file from the URL at send time.
import { Send, UrlAttachment } from "@antelopejs/interface-email";
const attachment: UrlAttachment = {
filename: "handbook.pdf",
contentType: "application/pdf",
url: "https://cdn.example.com/docs/handbook-v3.pdf",
};
await Send({
to: "[email protected]",
subject: "Employee Handbook",
text: "Please review the attached handbook.",
attachments: [attachment],
});
Inline Images
Inline attachments embed images directly in the HTML body using Content-ID references. Set inline to true and assign a cid value, then reference it in your HTML with the cid: protocol.
The following example reads a real PNG at ./assets/logo.png, relative to the server's working directory. Supply that file before running it.
import { readFile } from "node:fs/promises";
import { Send } from "@antelopejs/interface-email";
const logoBuffer = await readFile("./assets/logo.png");
await Send({
to: "[email protected]",
subject: "Welcome",
html: `
<div>
<img src="cid:company-logo" alt="Company Logo" />
<h1>Welcome to our platform!</h1>
</div>
`,
attachments: [
{
filename: "logo.png",
contentType: "image/png",
content: logoBuffer,
cid: "company-logo",
inline: true,
},
],
});
Note: Check
(await GetCapabilities()).features.inlineAttachmentsto confirm the provider supports inline images.
Multiple Attachments
The attachments field accepts an array, so you can mix different attachment types in a single email:
import { Send } from "@antelopejs/interface-email";
await Send({
to: "[email protected]",
subject: "Project Deliverables",
text: "All deliverables are attached.",
attachments: [
{
filename: "proposal.pdf",
contentType: "application/pdf",
path: "/documents/proposal.pdf",
},
{
filename: "mockup.png",
contentType: "image/png",
url: "https://cdn.example.com/mockups/v2.png",
},
{
filename: "notes.txt",
contentType: "text/plain",
content: Buffer.from("Meeting notes for the project kickoff."),
},
],
});
The BaseAttachment Interface
Every attachment requires a filename. These shared fields apply to all four sources:
| Field | Type | Required | Description |
|---|---|---|---|
filename | string | Yes | The filename shown to the recipient |
contentType | string | No | MIME type (e.g., "application/pdf") |
cid | string | No | Content-ID for inline images (reference in HTML as cid:yourCid) |
inline | boolean | No | If true, embed in the HTML body instead of attaching as a file |
The Attachment Union Type
The Attachment type is a union of all four attachment interfaces:
type Attachment =
BufferAttachment | Base64Attachment | PathAttachment | UrlAttachment;
When constructing attachments dynamically, TypeScript narrows the type based on the presence of distinguishing fields (content with encoding, path, or url).
Sending Emails
The interface provides three sending functions: Send for single emails, SendTemplate for template-based emails, and SendBatch for multiple emails in one operation.
Introduction
Let clients transfer bytes directly to storage while your server authorizes uploads and manages file references. @antelopejs/interface-file-storage defines the contract; an implementing module supplies the backend, URL signing, and storage configuration.