You need: email composed and provisioned.
Pick the template by what the message is
The template model is why that decision belongs to the template rather than the call site. Sending a transactional email is the shortest version, localized mail is what the recipient reads, and theming is what it looks like.
| Template | For |
|---|---|
magicLink, otp | Sign-in |
welcome | A new account |
securityAlert | Something they should know about now |
passwordChanged | A credential changed |
invite | Somebody is waiting on them |
operationalNotice | An operator’s message, in the kit’s shell |
supportReply | An answer to a support thread |
testerNudge | A testing-program reminder |
newsletter, marketingCampaign | Promotional |
leadCapture | A follow-up they opted into |
The one that only translates half of itself
The fix is to localize your own copy before you enqueue:
const summary = c.var.t.t("app/key_rotation.failed", { key });
await enqueueEmail(db, { template: "operationalNotice", payload: { summary, severity: "warning" }, locale });A key under your own capability’s name, translated in your own messages, handed over with the same locale.
A catalog cannot translate a sentence it has never seen.
Which five are like this
testerNudge · supportReply · operationalNotice · newsletter · marketingCampaign
The other seven are the kit’s own copy and are translated with it — adding a language the kit ships costs you a package upgrade and no configuration.
Category and kind are different questions
category — what the message is. A marketing template cannot render without an unsubscribe link, full stop.
kind — whether the recipient may refuse it.
A tester nudge is transactional in style and elective in consent, and that is exactly why one field could not have said both.
Do not open a second delivery path
Enqueue through the email capability, even from another capability’s code.
Anything that sends its own mail loses the retries, the suppression list and the bounce handling — which is precisely what the testers capability avoids by enqueuing its invitations rather than sending them.
Bounds on how often you can chase somebody
If your notification is a reminder, put a cooldown on it and a cap on the total.
The testers capability does both: a per-recipient cooldown enforced server-side on every path, and chasing that stops after three unanswered messages.
A nudge trigger with no guard is a button that mails the same twelve people repeatedly — and the fastest way to lose an audience is to become the reason they muted you.