Email templates
Logto provides different templates for customizing email content, which are categorized based on their use cases.
It is strongly recommended that you use different templates in different scenarios. Otherwise, users may receive email content that does not match the current operation, causing confusion. If there are missing templates that are not configured, it may cause flow errors that rely on that template and affect the normal development of business.
Email template types
usageType | Scenario | Variables |
---|---|---|
SignIn | Users sign in using their email and verify by entering verification code instead of entering a password. | code: string application: ApplicationInfo organization?: OrganizationInfo |
Register | Users create an account using their email and verify it by entering a verification code sent by Logto to their email. | code: string application: ApplicationInfo organization?: OrganizationInfo |
ForgotPassword | If users forget their password during login, they can choose to verify their identity using the email they've already verified with Logto. | code: string application: ApplicationInfo organization?: OrganizationInfo |
Generic | This template can be used as a general backup option for various scenarios, including testing connector configurations and so on. | code: string |
OrganizationInvitation | Use this template to send users an invitation link to join the organization. | link: string organization: OrganizationInfo inviter?: UserInfo |
UserPermissionValidation | During app usage, there may be some high-risk operations or operations with a relatively high risk level that require additional user verification, such as bank transfers, deleting resources in use, and canceling memberships. The UserPermissionValidation template can be used to define the content of the email verification code users receive in these situations. | code: string user: UserInfo application?: ApplicationInfo |
BindNewIdentifier | When a user modifies their profile, they may bind an email address to their current account. In this case, the BindNewIdentifier template can be used to customize the content of the verification email. | code: string user: UserInfo application?: ApplicationInfo |
Email template variables
Code
The verification code that users need to enter to complete the verification process. Available in SignIn
, Register
, ForgotPassword
, Generic
, UserPermissionValidation
, and BindNewIdentifier
templates.
- Verification codes expire in 10 minutes. We currently do not support the customization of verification code expiry time.
- A
{{code}}
placeholder needs to be reserved in the template. When sending a verification code, a randomly generated code will replace this placeholder before we send email to users.
ApplicationInfo
The public information of the client application that users are interacting with. Available in SignIn
, Register
, ForgotPassword
, UserPermissionValidation
, and BindNewIdentifier
templates.
type ApplicationInfo = {
id: string;
name: string;
displayName?: string;
branding?: {
logoUrl?: string;
darkLogoUrl?: string;
favicon?: string;
darkFavicon?: string;
};
};
- All nested application info fields can be accessed in templates through dot notation. For example,
{{application.name}}
will be replaced with the actual application name from your configuration. - If the root
application
variable is not provided, the handlebars placeholder will be ignored and not replaced. - If the provided
application
object does not contain the required fields or the value is undefined, the handlebars placeholder will be replaced with an empty string. E.g.{{application.foo.bar}}
will be replaced with ``.
OrganizationInfo
The public information of the organization that users are interacting with.
type OrganizationInfo = {
id: string;
name: string;
branding?: {
logoUrl?: string;
darkLogoUrl?: string;
favicon?: string;
darkFavicon?: string;
};
};
- For the
SignIn
,Register
, andForgotPassword
templates, theorganization
variable is optional. Only available when theorganization_id
parameter is present in the authorization request. See Organization-specific branding for more details. - For the
OrganizationInvitation
template, theorganization
variable is mandatory.
UserInfo
The public information of the user that the email is sent to. Available in UserPermissionValidation
, BindNewIdentifier
and OrganizationInvitation
templates.
type UserInfo = {
id: string;
name?: string;
username?: string;
primaryEmail?: string;
primaryPhone?: string;
avatar?: string;
profile?: Profile;
};
- Check profile for more details about the
Profile
type. - The
user
variable is mandatory for theUserPermissionValidation
andBindNewIdentifier
templates. - The
inviter
variable is optional for theOrganizationInvitation
template. Only available when theinviterId
is provided in the organization invitation request.
Email template examples
You can use the provided email template code examples as a starting point for customizing your UI. To create a user interface similar to the following:

