One-time passcode email template
Confirm a sensitive action with a one-time passcode, the action named and the request spelled out. Sign-in with a magic link uses Login code or Linear login code.
Customize copy and variables in the AI email editor. Browse all email templates or the Transactional collection. See the Email verification template. See the Password reset email template. See the Linear login code.
See the email before you edit.
Subject
Confirm it's you to reveal a production secret
Preheader
Your code is 481726. Works once, for the next 5 minutes.
Make it fit the send.
- Name the action and the thing acted on as input: the action completes the sentence “Confirm it's you to”, the resource is the path, project or team the code applies to, and one sentence says exactly what happens when the code is entered.
- The code is the hero and there is no button, because the OTP only works in the session that asked. A muted link cancels the request, so someone who did not ask for it can stop it without entering the code.
- State the expiry in the expiry notice and pass the request details as a list of label and value. The template never reads the clock. Your application generates the code, binds it to the account, action and session, limits attempts and enforces one use.
- For a sign-in that pairs a magic link with a fallback code, open Login code or Linear login code instead. It is written for Plinth, a fictional platform for deploying web apps: replace its mark and the shield pictogram, and edit the passcode email in the AI email editor.
Data this template expects.
- {{account}}
- The address the code was sent to, for example maya@halyard.example. Shown in the footer so the reader knows which account asked.
- {{action}}
- What the code confirms, phrased to follow “Confirm it's you to”, for example “reveal a production secret”.
- {{actionDetail}}
- One sentence naming exactly what happens when the code is entered. Keep it specific and true to what your application does.
- {{cancelUrl}}
- A link that cancels the pending request without the code. It must work outside the session that asked.
- {{code}}
- The one-time code as a string, for example “481726”. Preserve leading zeroes and never reuse the preview value for real requests.
- {{expiryNotice}}
- For example: “Works once, for the next 5 minutes.” Derive this copy from the actual server-side expiry policy.
- {{requestDetails}}
- A list of { label, value } objects, for example { "label": "Device", "value": "Firefox 144 on Ubuntu 24.04" }. Use recorded context, not guessed location or device identity.
- {{resource}}
- The thing acted on, as your product names it: a path, a project or a team, for example halyard-labs/storefront-web/production/DATABASE_URL.
- {{securityUrl}}
- Your sessions or account-security page, for the reader who did not ask for the code.
Choose the Code Variant
Production secret or deletion: set the action and resource to what the reader is about to do and the detail to its exact consequence. The reader should know what the code unlocks before typing it.
Ownership transfer or CLI sign-in: the long-content fixture shows a team ownership transfer with a longer consequence. The same fields carry any step-up check, so the template does not change.
Sign-in or verification code: use Login code or Email verification instead. A step-up code must not double as a sign-in, address-verification or password-reset credential.
Handle Resends and Wrong Codes
Your application generates the code, binds it to the intended account and purpose, limits verification attempts, and enforces expiry and one-time use. The template displays the value supplied to it. Its five-minute preview is example data, not an enforced lifetime.
Decide whether resending keeps the active code or invalidates it and issues another. Explain the policy on the code-entry screen, and test delayed delivery so an older email cannot mislead someone about which code is valid.
For an unsolicited code, the email tells the recipient not to share it and to sign out other sessions. Keep the cancel and security links usable outside the signed-in session. Test leading zeroes, the wrong code, an expired code, reuse after success, and the attempt limit before launch.
Connect an OTP Callback
The Better Auth integration includes an emailOTP callback. Pass the callback’s code to the code input and preserve the operation type when selecting your email copy. Its built-in emails are separate from this gallery starter; a template override is the bridge to your customized design.
Keep API keys and code verification on the server. Render and send the email from your callback or server action, then let your application decide whether the submitted code completes the action.