Four things the API was missing. Nothing you already send changes.
Four additions, none of which change anything you are already doing.
Templates
Store a subject and body once, send it by name:
{
"from": "[email protected]",
"to": "[email protected]",
"template_slug": "welcome",
"variables": { "name": "Ada" }
}
The whole template language is {{name}}, escaped in the HTML part, and {{{name}}} when
you are passing markup you built yourself. No loops, no conditionals, no expressions —
that is a ceiling rather than a roadmap. If you need a list of order lines, build the
markup in your own language, where you can test it, and pass it as one variable.
A variable the template uses and you did not supply is a 422 naming every one that is
missing, not an empty string. "Hi ," sent to a hundred thousand people is worse in every
way than a send that did not happen.
Every save keeps a version, and restoring writes the old one forward rather than
rewinding, so a restore is itself something you can undo. The dashboard has an editor
with a live preview, the variables it found in your body, and a button that sends it to
you in test mode.
Batch send
POST /v1/emails/batch takes up to 100 messages. Each one is validated, limited and
queued exactly as a single send is, so one suppressed address in a nightly run costs you
that message and nothing else. The response reports per message, in request order.
Attachments from a URL
An attachment can now be a link instead of base64:
{ "filename": "invoice.pdf", "url": "https://cdn.acme.com/invoices/123.pdf" }
We fetch it when the send is accepted, so a broken link fails on the call that made it
rather than two seconds later. Base64 still works exactly as before.
Key scopes
A key can now be limited to what it needs. The one worth having is send only — the
key you put in an application server, which can send and cannot read back what it sent
or change anything about the account. The create-key dialog offers it as a preset.
Existing keys are unaffected: every key made before today has every scope, and a new key
created without naming any still does. Narrowing is something you choose.