Since the email templates used in different scenarios of Logto are very similar, with the only difference being the description of the current scenario and operation.
We do not show the HTML code of all templates in detail here. Instead, we only take the sign-in scenario as an example. Other scenarios, such as sign-up and forgot password, are very similar to the following sample.
Users can refer to this template and adjust according to their actual situation.
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Verify your email to sign in</title>
<style>
.auth-service-by:hover .mini-logo {
display: none !important;
}
.auth-service-by:hover .mini-logo-color {
display: block !important;
}
body {
font-family:
'SF Pro Text',
-apple-system,
system-ui,
BlinkMacSystemFont,
'Segoe UI',
Roboto,
Arial,
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
font-smooth: always;
background-color: #fff;
color: #191c1d;
max-width: 640px;
padding: 32px 0;
font-size: 14px;
font-weight: 400;
line-height: 20px;
}
h1 {
font-size: 24px;
font-weight: 700;
line-height: 32px;
margin-top: 32px;
}
.verification-code {
margin: 20px 0;
background: #eff1f1;
border-radius: 12px;
padding: 36px;
font-size: 32px;
font-weight: 600;
line-height: 40px;
}
.footer {
text-align: center;
color: #a9acac;
margin-top: 48px;
}
</style>
</head>
<body>
<div style="max-width: 698px; border-radius: 16px; border: 1px solid #E0E3E3;">
<div style="padding: 0 24px;">
<center>
<img src="{{logoUrl}}" alt="Logo" width="auto" height="40" />
<h1>Verify your email to sign in</h1>
<p>
We have received a sign in attempt with the following code. Please enter it in the page
you opened to complete the sign in process.
</p>
<div class="verification-code">000000</div>
<p style="color: #747778;">
If you did not attempt to sign in but received this email, please ignore it. The code
will remain active for 10 minutes.
</p>
<hr style="margin: 64px 0 24px; max-width: 420px;" />
<p style="color: #747778; margin: 16px 0 0;">{{companyInfo}}</p>
</center>
</div>
</div>
<div class="footer">
<hr />
<p style="font-size: 14px; line-height: 20px; margin: 20px 0;">
<a href="https://logto.io" style="color: #A9ACAC; text-decoration: underline;">Logto</a>:
The better identity infrastructure for developers.
</p>
<table style="margin: 0 auto; width: auto; border-spacing: 0;">
<tbody>
<tr>
<td style="vertical-align: middle;">
<a href="{{discordServerUrl}}" style="display: block; margin: 0 12px;">
<img src="{{discordLogoUrl}}" style="width: 20px;" />
</a>
</td>
<td style="vertical-align: middle;">
<a href="{{githubUrl}}" style="display: block; margin: 0 12px;">
<img src="{{githubLogoUrl}}" style="width: 20px;" />
</a>
</td>
<td style="vertical-align: middle;">
<a href="{{twitterUrl}}" style="display: block; margin: 0 12px;">
<img src="{{twitterLogoUrl}}" style="width: 20px;" />
</a>
</td>
<td style="vertical-align: middle;">
<a href="{{mailToUrl}}" style="display: block; margin: 0 12px;">
<img src="{{emailIconUrl}}" style="width: 20px;" />
</a>
</td>
</tr>
</tbody>
</table>
<p style="font-size: 12px; line-height: 16px;">
© Silverhand, Inc., 2810 North Church Street, Wilmington, DE 19802
</p>
<p style="color: #A9ACAC; font-size: 12px; line-height: 16px;">
Have questions or need help?
<a href="{{mailToUrl}}" style="color: #A9ACAC; text-decoration: underline;">Contact us</a>
</p>
</div>
</body>
</html>
You can then escape the HTML code above and add it to the connector "Template" field in configs as follows (assuming using SendGrid connector):
{
"subject": "<sign-in-template-subject>",
"content": "<table cellpadding=\"0\" cellspacing=\"0\" ...",
"usageType": "SignIn",
"type": "text/html"
}
Email template localization
Custom email templates for different languages
Logto supports creating custom email templates for different languages via Management API. You can create custom email templates for different languages and template types to provide a localized experience for your users.
type EmailTemplate = {
languageTag: string;
templateType: TemplateType;
details: {
subject: string;
content: string;
contentType?: 'text/html' | 'text/plain';
replyTo?: string;
sendFrom?: string;
};
};
Field | Description |
---|---|
subject | The subject template of the email. |
content | The content template of the email. |
contentType | Some email providers may render email templates differently based on the content type. (e.g. Sendgrid, Mailgun). Use this field to specify the content type of the email template. |
replyTo | The email address that will receive replies to the email. Check with your email provider to see if this field is supported. |
sendFrom | The name alias of the email sender. Check with your email provider to see if this field is supported. |
Once the email templates are created, Logto will automatically select the appropriate email template based on the user's language preference using the following priority order:
- For client-side Experience APIs and User Account APIs, language preference is determined by the
Accept-Language
header in the request. For Management APIs (such as Organization Invitation), you can specify the language preference by including alocale
parameter in themessagePayload
field of the request body. - When a language preference is detected, Logto looks for a matching custom email template using the
languageTag
andtemplateType
fields. If a template exists for the specified language and template type, Logto will use that template to render the email. - If no language preference is detected, or if no custom template exists for the detected language and template type, Logto will use the tenant's default language configured in the Sign-in Experience. Check Localized languages for configuration details.
- If no matching template is found, Logto will use the default email template defined in the connector configuration.
Supported email connectors:
Provider-side email template localization
For developers who use the email connectors that have email template managed by the provider:
The user preferred language will be passed to the provider using the locale
parameter in the template payload. You can create multiple templates for different languages in the provider's console and use the locale
parameter to specify the language preference.
FAQs
How to use third-party email template services if templates are not configured in Logto?
You can add a new endpoint to your own web service to send emails, then use the Logto HTTP email connector to call the endpoint you maintain.
This allows you to handle email template logic on your own server.
Is there a way to use Logto email for sending our users a customized "Welcome email"?
We offer Webhook functionality. You can implement your own API endpoint to receive the User.Created
event sent by the Logto Webhook, and add logic to send a customized welcome email within the webhook handler.
The Logto email connector only provides email notifications for events related to the authentication flow. Welcome emails are a business requirement and are not natively supported by the email connector, but this functionality can be achieved through Webhooks.
Related resources
Maximize verification email delivery to guarantee user access