We are currently implementing Auth0 for authentication and authorization in our .NET + React-based multi-tenant SaaS application. We are using passwordless authentication with email magic links and would like to better understand the customization capabilities around this flow. We aim to enhance the passwordless magic link email with:
-
User-specific data (e.g., name, metadata)
-
Tenant-specific branding (e.g., logo, tenant name)
-
Custom-designed email templates aligned with our SaaS platform
We have a few specific questions:
-
Customization of Passwordless Magic Link Email
Could you please clarify the extent to which the default passwordless (magic link) email template can be customized?
-
Are we limited to predefined variables such as {{ link }} and {{ code }}?
-
Is there any way to include additional dynamic data (e.g., user metadata, tenant-specific details)?
-
It would be helpful if you could share any official documentation outlining supported template variables and customization options.
-
Custom Email Sending via Backend
We are exploring whether it is possible to send the passwordless magic link email from our own backend (e.g., using SendGrid or another provider) to achieve full control over branding and content.
-
Is there a supported approach for this using Auth0 APIs?
-
Can the magic link be generated or retrieved programmatically (e.g., via /passwordless/start or any other endpoint)?
-
If not directly supported, are there recommended patterns or best practices for implementing a custom-branded passwordless experience while still leveraging Auth0?
-
Template Variables / Liquid Support
-
Does Auth0 support Liquid templating or any equivalent templating engine for passwordless emails?
-
What variables are officially supported in passwordless email templates?
-
Are there any extensibility points (Actions, Hooks, etc.) that can inject additional data into the email template?
Hi @shahzadali-elorn
Welcome to the Auth0 Community!
- You can modify the Email Templates to completely overwrite the default HTML using Liquid syntax . You can check out the supported list in our documentation.
- That means you will not be limited to just
{{ link }} and {{ code }} . You also have access to standard context variables like {{ application.name }} , {{ tenant.name }} , and {{ friendly_name }} .
- If the user already exists in your Auth0 database, you can access their metadata in the template using
{{ user.user_metadata.custom_field }} or {{ user.app_metadata.custom_field }} .
- If the user is signing in for the very first time (a sign-up), their user profile does not technically exist in Auth0 until after they click the magic link and authenticate. Therefore,
user_metadata will be empty during the sign-up email dispatch .
- If you are using Auth0’s “Organizations” feature and pass the Organization ID in the login request, you can dynamically inject:
{{ organization.name }}
{{ organization.branding.logo_url }}
{{ organization.branding.colors.primary }}
- No. When you call the Authentication API (
/passwordless/start ), Auth0 generates the token and immediately dispatches the email via its internal engine . Auth0 intentionally does not return the magic link or OTP code in the API response. This is a strict security mechanism to prevent malicious actors from requesting a link for an arbitrary email address and intercepting the payload in the API response.
- Auth0 is designed to handle the dispatch itself. The supported pattern is to configure your own Custom Email Provider directly within the Auth0 Dashboard via Branding → Email Provider.
- The recommended pattern would be to configure Auth0 to use your SendGrid API key, you write your custom, SaaS-branded HTML in the Auth0 Email Templates dashboard using Liquid, and when
/passwordless/start is called, Auth0 securely renders the HTML and routes it through your SendGrid account for delivery.
- As mentioned, Liquid is fully supported, however, there are some rigid boundaries regarding extensibility:
- Currently, there is no Action trigger (like a “Pre-Email Send” Action) that intercepts the passwordless email dispatch . Auth0 Actions like
Pre User Registration and Post Login only execute after the user clicks the magic link and arrives back at Auth0. You cannot use Actions to inject arbitrary data into the email template at runtime.
- The
/passwordless/start endpoint does not support passing arbitrary runtime variables (like a custom businessName or promoCode ) that can be plucked out of the Liquid template . The template relies strictly on the predefined Auth0 state (the App, the User, and the Organization).
Hope this helps! If you have any other questions, let me know!
Kind Regards,
Nik
Hello Nik,
Thank you for your assistance—your response was very helpful and clarified several points for me.
Based on your explanation, it appears that there is currently no supported way to use custom Liquid variables such as user.user_metadata.*, tenant.*, or user.app_metadata.* within the passwordless email templates.
I would appreciate some further clarification regarding organization-based customization:
-
For applications using Organizations, is it possible to configure different email templates for each organization?
-
Alternatively, are we limited to a single template that dynamically adapts based on organization variables?
Additionally, could you please confirm whether there are any other supported variables beyond the following:
If there are any additional variables or documentation available, it would be very helpful for our implementation.
Thank you again for your support. I look forward to your response.
Regards,
Shahzad Ali
Hi again!
Regarding the organization customization, there aren’t multiple templates available for each of the organizations. As you have mentioned, you will be limited to customize the single template dynamically based on the passed in organization variables
Otherwise, regarding the organization variables, the full list of supported values is available in the documentation I linked above. To save you a click, they are:
- When a user logs in through an Organization, the following additional variables are available:
organization.id
organization.display_name
organization.name
organization.metadata
organization.branding.logo_url
organization.branding.colors.primary
organization.branding.colors.page_background
- Multiple custom domains variables:
custom_domain.domain, the custom domain name being used (e.g., login.example.com)
custom_domain.domain_metadata, the custom domain’s metadata fields (key-value pairs) that you can use to customize email content based on the domain
If you have any other questions, let me know!
Kind Regards,
Nik