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

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

Send it

Node.js
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.