
The notification you cannot change the wording of
A compliance reviewer usually asks two questions about transactional email. What exactly did this customer receive the day they signed up, and who signed off on that wording. If your password reset lives as a template in a platform dashboard, you can answer the first question for a few weeks and the second one not at all. Nobody notices that until the review lands, which is the point at which it gets expensive.
Editing the copy is easy, proving you edited it is not
Changing the subject line of a confirmation email takes about forty seconds in any platform builder. That part was never the constraint. What you do not get is a diff, a reviewer, an approval, or a record that the old wording ever existed. The template is a text field in someone else's database, and text fields do not keep history.
Supabase handles this better than most, because it lets you leave the dashboard entirely. You can read and write its auth email templates through the Management API with a PATCH to /v1/projects/{ref}/config/auth, and self-hosted or local projects configure them in supabase/config.toml with the HTML sitting in files next to your code. That one detail turns legal copy into something that lives in git, gets reviewed in a pull request, and ships through CI like everything else.
The templating is nothing exotic. Supabase exposes variables such as {{ .ConfirmationURL }}, {{ .Token }} and {{ .Data }}, the last of which reads from auth.users.user_metadata. You could rebuild that rendering in an afternoon. Rendering is not the thing worth moving. Ownership of the file is.
Retention is the limit nobody shops for
Resend holds email data for 30 days on Free, Pro and Scale alike, listing flexible retention only on Enterprise. Supabase gives you 7 days of log retention on the $25 Pro plan and 28 days on Team at $599 a month, or you add Log Drains at $60 per drain per project and ship the logs somewhere you control. Those figures come from the vendors' own pricing pages, checked today, and they are reasonable numbers for what the products do. They are simply shorter than an audit window.
Imagine the question arriving in March about an email sent in December. On a default setup there is no record to produce. Nothing failed. Retention past 30 days was never something you bought. Teams find this out during SOC 2 readiness and then negotiate a plan upgrade under deadline pressure, which is a bad time to negotiate anything.
Owning the send path makes the whole question dull. You write a row to your own database before the provider is called: recipient, template version, a hash of the rendered body, timestamp. The email vendor goes back to being a delivery mechanism you can swap out. Resend charges $20 a month for 50,000 transactional emails and $0.90 per extra thousand, cheap enough that the provider was never the expensive part. The lock-in sat in the template and the log.
What this looked like in practice
When we moved Stay World Class off Webflow and Xano onto Next.js, NestJS and Supabase, the notification layer was not the headline. The headline was Lighthouse going from 55.91 to 91 out of 100, with LCP landing 77% faster. The data moved through a four stage ETL that mapped every legacy ID onto a PostgreSQL UUID so no historical record lost its identity.
The quieter win arrived later. Email copy became a file in the repository. Someone proposed a change, someone else read it, and the record of who approved what fell out of normal work instead of a separate compliance exercise. Nobody had to remember to document anything.
When the template is still the right answer
If your product sends a password reset and a magic link and nothing else, and no auditor has ever asked you for a sent-mail record, the platform template is correct and rebuilding it wastes a sprint. Same for an internal tool with twelve users. A retention limit only hurts someone who will be asked about it.
The signal to watch for is specific. The first time somebody outside engineering wants to approve wording before it goes out, or asks what a given customer received on a given date, your notification layer has joined your compliance surface. That is the week to move it, rather than the week the auditor writes to you.
