Vibe Coding Email

Adding Email and Notifications to Your Vibe Coded App

The moment your app has accounts, it needs to send email — a password reset link, a "confirm your address" message, a receipt after a payment, an alert when something happens. It feels like the simplest feature yet: call a "send email" function with an address and some text. But email fails in ways a button never does. Sent carelessly, your messages land in spam and the reset link never arrives; your API key leaks and someone uses your account to send spam in your name; or a notification goes to the wrong person and quietly leaks what should have been private. This guide covers the safe way to add email as a vibe coder: why you shouldn't send it from your own server, the exact prompt to ask for, and why a "send email" button is not the same as a delivered, safe message.

Last reviewed: Jul 24 2026

A glowing translucent envelope of light travels along a rail through a corridor of layered authentication gates toward one illuminated mailbox, with a single gate lit in warm amber where the message is verified before it is allowed to pass.
An authenticated gate proves a message is really yours to send — one of the checks between your app and the inbox.

Why Sending Email Deserves Extra Scrutiny

Email is one of the easiest features to ask AI for, and one of the easiest to get wrong in ways you won't see from the outside. AI can produce a working sendEmail() call, an "Email sent!" message on screen, and a message that arrives cleanly in your own inbox during testing — and it will look finished. What's easy to miss: whether real users' mail actually reaches their inbox instead of their spam folder, whether the sending key is exposed where a visitor could take it, and whether the app can be tricked into emailing the wrong person or the wrong content.

The good news is the same as with accounts, payments, and uploads: you don't need to run mail infrastructure yourself to do this safely. You need to avoid one common mistake — trying to deliver mail directly from your own app server instead of using a hosted provider — and confirm a few things AI tools often skip by default: that the sending happens on your backend where the key stays secret, that your sending domain is authenticated so receiving systems can verify it, and that the recipient and contents come from your own verified data, never straight from whatever a request claimed.

Deliverability Is a Feature, Not a Given

A message that "sends successfully" has not necessarily been delivered. Your code getting a 200 response from an email service only means the service accepted the request — not that the mail reached an inbox instead of a spam folder or a silent block. Password resets and verification links are the emails users notice most when they fail to arrive, and the ones they can't work around. Treat "did it reach the inbox?" as part of the feature, not an afterthought.


The Safe Default: A Hosted Email API

