Customize Email Handling
Our default email flow can address the requirements of most applications. Sometimes, however, you may require more flexibility, such as when implementing:
localization
custom Redirect To URLs based on user or tenant
different email templates per application or tenant
The Auth0 Management API provides endpoints to help you manage your email flow to control when and how emails are sent. If necessary, you can also implement your own Custom Email endpoints and use the Auth0 Management API endpoints to help manage the rest of the flow.
Verification emails
A verification email should be sent to every user for which the email_verified
property is false
. Typically, these are users in database connections or users authenticating with social providers that do not validate email addresses upon new user registration.
You can send verification emails in more than one way:
The Send an email address verification email endpoint sends the user an email prompting them to verify their email address.
curl --request POST \
--url 'https://YOUR_DOMAIN/api/v2/jobs/verification-email' \
--header 'authorization: Bearer MGMT_API_ACCESS_TOKEN' \
--header 'content-type: application/json' \
--data '{ "user_id": "USER_ID_TO_SEND_VERIFY_EMAIL_TO", "client_id": "YOUR_APPLICATION_CLIENT_ID","identity": {"user_id": "5457edea1b8f22891a000004","provider": "google-oauth2"}, "organization_id": "YOUR_ORGANIZATION_ID" }'
Was this helpful?
var client = new RestClient("https://YOUR_DOMAIN/api/v2/jobs/verification-email");
var request = new RestRequest(Method.POST);
request.AddHeader("content-type", "application/json");
request.AddHeader("authorization", "Bearer MGMT_API_ACCESS_TOKEN");
request.AddParameter("application/json", "{ \"user_id\": \"USER_ID_TO_SEND_VERIFY_EMAIL_TO\", \"client_id\": \"YOUR_APPLICATION_CLIENT_ID\",\"identity\": {\"user_id\": \"5457edea1b8f22891a000004\",\"provider\": \"google-oauth2\"}, \"organization_id\": \"YOUR_ORGANIZATION_ID\" }", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Was this helpful?
package main
import (
"fmt"
"strings"
"net/http"
"io/ioutil"
)
func main() {
url := "https://YOUR_DOMAIN/api/v2/jobs/verification-email"
payload := strings.NewReader("{ \"user_id\": \"USER_ID_TO_SEND_VERIFY_EMAIL_TO\", \"client_id\": \"YOUR_APPLICATION_CLIENT_ID\",\"identity\": {\"user_id\": \"5457edea1b8f22891a000004\",\"provider\": \"google-oauth2\"}, \"organization_id\": \"YOUR_ORGANIZATION_ID\" }")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("content-type", "application/json")
req.Header.Add("authorization", "Bearer MGMT_API_ACCESS_TOKEN")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := ioutil.ReadAll(res.Body)
fmt.Println(res)
fmt.Println(string(body))
}
Was this helpful?
HttpResponse<String> response = Unirest.post("https://YOUR_DOMAIN/api/v2/jobs/verification-email")
.header("content-type", "application/json")
.header("authorization", "Bearer MGMT_API_ACCESS_TOKEN")
.body("{ \"user_id\": \"USER_ID_TO_SEND_VERIFY_EMAIL_TO\", \"client_id\": \"YOUR_APPLICATION_CLIENT_ID\",\"identity\": {\"user_id\": \"5457edea1b8f22891a000004\",\"provider\": \"google-oauth2\"}, \"organization_id\": \"YOUR_ORGANIZATION_ID\" }")
.asString();
Was this helpful?
var axios = require("axios").default;
var options = {
method: 'POST',
url: 'https://YOUR_DOMAIN/api/v2/jobs/verification-email',
headers: {
'content-type': 'application/json',
authorization: 'Bearer MGMT_API_ACCESS_TOKEN'
},
data: {
user_id: 'USER_ID_TO_SEND_VERIFY_EMAIL_TO',
client_id: 'YOUR_APPLICATION_CLIENT_ID',
identity: {user_id: '5457edea1b8f22891a000004', provider: 'google-oauth2'},
organization_id: 'YOUR_ORGANIZATION_ID'
}
};
axios.request(options).then(function (response) {
console.log(response.data);
}).catch(function (error) {
console.error(error);
});
Was this helpful?
#import <Foundation/Foundation.h>
NSDictionary *headers = @{ @"content-type": @"application/json",
@"authorization": @"Bearer MGMT_API_ACCESS_TOKEN" };
NSDictionary *parameters = @{ @"user_id": @"USER_ID_TO_SEND_VERIFY_EMAIL_TO",
@"client_id": @"YOUR_APPLICATION_CLIENT_ID",
@"identity": @{ @"user_id": @"5457edea1b8f22891a000004", @"provider": @"google-oauth2" },
@"organization_id": @"YOUR_ORGANIZATION_ID" };
NSData *postData = [NSJSONSerialization dataWithJSONObject:parameters options:0 error:nil];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://YOUR_DOMAIN/api/v2/jobs/verification-email"]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:10.0];
[request setHTTPMethod:@"POST"];
[request setAllHTTPHeaderFields:headers];
[request setHTTPBody:postData];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(@"%@", error);
} else {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
NSLog(@"%@", httpResponse);
}
}];
[dataTask resume];
Was this helpful?
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://YOUR_DOMAIN/api/v2/jobs/verification-email",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "{ \"user_id\": \"USER_ID_TO_SEND_VERIFY_EMAIL_TO\", \"client_id\": \"YOUR_APPLICATION_CLIENT_ID\",\"identity\": {\"user_id\": \"5457edea1b8f22891a000004\",\"provider\": \"google-oauth2\"}, \"organization_id\": \"YOUR_ORGANIZATION_ID\" }",
CURLOPT_HTTPHEADER => [
"authorization: Bearer MGMT_API_ACCESS_TOKEN",
"content-type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
Was this helpful?
import http.client
conn = http.client.HTTPSConnection("")
payload = "{ \"user_id\": \"USER_ID_TO_SEND_VERIFY_EMAIL_TO\", \"client_id\": \"YOUR_APPLICATION_CLIENT_ID\",\"identity\": {\"user_id\": \"5457edea1b8f22891a000004\",\"provider\": \"google-oauth2\"}, \"organization_id\": \"YOUR_ORGANIZATION_ID\" }"
headers = {
'content-type': "application/json",
'authorization': "Bearer MGMT_API_ACCESS_TOKEN"
}
conn.request("POST", "/YOUR_DOMAIN/api/v2/jobs/verification-email", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
Was this helpful?
require 'uri'
require 'net/http'
require 'openssl'
url = URI("https://YOUR_DOMAIN/api/v2/jobs/verification-email")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request["authorization"] = 'Bearer MGMT_API_ACCESS_TOKEN'
request.body = "{ \"user_id\": \"USER_ID_TO_SEND_VERIFY_EMAIL_TO\", \"client_id\": \"YOUR_APPLICATION_CLIENT_ID\",\"identity\": {\"user_id\": \"5457edea1b8f22891a000004\",\"provider\": \"google-oauth2\"}, \"organization_id\": \"YOUR_ORGANIZATION_ID\" }"
response = http.request(request)
puts response.read_body
Was this helpful?
import Foundation
let headers = [
"content-type": "application/json",
"authorization": "Bearer MGMT_API_ACCESS_TOKEN"
]
let parameters = [
"user_id": "USER_ID_TO_SEND_VERIFY_EMAIL_TO",
"client_id": "YOUR_APPLICATION_CLIENT_ID",
"identity": [
"user_id": "5457edea1b8f22891a000004",
"provider": "google-oauth2"
],
"organization_id": "YOUR_ORGANIZATION_ID"
] as [String : Any]
let postData = JSONSerialization.data(withJSONObject: parameters, options: [])
let request = NSMutableURLRequest(url: NSURL(string: "https://YOUR_DOMAIN/api/v2/jobs/verification-email")! as URL,
cachePolicy: .useProtocolCachePolicy,
timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data
let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
if (error != nil) {
print(error)
} else {
let httpResponse = response as? HTTPURLResponse
print(httpResponse)
}
})
dataTask.resume()
Was this helpful?
Using Auth0 Rules, you can call your API when a user logs in for the first time with an email address that has not been verified. After calling your API, add a flag to the user's profile metadata that indicates that the verification email has been sent:
function (user, context, callback) {
const request = require('request');
user.user_metadata = user.user_metadata || {};
if (user.email_verified || user.user_metadata.verification_email_sent) {
return callback(null, user, context);
}
request.post({
url: 'https://yourapi.yourcompany.com/mail/verification',
json: {
user: user,
context: context,
secretToken: configuration.MY_SECRET_TOKEN,
},
timeout: 5000
}, function(err, response, body){
if (err)
return callback(new Error(err));
// Email sent flag persisted in the user's profile.
user.user_metadata.verification_email_sent = true;
auth0.users.updateUserMetadata(user.user_id, user.user_metadata)
.then(function() {
callback(null, user, context);
})
.catch(function(err) {
callback(err);
});
return callback(null, user, context);
});
}
Was this helpful?
Require verified email for login
You can require users to verify their email before logging in with a rule:
function (user, context, callback) {
if (!user.email_verified) {
return callback(new UnauthorizedError('Please verify your email before logging in.'));
} else {
return callback(null, user, context);
}
}
Was this helpful?
Custom redirects
A custom redirect is useful when you want to direct users to certain URLs based on user attributes or on the tenant. The Auth0 Management API provides a Create Email Verification Ticket endpoint that generates the verification link for each user. This endpoint allows you to specify the result_url
to which users will be redirected after they have validated their email address by clicking the link in the verification email.
We recommend AllowList the URL in the Auth0 Dashboard. For details, see Add Addresses to AllowList.
Welcome emails
A welcome email is sent to users once they have verified their email address.
Send welcome email using your own API
Using a rule, you can call your API to send a welcome email only if the user's email address has been verified and the email has not been sent previously.
function (user, context, callback) {
const request = require('request');
if (!user.email_verified || user.welcome_email_sent) {
return callback(null, user, context);
}
request.post({
url: 'https://yourapi.yourcompany.com/mail/welcome',
json: {
user: user,
context: context,
secretToken: configuration.MY_SECRET_TOKEN,
},
timeout: 5000
}, function(err, response, body){
if (err)
return callback(new Error(err));
// Email sent flag persisted in the user's profile.
user.app_metadata.welcome_email_sent = true;
return callback(null, user, context);
});
}
Was this helpful?
Change password confirmation emails
To handle password change requests, you will need to host a form to capture the user's new password, and post it to the Create Password Change Ticket endpoint in the new_password
parameter. Calling this endpoint will generate a Change Password Confirmation link. With it, you can send the user an email containing the link. When the user clicks the link, they can update their password.
Alternatively, if you invoke the endpoint without specifying the new_password
parameter, the link in the email will redirect the user to a page prompting them to set a new password.
