Configure Default Login Routes

Configure Default Login Routes

In certain cases (described below), Auth0 may need to redirect back to the application's Login Initiation endpoint, using OIDC third-party initiated login. To learn more, read Initiating Login from a Third Party at https://openid.net.

You can configure these URIs with the Dashboard in Application Settings or Tenant Advanced Settings or with the Management API.

At the application level:


curl --request PATCH \
  --url 'https://YOUR_DOMAIN/api/v2/clients/YOUR_CLIENT_ID' \
  --header 'authorization: Bearer API2_ACCESS_TOKEN' \
  --header 'cache-control: no-cache' \
  --header 'content-type: application/json' \
  --data '{"initiate_login_uri": "<login_url>"}'

Was this helpful?

/
var client = new RestClient("https://YOUR_DOMAIN/api/v2/clients/YOUR_CLIENT_ID");
var request = new RestRequest(Method.PATCH);
request.AddHeader("content-type", "application/json");
request.AddHeader("authorization", "Bearer API2_ACCESS_TOKEN");
request.AddHeader("cache-control", "no-cache");
request.AddParameter("application/json", "{\"initiate_login_uri\": \"<login_url>\"}", 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/clients/YOUR_CLIENT_ID"

	payload := strings.NewReader("{\"initiate_login_uri\": \"<login_url>\"}")

	req, _ := http.NewRequest("PATCH", url, payload)

	req.Header.Add("content-type", "application/json")
	req.Header.Add("authorization", "Bearer API2_ACCESS_TOKEN")
	req.Header.Add("cache-control", "no-cache")

	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.patch("https://YOUR_DOMAIN/api/v2/clients/YOUR_CLIENT_ID")
  .header("content-type", "application/json")
  .header("authorization", "Bearer API2_ACCESS_TOKEN")
  .header("cache-control", "no-cache")
  .body("{\"initiate_login_uri\": \"<login_url>\"}")
  .asString();

Was this helpful?

/
var axios = require("axios").default;

var options = {
  method: 'PATCH',
  url: 'https://YOUR_DOMAIN/api/v2/clients/YOUR_CLIENT_ID',
  headers: {
    'content-type': 'application/json',
    authorization: 'Bearer API2_ACCESS_TOKEN',
    'cache-control': 'no-cache'
  },
  data: {initiate_login_uri: '<login_url>'}
};

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 API2_ACCESS_TOKEN",
                           @"cache-control": @"no-cache" };
NSDictionary *parameters = @{ @"initiate_login_uri": @"<login_url>" };

NSData *postData = [NSJSONSerialization dataWithJSONObject:parameters options:0 error:nil];

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://YOUR_DOMAIN/api/v2/clients/YOUR_CLIENT_ID"]
                                                       cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                   timeoutInterval:10.0];
