Back to Blog

Verification Code Email Template for One-Time Passwords

8 min read
Verification Code Email Template for One-Time Passwords

Verification-code emails are small but security-sensitive. The template must change its purpose label for signup, login, email change, and sensitive actions so a recipient knows what they are authorizing.

Purpose-specific fields

PurposeIntroSuccess state
SignupConfirm your email addressAccount activation
LoginVerify your sign-inAuthentication attempt
Address changeConfirm the new addressNew address becomes active
Sensitive actionConfirm this account actionAction is authorized

Bind the code to the purpose. A signup code should not authorize a password reset.

Template

Subject: Your {{product_name}} verification code

Preheader: Use this one-time code to {{purpose}}.

Use this code to {{purpose}}:

{{verification_code}}

The code expires in {{expiration_minutes}} minutes and can be used once. If you did not request this, do not share the code and contact {{support_or_security_email}} if needed.

{{company_name}}

Data and security

Generate the code server-side with an unpredictable source. Store a hash or protected representation where possible, enforce expiry and attempt limits, and invalidate it after success. Do not log the code in plaintext or include it in a URL.

If the recipient requests another code, use an explicit resend policy. Tell the UI whether the newest code replaces older codes; avoid making users guess which message is current.

Delivery and accessibility

The code must remain visible when images are blocked. Use a real text element with enough contrast and a logical reading order. Include a plain-text alternative. Keep the message free of promotional content that could delay the security action.

QA checklist

  • Signup, login, address-change, and sensitive-action copy are distinct.
  • A code cannot be reused for another purpose.
  • Expired and invalid codes fail without account enumeration.
  • Rate limits prevent repeated delivery abuse.
  • The code is never placed in the subject line or URL.
  • The email renders legibly on mobile and in dark mode.

For passwordless links, see the magic link template; for broader risk events, see the security alert template.

Choose code length and presentation

Use the product’s security policy to choose code length and attempt limits. A six-digit code is easy to enter but should have a short lifetime and strict retry controls. Never rely on the email copy to enforce security; the server must reject expired, reused, or purpose-mismatched codes.

For high-risk actions, show the action name in the product UI and email. “Confirm changing your email address” is safer than an unexplained “verification code,” because the user can recognize an unexpected request.

Operational metrics

Track delivery-to-success time, resend rate, expiration rate, failed attempts, and support recovery. A high resend rate can indicate delivery delay, unclear copy, or an overly short lifetime; investigate before simply extending the expiry.

Keep the purpose visible

The same code service may support several workflows, but the email should name the action the code authorizes. Use a different event type and audit record for each purpose:

FlowSubject or introExit
New accountConfirm your email addressAddress verified or code expired
Sign-inVerify your sign-inAuthentication attempt completed
Email changeConfirm your new addressNew address activated
Sensitive actionConfirm the requested actionAction completed or canceled

Do not let a code issued for one flow satisfy another endpoint. Bind it to the account, purpose, attempt, and—where the product requires it—the initiating session.

Resend behavior is part of the UX

Tell the interface whether a resend invalidates older codes, whether several active codes can coexist, and how long the user must wait before requesting another. The email itself should not imply that the newest message is valid unless that is true. Rate-limit by account, device, and network signals without revealing whether an address exists.

Use an authenticated support or recovery path for a user who cannot receive mail. Never ask them to reply with the code. For high-risk actions, require the user to restart the action rather than allowing support to override a failed verification by email.

Test long product names, localized expiry text, right-to-left layouts, delayed delivery, repeated resends, and a code copied with spaces or line breaks. Measure successful verification, expiry, resend, failed-attempt, and support rates by purpose.