Skip to main content

Mail Merge Guide

Send every row of a spreadsheet its own PDF (an invoice, statement, certificate or letter) as an email attachment, from your own mailbox.

This guide walks through a first campaign. For every field and error, see the mail merge API reference.

What you need​

  1. A template. Design the document once in the dashboard under Templates. Each {{field}} in it becomes a column you fill from the spreadsheet.
  2. A spreadsheet. CSV or Excel (.xlsx), with a header row and one row per recipient, including a column with each email address.
  3. A sender. The SMTP details of the mailbox the emails should come from.

1. Add a sender​

In the dashboard, open Mail merge → Senders → Add sender. Pick your provider and the server settings fill in.

ProviderServerPortPassword to use
Gmail / Google Workspacesmtp.gmail.com587An app password, not your normal password
Microsoft 365 / Outlooksmtp.office365.com587Your password; SMTP AUTH must be turned on for the mailbox in the Microsoft 365 admin center
Zoho Mailsmtp.zoho.com465An app-specific password if two-factor sign-in is on
Brevosmtp-relay.brevo.com587An SMTP key from SMTP & API
SendGridsmtp.sendgrid.net587Username apikey, password your API key

After saving, send the test email: it arrives with a small PDF attached. Only then can the sender run campaigns. We store the password encrypted and never show it again.

Know your provider's limits

Your mailbox's own daily limit applies: about 500 a day on Gmail, 2,000 on Google Workspace, and 10,000 recipients on Microsoft 365. For bigger lists, use a sending service such as Brevo or SendGrid as the sender. If your provider limits the rate, set Emails per minute on the sender and campaigns will stay under it.

2. Prepare the spreadsheet​

Email,Name,Invoice #,Amount,Due
ann@example.com,Ann Lee,INV-1001,"1,204.50",2026-10-31
bo@example.com,Bo Chan,INV-1002,88.00,2026-10-31
  • Numbers. 1,204.50, $12.00 and 20% are read as numbers.
  • Dates. Write them as 2026-10-31. Excel dates are converted for you.
  • Repeated addresses get one email (turn this off with options.dedupe: false in the API).
  • Limits. Up to 100 rows per campaign. For more, choose Request a higher limit under Mail merge: say how many you need (up to 10,000) and what you are sending. We review requests within one business day.

3. Create the campaign​

Mail merge → New campaign walks through six steps:

  1. Template. Pick the document every recipient gets.
  2. Recipients. Upload the file. The first rows are shown so you can check it was read correctly.
  3. Columns. Match each template field to a column. Matches are suggested from the column names.
  4. Email. Choose the sender and write the subject and message. The { } button inserts variables: template fields, or any column (Invoice # becomes {{invoice}}).
  5. Review. Every row is checked: bad addresses, missing required values and duplicates are listed with their row numbers. Step through rows to see each email and PDF exactly as it will be sent, then send one to yourself.
  6. Send. Confirm that every recipient agreed to receive these emails, and start.

You can close the page while it sends. Progress shows under Mail merge, and we email you when it finishes.

4. Read the results​

The campaign page and the report CSV show what happened to every row:

ResultWhat it meansCharged
SentYour mail server accepted itYes
RejectedYour server refused that addressNo
FailedThe PDF could not be made, or the server refused the messageNo
UnconfirmedThe connection dropped just after the message was sent. It may have arrived, so it is not sent againNo
SkippedInvalid or duplicate row, or the campaign stopped firstNo

If your mail server rejects the password mid-campaign (for example after a password change), the campaign stops, the sender is marked failing, and the unsent rows are skipped. Fix the sender, send it a test, then send the skipped rows in a new campaign.

Doing it with the API​

Everything after adding the sender works with an API key: create, preview, test, start, follow progress and download the report.

curl -X POST https://api.podpdf.com/mailmerge/campaigns \
-H "X-API-Key: your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"template_id": "YOUR_TEMPLATE_ID",
"connection_id": "YOUR_CONNECTION_ID",
"input": { "csv": "Email,Name,Amount\nann@example.com,Ann Lee,1204.50\n" },
"mapping": { "customer.name": "Name", "amount": "Amount" },
"email": {
"subject": "Your statement, {{customer.name}}",
"body_text": "Hello {{customer.name}},\nYour statement for {{amount}} is attached."
},
"start": true,
"consent": { "confirmed": true }
}'

Then poll GET /jobs/{campaign_id}, or subscribe a webhook to mailmerge.campaign.completed and mailmerge.campaign.partial.

Good sending practice​

  • Consent. Only email people who agreed to hear from you: for invoices and statements, your customers.
  • Unsubscribe. Add an unsubscribe link for anything that is not strictly transactional. The Unsubscribe link setting adds the List-Unsubscribe header mail providers look for.
  • Test first. Send yourself a test and check it in Gmail and Outlook before a large campaign.
  • Authenticate your domain. Make sure your domain's SPF and DKIM records cover your mail provider, so campaigns land in the inbox rather than spam.