How to Build a Signup Email Verification Flow
A signup email verification flow proves the address is real before you trust it. Here is how to build one that blocks fakes without killing conversion.
A signup email verification flow exists to prove one thing: the person who typed that address can read mail sent to it. That is it. Everything else, the welcome copy, the product tour, comes after. If you skip verification, you fill your database with typos, throwaway addresses, and bots, and you poison your sending reputation by mailing addresses that bounce. Build the verification step first, then earn the welcome.
Why verify the email at signup at all?
Three reasons, and they compound. First, deliverability: every send to a fake or mistyped address is a bounce, and a high bounce rate tells mailbox providers you are careless, which lands your good mail in spam. Second, security: an unverified address means anyone can register accounts under emails they do not own, which enables spam, impersonation, and abuse of your reset flow. Third, data quality: an unverified list is a list you cannot trust for anything.
Verification is the cheapest quality gate you will ever build. It costs one email and one click. The trick is doing it without adding friction that kills your signup conversion.
How does an email verification flow work?
Same token machinery as a password reset, different intent. On signup, create the account in an unverified state, generate a random token, store its hash with a timestamp, and email the raw token in a link. When the user clicks, you match the hash, mark the account verified, and delete the token. This shares so much logic with resets that I build both on one token service. The mechanics are the same ones I use in a secure password reset email flow.
Let unverified users into a limited state rather than blocking them at the door. They can see the app, but the actions that matter (inviting teammates, sending mail, spending money) stay locked until they verify. This keeps conversion high while still forcing the gate before anything risky happens.
Should I use a code or a link to verify?
Depends on the surface. A magic link is smooth on desktop: click and you are in. A six-digit code is better on mobile and cross-device, because the user might sign up on a laptop and open mail on a phone. Codes also work when the click would land in a different browser session and lose context.
My default: send both. A big button for the click, and the code printed below it for people who cannot click through cleanly. Keep the code short, expire it in ten to fifteen minutes, rate limit attempts so nobody brute-forces a six-digit code, and lock out after a handful of tries. Make the verification email arrive in seconds, because a user staring at your "check your inbox" screen is a user you are about to lose. Speed here is a conversion feature, which is why I treat transactional email as infrastructure and not a nice-to-have.
How do I keep verification from killing conversion?
Send instantly. A verification email that takes two minutes loses people who assume it is broken. Provider speed is the difference between a verified user and an abandoned tab.
Add a visible resend button with its own rate limit, because the first email sometimes lands in spam or gets missed. Show the address you sent to, so a typo is obvious on screen ("we sent to jhon@example.com" catches the error the user made). And watch your verification-email bounces closely: a spike means people are entering garbage, or your sending setup broke. Bounce handling here is not optional; it is how you keep the list clean, the same way you would handle bounces and suppression lists anywhere else.
What to send after they verify
Now, and only now, the welcome. The verification email is not the place to sell; it is the place to open the gate. Keep it short: confirm the address, give the button and code, state the expiry. Once verified, trigger your real onboarding, which should fire on product events rather than a fixed drip.
Run all of it on a sender built for application mail so verification lands fast and you get the delivery events to prove it. Usermails is what I reach for: developer-first sending with the webhooks to watch every verification click. Gate the risky actions, verify before you trust the address, and your list stays clean from the first signup.