Just as a hosted auth provider takes password storage off your plate, a hosted email service takes mail delivery infrastructure off your plate: it operates the sending network, retries temporary failures, and tells you when a message bounced or drew a spam complaint. Your app makes one authenticated API call from its backend (or uses the provider's authenticated SMTP relay); the service handles delivery. Trying to deliver mail directly from your own app server means managing IP reputation, warm-up, feedback loops, and blocklists — specialist work that hosted services exist to remove.

Authenticate Your Sending Domain: SPF, DKIM, and DMARC

Domain authentication is a foundation for deliverability, not a guarantee of the inbox. SPF authorizes sending systems, DKIM adds a verifiable signature, and DMARC tells receivers what to do when authentication does not align with the address users see in the From field. Follow the provider's exact DNS setup: some ask you to publish SPF records, while others manage SPF through their own return-path and only require you to add DKIM. Then publish a DMARC policy for your domain using the provider's or your domain host's instructions. Authentication lets receivers verify your mail, while reputation, complaint and bounce rates, message content, and recipient engagement still affect placement. Don't send real user mail from an unverified domain (or impersonate a free @gmail.com-style address whose DNS you don't control) and expect reliable delivery.


The Prompt to Ask For

Name the hosted service explicitly so AI doesn't invent self-managed delivery, and ask for backend sending, key safety, and a verified sender in the same prompt so none of them is left as an afterthought:

Prompt

Add transactional email to my app using [Resend / Postmark / Amazon SES] for [password reset / email verification / receipts / notifications]. Send the email from my backend, never from the browser, and read the API key from a server-side environment variable — never hardcode it or expose it to client code. The final recipient must be loaded from my own database record for the account the verified action belongs to, not copied blindly from the request. For password reset, use the submitted address only to look up the account, return the same generic response whether or not it exists, and send a short-lived, single-use reset link created by my auth system only to the stored address. Do not put any unvalidated user input into the email's subject, headers, or the "to"/"from"/"reply-to" fields. Tell me which DNS records I need to add to authenticate my sending domain, and give me a way to send a test message before I wire it into real user actions.

When the AI returns code, check for these things before you consider it done:

  1. Sending happens on the server, and the API key lives in an environment variable — not in client-side code, not in a committed file. If the key can be read from anything the browser downloads, treat it as already leaked.
  2. The final recipient comes from your own trusted data — the signed-in user's stored address or the account record found during a reset flow — not from a request field that a caller could use to redirect someone else's receipt or notification.
  3. No raw user input is placed into subjects, headers, or address fields — the next section explains why an attacker controlling those can turn your app into a spam relay.
  4. Domain authentication is part of setup — the provider dashboard shows your domain as verified, with SPF and DKIM in place, before you rely on delivery.

Why a "Send Email" Button Isn't a Delivered, Safe Email

The dangerous shortcut with email is letting the browser decide who gets mailed and what it says. If your frontend calls an endpoint that emails "whatever address and message the request contained," anyone can call that endpoint directly — not just through your form — and use your verified domain and your sending quota to deliver mail of their choosing. That's how a small app quietly becomes a tool for sending spam or phishing in your name, which also wrecks the sending reputation your real mail depends on.

The Server Decides Who Gets Mailed, Not the Request

Sending must happen on your backend, triggered by a verified event, with the final recipient looked up from your own data. A password-reset form necessarily accepts an address, but the server should use it only to find the account and then mail the address stored on that record; its on-screen response should look the same even when no account exists, so the form does not reveal who has signed up. A receipt goes to the buyer your verified payment record names. When the recipient and content are derived from records you trust, a malicious request has nothing to redirect. When an endpoint will send arbitrary content to an arbitrary address from the request, it is an open door.

There's a related, quieter failure that has nothing to do with attackers: sending the right email to the wrong person. If a notification loop reuses a variable, an off-by-one selects the wrong user, or a test address is left wired in, your app can cheerfully deliver one user's receipt, reset link, or private alert to someone else. Because email leaves your system and can't be recalled, that's a data leak, not a bug you can quietly patch. Verify that the address is loaded fresh from the correct record for each message, and test with two separate accounts to confirm each one only ever receives its own mail — the same two-account discipline used for accounts and file access.

Prompt

Show me exactly where each email's final recipient address comes from. Confirm it's loaded from my database for the specific account the action belongs to, and that no general email endpoint will send arbitrary content to an arbitrary address from the request body. For password reset, confirm the submitted address is used only for account lookup, the public response does not reveal whether the account exists, and the auth system creates an expiring, single-use link. Then give me a test with two different accounts and one nonexistent address so I can verify that each account only receives its own mail and all three reset requests show the same public response.


Transactional vs Marketing Email

Not all email is the same, and mixing the two is a common way to get your whole domain filtered. Transactional email is a direct response to something a specific user did: a reset link, a verification code, a receipt, an alert they asked for. Marketing email is something you decided to send — announcements, newsletters, re-engagement nudges — often to many people at once. The safety rules differ.


Test Mode Before Live

Email is unusually easy to test wrong, because during development every message goes to you and everything looks fine. The failures show up only with real, varied recipients. A few habits close that gap:


Pre-Launch Email Checklist

Related Guides

Adding User Accounts to Your Vibe Coded App

Email verification and password reset are where most apps first need to send mail — the accounts guide this one builds on.

Adding Payments to Your Vibe Coded App

Receipts and payment alerts are transactional email too — hosted checkout, webhooks, and what to verify before real money moves.

Growing Your Vibe Coded App

Adding features, handling real users, and keeping an eye on cost and reliability as your app grows.

Sanitizing Code and Data Before Sending to AI

What to scrub before pasting code or credentials into an AI conversation — including email API keys.

Back to Home