Setting the file. One moment.
Skill 130 · Sending Transactional Emails
Subchapter 130.1
references/moving-from-other-providers.mdMarkdown5 KBView on GitHub
Move one email at a time. Pick a low-risk email first, switch it, check a few real sends, then move the next one.
A PostHog send takes a template ID, one recipient, the values for the template’s placeholders, the recipient’s distinct ID, and an idempotency key. The subject, body, sender and reply-to address live on the template, so move them out of the code and into the template.
| Provider | What the code sends today | In PostHog |
|---|---|---|
| Customer.io transactional | transactional_message_id, to, identifiers, message_data | Almost the same shape. templateId / template_id, to, distinctId / distinct_id, templateData / template_data |
| Loops | transactionalId, email, dataVariables | templateId, to, templateData |
| Postmark | TemplateAlias or TemplateId, To, TemplateModel | templateId, to, templateData |
| SendGrid | templateId, to, dynamicTemplateData | templateId, to, templateData |
| Mailgun | template, to, h:X-Mailgun-Variables | templateId, to, templateData |
| Amazon SES | A template name and template data, or a raw subject and body | templateId, to, templateData |
| Resend, Mandrill, Brevo | Often a subject and an HTML body, or a React Email component, built in code | Build the email as a PostHog template, then send templateId, to, templateData |
| nodemailer or SMTP | A subject and a body built in code | Build the email as a PostHog template, then send templateId, to, templateData |
designing-email-templates skill. Start from the email the provider sends today, so it keeps the same logo, colors, and layout. Ask the user for its HTML or a screenshot if you can’t read it. For an email built in code, such as a React Email component, render it once and use the result as the starting design.name becomes {{ variables.name }}. The template can’t read person properties, so pass every value in templateData.recipient_suppressed, recipient_unreachable, and quota_limited. A code that means “don’t retry” must not go back into a retry loop.workflows-reputation-get before the switch.Watch the first sends. Read a few statuses from the user’s code, and look at the template’s Sends and Metrics tabs. Remove the old provider’s code for that email only when the user is happy with it.