invoice email
Invoice emails: send invoices with PDF attachments by API
How to email an invoice with a PDF attachment through an email API: what to include, attachment limits, deliverability and complete code.
In short
To email an invoice, generate the PDF on your server, base64-encode it and send it as an attachment with content_type application/pdf, alongside a short HTML body with the invoice number, amount and due date. Use an Idempotency-Key per invoice so a retry never bills twice in the customer's inbox, and set reply_to to your billing address.What to include
- Invoice number, amount and due date in the body - not only inside the PDF.
- The PDF attached, named so it sorts well: invoice-2026-10428.pdf.
- How to pay, or confirmation that it has already been paid.
- Who to contact about billing, via reply_to.
Best practices
Keep attachments small
Sendpository accepts up to 10 files and 10 MB per message. Invoices are usually well under 1 MB - compress embedded images.
Set the content type
content_type: application/pdf lets mail clients preview the invoice instead of offering a generic download.
Idempotency per invoice
Idempotency-Key: invoice-10428 means a retried billing job never sends the same invoice twice.
Say it in the body too
Some clients hide attachments on mobile. The amount and due date in the HTML mean nobody has to open the PDF to know what they owe.
Track delivery, not opens
Listen for email.bounced and email.delivered webhooks to know an invoice arrived; open tracking is unreliable evidence of anything.
Subject lines that work
Invoice #10428 from Acme - ₹4,720 due 15 OctYour Acme invoice for SeptemberReceipt for your Acme payment (#10428)
Send it
import { readFile } from "node:fs/promises";
const pdf = await readFile(`/tmp/invoice-${invoice.number}.pdf`);
const res = await fetch("https://api.sendpository.com/v1/emails", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.SENDPOSITORY_API_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": `invoice-${invoice.number}`,
},
body: JSON.stringify({
from: "Acme Billing <billing@mail.yourdomain.com>",
to: [invoice.email],
reply_to: ["billing@yourdomain.com"],
subject: `Invoice #${invoice.number} from Acme`,
html: `<p>Invoice #${invoice.number} for ${invoice.total} is attached. It is due on ${invoice.dueDate}.</p>`,
text: `Invoice #${invoice.number} for ${invoice.total}, due ${invoice.dueDate}. PDF attached.`,
attachments: [
{
filename: `invoice-${invoice.number}.pdf`,
content_type: "application/pdf",
content: pdf.toString("base64"),
},
],
tags: { type: "invoice", invoice: String(invoice.number) },
}),
});
if (!res.ok) throw new Error((await res.json()).error.type);Using another language? The same request works from any stack - it is JSON over HTTPS.
Questions
How do I send an invoice as an email attachment with an API?
Base64-encode the PDF and include it in the attachments array with a filename and content_type application/pdf. Sendpository accepts up to 10 attachments and 10 MB per message.
Do invoice emails with attachments go to spam?
Not when the domain is authenticated and the attachment is a normal PDF. Executable file types are refused outright. Put the key details in the body as well, so the message isn't just an attachment.
Should I attach the invoice or link to it?
Attach it for small businesses and accountants who file email; link to it when invoices are large or contain data that should require a login. Many products do both.
Related
Send your first email in minutes
6,000 emails a month (up to 200 a day), free forever. No card needed.