Auth0's built-in email sender is only for testing, so every production tenant needs its own provider. To send through OwnMailServer, open Branding, then Email Provider, turn on Use my own email provider, choose SMTP, and enter smtp.ownmailserver.com, port 587, any username and an API key as the password, with a From address on your verified domain. Then click Send Test Email. It takes about ten minutes.
| Approach | Good for | Code |
|---|---|---|
| SMTP | Most tenants: Auth0's templates, sent from your domain | None |
| Custom Provider Action + our API | Your own logic per message type, retries, logging | One Action |
Why Auth0 needs its own email provider
Auth0 sends email for verification, password resets, verification codes, MFA codes, welcome messages, blocked-account notices and organization invitations. Out of the box it uses a built-in sender that, as of October 2026, Auth0 documents like this:
- All emails come from
no-reply@auth0user.net. You can't change the From address. - It allows 10 emails a minute, of every type together.
- You can't use custom email templates.
Auth0 says to use it for testing only. With your own provider, sign-in emails come from your domain, signed with your DKIM key, and every bounce and complaint shows up in your dashboard.
What you need before you start
- An approved OwnMailServer account with a verified sending domain. The From address must be on that domain, or we refuse the email with
550. The API docs list the DNS records, and the DKIM guide explains them. - An API key, created in your dashboard under API keys & SMTP. Choose Sending only (the default), limited to your sending domain, so the key Auth0 stores can't do anything but send. Make one just for Auth0, so you can revoke it without touching your other apps.
- Ideally a separate subdomain for auth email, such as
no-reply@auth.acme.com. Mailbox providers judge each domain's reputation, so a newsletter that draws complaints won't pull your password resets into spam.
Step 1: Enter the SMTP settings
In the Auth0 Dashboard, open Branding, then Email Provider. Turn on Use my own email provider, select SMTP, and fill in:
| Field | Value |
|---|---|
| From |
no-reply@auth.acme.com (on your verified domain) |
| Host | smtp.ownmailserver.com |
| Port | 587 |
| Username |
ownmailserver (we accept any value) |
| Password | Your API key |
Click Save. Auth0 lists four requirements for an SMTP server, and we meet each one:
| Auth0 requires | OwnMailServer |
|---|---|
| SMTP AUTH with the LOGIN method | LOGIN and PLAIN, after STARTTLS |
| TLS 1.2 or later | Yes, on port 587 |
| A certificate from a public certificate authority | Let's Encrypt, valid for smtp.ownmailserver.com
|
| Accept connections from Auth0's IP addresses | We accept connections from anywhere and check the API key |
If you change the host, port or username later, Auth0 asks for the password again, so keep the API key somewhere safe, such as your secrets manager.
To set the same thing from a script or CI, use Auth0's Management API with a token that has the update:email_provider scope. Use POST the first time and PATCH to change it:
curl -X PATCH "https://$AUTH0_DOMAIN/api/v2/emails/provider" \
-H "Authorization: Bearer $AUTH0_MGMT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "smtp",
"enabled": true,
"default_from_address": "no-reply@auth.acme.com",
"credentials": {
"smtp_host": "smtp.ownmailserver.com",
"smtp_port": 587,
"smtp_user": "ownmailserver",
"smtp_pass": "'"$OMS_API_KEY"'"
}
}'
Step 2: Send a test email
Click Send Test Email on the same page. Then search for the address in your OwnMailServer dashboard to see the delivery, or ask the Claude connector what happened to it. If nothing arrives after a few minutes, check Monitoring, then Logs in Auth0 for a failed send:
| You see | Cause | Fix |
|---|---|---|
535 / authentication failed |
Password isn't a valid API key | Paste the full key, or create a new one |
550 |
From domain isn't verified, or the account is pending | Finish domain setup in the dashboard |
450 |
Warm-up cap or 10 a second reached | Wait; Auth0 logs the failure |
421 too many failed logins |
5 failed logins from one IP address | Fix the password, wait 15 minutes |
Email still from auth0user.net
|
The provider toggle is off or not saved | Turn on Use my own email provider and save |
Step 3: Edit the templates
With your own provider set up, open Branding, then Email Templates to change each email: verification email (link and code), change password, welcome email, MFA enrollment, blocked account and others. Each template has its own From field, which overrides the default, so keep it on your verified domain too. Templates use Liquid: put a variable such as url, user.email or application.name inside double curly braces.
Keep auth emails plain: a short line, one button, the same link as text, and no tracking or marketing. That's what mailbox providers expect from a password reset, and it's what gets it to the inbox quickly.
Option B: A Custom Provider Action that calls our API
If you want your own logic, such as logging each send or handling message types differently, choose Custom Provider under Branding, then Email Provider. Auth0 then stops using SMTP and runs an Action on the custom-email-provider trigger for every email, passing the rendered subject, HTML and text. Your Action sends them through POST /emails.
Enter the From address, add your API key as a secret named OMS_API_KEY (the key icon in the editor), and use this code:
exports.onExecuteCustomEmailProvider = async (event, api) => {
const n = event.notification;
let res;
try {
res = await fetch("https://api.ownmailserver.com/emails", {
method: "POST",
headers: {
Authorization: `Bearer ${event.secrets.OMS_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
from: n.from,
to: n.to,
subject: n.subject,
html: n.html,
text: n.text,
tags: [{ name: "auth0", value: n.message_type }],
}),
});
} catch (err) {
api.notification.retry(`Network error: ${err.message}`);
return;
}
if (res.ok) return;
const body = (await res.text()).slice(0, 500);
// 429 (rate or daily cap) and 5xx are temporary: Auth0 retries up to 5 times.
if (res.status === 429 || res.status >= 500) api.notification.retry(`OwnMailServer ${res.status}: ${body}`);
else api.notification.drop(`OwnMailServer ${res.status}: ${body}`);
};
Save to deploy it, then click Send Test Email. Errors such as an unverified domain (4xx other than 429) won't fix themselves, so the Action drops them and Auth0 logs the reason instead of retrying. The tags value records Auth0's message type with each email, such as reset_email or verify_email, so you can tell them apart later.
An Action is a tenant-wide setting: only one Action can be bound to the custom-email-provider trigger. If you manage Auth0 with Terraform, the auth0_email_provider resource with name = "custom" does the same thing.
Keep auth email within your warm-up cap
A new OwnMailServer account starts at a few hundred recipients a day and rises about 25% after each clean day (how warm-up works). Your dashboard shows today's cap. Verification and reset emails rarely come close. If you're moving an existing tenant with many daily signups, keep the old provider meanwhile and switch Auth0 over once the cap covers a normal day, as described in our migration guide.
When this isn't the right fit
If your tenant only sends a handful of auth emails, any SMTP provider with a free tier will do, and Auth0's 10-a-minute test sender is the real problem, not cost. We're a good fit when you want auth and app email from one provider on your own domain, with bounces, complaints and warm-up handled for you. The Supabase guide and Firebase guide cover the same setup for those platforms, and pay-as-you-go pricing is $0.20 per 1,000 emails with a $10 monthly minimum.
FAQ
Why do my Auth0 emails come from no-reply@auth0user.net?
Your tenant still uses Auth0's built-in email provider. It always sends from no-reply@auth0user.net, allows 10 emails a minute and doesn't let you use custom templates. Auth0 says it is for testing only. Turn on Use my own email provider under Branding, Email Provider, set up SMTP or another provider, and your emails come from your own domain.
What SMTP port should I use for Auth0?
Use 587. Auth0 recommends it because it's the current standard port for sending and supports TLS, and it's the port we offer: Auth0 connects, upgrades the connection with STARTTLS and logs in with the LOGIN method. We don't offer 465, and port 25 isn't for authenticated sending. If Auth0 reports a login failure, the password must be a full OwnMailServer API key.
Does Auth0 need my SMTP server to allow its IP addresses?
Auth0 requires your SMTP server to accept connections from Auth0's IP addresses, and lists them under Branding, Email Provider. Our SMTP server accepts connections from anywhere and checks the API key instead, so you don't need to add anything. A firewall on your side only matters if you run your own mail server.
Can I send Auth0 emails through an API instead of SMTP?
Yes. Choose Custom Provider under Branding, Email Provider and write an Action for the custom-email-provider trigger. Auth0 passes it the rendered subject, HTML and text, and your code sends them with our POST /emails endpoint. The Action can ask Auth0 to retry up to 5 times when we answer with a temporary error.
How many Auth0 emails can I send on a new OwnMailServer account?
A new account starts with a daily cap of a few hundred recipients, and the cap rises about 25% after each clean day. Auth email such as verification and password resets is usually low volume, so most apps stay well under it. If you also send a large welcome email to every new signup, keep that in mind while the cap grows.
Originally published at ownmailserver.com.
Top comments (0)