[request setHTTPMethod:@"PATCH"];
[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/clients/YOUR_CLIENT_ID",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "PATCH",
  CURLOPT_POSTFIELDS => "{\"initiate_login_uri\": \"<login_url>\"}",
  CURLOPT_HTTPHEADER => [
    "authorization: Bearer API2_ACCESS_TOKEN",
    "cache-control: no-cache",
    "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 = "{\"initiate_login_uri\": \"<login_url>\"}"

headers = {
    'content-type': "application/json",
    'authorization': "Bearer API2_ACCESS_TOKEN",
    'cache-control': "no-cache"
    }

conn.request("PATCH", "/YOUR_DOMAIN/api/v2/clients/YOUR_CLIENT_ID", 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/clients/YOUR_CLIENT_ID")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Patch.new(url)
request["content-type"] = 'application/json'
request["authorization"] = 'Bearer API2_ACCESS_TOKEN'
request["cache-control"] = 'no-cache'
request.body = "{\"initiate_login_uri\": \"<login_url>\"}"

response = http.request(request)
puts response.read_body

Was this helpful?

/
import Foundation

let headers = [
  "content-type": "application/json",
  "authorization": "Bearer API2_ACCESS_TOKEN",
  "cache-control": "no-cache"
]
let parameters = ["initiate_login_uri": "<login_url>"] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://YOUR_DOMAIN/api/v2/clients/YOUR_CLIENT_ID")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "PATCH"
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?

/

At the tenant level:


curl --request PATCH \
  --url 'https://YOUR_DOMAIN/api/v2/tenants/settings' \
  --header 'authorization: Bearer API2_ACCESS_TOKEN' \
  --header 'cache-control: no-cache' \
  --header 'content-type: application/json' \
  --data '{"default_redirection_uri": "<login_url>"}'

Was this helpful?

/
var client = new RestClient("https://YOUR_DOMAIN/api/v2/tenants/settings");
var request = new RestRequest(Method.PATCH);
request.AddHeader("content-type", "application/json");
request.AddHeader("authorization", "Bearer API2_ACCESS_TOKEN");
request.AddHeader("cache-control", "no-cache");
request.AddParameter("application/json", "{\"default_redirection_uri\": \"<login_url>\"}", 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/tenants/settings"

	payload := strings.NewReader("{\"default_redirection_uri\": \"<login_url>\"}")

	req, _ := http.NewRequest("PATCH", url, payload)

	req.Header.Add("content-type", "application/json")
	req.Header.Add("authorization", "Bearer API2_ACCESS_TOKEN")
	req.Header.Add("cache-control", "no-cache")

	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.patch("https://YOUR_DOMAIN/api/v2/tenants/settings")
  .header("content-type", "application/json")
  .header("authorization", "Bearer API2_ACCESS_TOKEN")
  .header("cache-control", "no-cache")
  .body("{\"default_redirection_uri\": \"<login_url>\"}")
  .asString();

Was this helpful?

/
var axios = require("axios").default;

var options = {
  method: 'PATCH',
  url: 'https://YOUR_DOMAIN/api/v2/tenants/settings',
  headers: {
    'content-type': 'application/json',
    authorization: 'Bearer API2_ACCESS_TOKEN',
    'cache-control': 'no-cache'
  },
  data: {default_redirection_uri: '<login_url>'}
};

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 API2_ACCESS_TOKEN",
                           @"cache-control": @"no-cache" };
NSDictionary *parameters = @{ @"default_redirection_uri": @"<login_url>" };

NSData *postData = [NSJSONSerialization dataWithJSONObject:parameters options:0 error:nil];

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://YOUR_DOMAIN/api/v2/tenants/settings"]
                                                       cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                   timeoutInterval:10.0];
[request setHTTPMethod:@"PATCH"];
[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/tenants/settings",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "PATCH",
  CURLOPT_POSTFIELDS => "{\"default_redirection_uri\": \"<login_url>\"}",
  CURLOPT_HTTPHEADER => [
    "authorization: Bearer API2_ACCESS_TOKEN",
    "cache-control: no-cache",
    "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 = "{\"default_redirection_uri\": \"<login_url>\"}"

headers = {
    'content-type': "application/json",
    'authorization': "Bearer API2_ACCESS_TOKEN",
    'cache-control': "no-cache"
    }

conn.request("PATCH", "/YOUR_DOMAIN/api/v2/tenants/settings", 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/tenants/settings")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Patch.new(url)
request["content-type"] = 'application/json'
request["authorization"] = 'Bearer API2_ACCESS_TOKEN'
request["cache-control"] = 'no-cache'
request.body = "{\"default_redirection_uri\": \"<login_url>\"}"

response = http.request(request)
puts response.read_body

Was this helpful?

/
import Foundation

let headers = [
  "content-type": "application/json",
  "authorization": "Bearer API2_ACCESS_TOKEN",
  "cache-control": "no-cache"
]
let parameters = ["default_redirection_uri": "<login_url>"] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://YOUR_DOMAIN/api/v2/tenants/settings")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "PATCH"
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?

/

The login_url should point to a route in the application that ends up redirecting to Auth0's /authorize endpoint, e.g. https://mycompany.org/login. Note that it requires https and it cannot point to localhost. login_url can include query parameters and a URI fragment.

As per the OIDC Third Party Initiated Login specification, the iss parameter containing Issuer Identifier will be added as a query string parameter to login_url before redirecting.

Redirect default login route scenarios

Users bookmark login page

When an application initiates the login process, it navigates to https://YOUR_DOMAIN/authorize with a set of required parameters. Auth0 then redirects end-users to a https://YOUR_DOMAIN/login page, with a URL that looks like:

https://YOUR_DOMAIN/login?state=g6Fo2SBjNTRyanlVa3ZqeHN4d1htTnh&...

The state parameter points to a record in an internal database where we track the status of the authorization transaction. Whenever the transaction completes, or after a set time passes, the record is deleted from the internal database.

Sometimes users bookmark the login page, and when they navigate to the bookmarked /login URL, the transaction record is no longer there and Auth0 cannot continue with the login flow. In that case, Auth0 will redirect to the default client URL if configured, or the tenant level URL if not. If no default login URL is set, Auth0 will render an error page.

Complete password reset flow

After completing the password reset flow and the default URI for the application or tenant is configured, users will see a button that will let them navigate back to the login page.

This behavior only happens when you enable the New Universal Login Experience. In Classic mode, you need to configure the redirect URL in the Verification Email template. To learn more, read Customize Email Templates.

For tenants using New Universal Login, the /post-password-change endpoint supports redirecting users back to a specific application. When client_id is specified and the application's login URI is set, users will see a button sending them back to the application after completing a password reset.


curl --request POST \
  --url 'https://YOUR_DOMAIN/api/v2/tickets/password-change' \
  --header 'authorization: Bearer MGMT_API_ACCESS_TOKEN' \
  --header 'content-type: application/json' \
  --data '{ "user_id": "A_USER_ID", "client_id": "A_CLIENT_ID" }'

Was this helpful?

/
var client = new RestClient("https://YOUR_DOMAIN/api/v2/tickets/password-change");
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\": \"A_USER_ID\", \"client_id\": \"A_CLIENT_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/tickets/password-change"

	payload := strings.NewReader("{ \"user_id\": \"A_USER_ID\", \"client_id\": \"A_CLIENT_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/tickets/password-change")
  .header("content-type", "application/json")
  .header("authorization", "Bearer MGMT_API_ACCESS_TOKEN")
  .body("{ \"user_id\": \"A_USER_ID\", \"client_id\": \"A_CLIENT_ID\" }")
  .asString();

Was this helpful?

/
var axios = require("axios").default;

var options = {
  method: 'POST',
  url: 'https://YOUR_DOMAIN/api/v2/tickets/password-change',
  headers: {
    'content-type': 'application/json',
    authorization: 'Bearer MGMT_API_ACCESS_TOKEN'
  },
  data: {user_id: 'A_USER_ID', client_id: 'A_CLIENT_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": @"A_USER_ID",
                              @"client_id": @"A_CLIENT_ID" };

NSData *postData = [NSJSONSerialization dataWithJSONObject:parameters options:0 error:nil];

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://YOUR_DOMAIN/api/v2/tickets/password-change"]
                                                       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/tickets/password-change",
  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\": \"A_USER_ID\", \"client_id\": \"A_CLIENT_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\": \"A_USER_ID\", \"client_id\": \"A_CLIENT_ID\" }"

headers = {
    'content-type': "application/json",
    'authorization': "Bearer MGMT_API_ACCESS_TOKEN"
    }

conn.request("POST", "/YOUR_DOMAIN/api/v2/tickets/password-change", 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/tickets/password-change")

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\": \"A_USER_ID\", \"client_id\": \"A_CLIENT_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": "A_USER_ID",
  "client_id": "A_CLIENT_ID"
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://YOUR_DOMAIN/api/v2/tickets/password-change")! 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?

/

Complete email verification flow

As part of the signup process, users get an email to verify their email address. If they click on the link, they will land on a page that says that the email was verified, with a button to go back to the application. When clicked, users will be redirected to the login page, and if they already have a valid session, they'll end up being redirected to the application.

This behavior only happens when the New Universal Login Experience is enabled. In Classic mode, you need to configure the redirect URL in the Verification Email template.

Invite organization members

When users are invited to join an Organization, they receive an invitation link by email. If they select the link, they are redirected to the configured default login route with invitation-specific parameters appended.

For example, if you have an organization-enabled application with an Application Login URI set to https://myapp.com/login, then the link sent in the email invitation that an end-user receives will be: https://myapp.com/login?invitation={invitation_ticket_id}&organization={organization_id}&organization_name={organization_name}.

Thus, the route in your application must accept invitation and organization parameters through the query string. To start the invitation acceptance transaction, it should forward both parameters along with the end-user to your Auth0 /authorize endpoint.

Learn more