Send a magic link
curl --request POST \
--url https://api.portalhq.io/api/v3/auth/magic-links \
--header 'Content-Type: application/json' \
--header 'x-portal-auth-environment-id: <api-key>' \
--data '
{
"email": "user@example.com",
"redirectUrl": "https://example.com/callback",
"fromEmail": "hello@auth.example.com",
"templateId": "clx1template000000000000"
}
'import requests
url = "https://api.portalhq.io/api/v3/auth/magic-links"
payload = {
"email": "user@example.com",
"redirectUrl": "https://example.com/callback",
"fromEmail": "hello@auth.example.com",
"templateId": "clx1template000000000000"
}
headers = {
"x-portal-auth-environment-id": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'x-portal-auth-environment-id': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
email: 'user@example.com',
redirectUrl: 'https://example.com/callback',
fromEmail: 'hello@auth.example.com',
templateId: 'clx1template000000000000'
})
};
fetch('https://api.portalhq.io/api/v3/auth/magic-links', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.portalhq.io/api/v3/auth/magic-links",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'email' => 'user@example.com',
'redirectUrl' => 'https://example.com/callback',
'fromEmail' => 'hello@auth.example.com',
'templateId' => 'clx1template000000000000'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-portal-auth-environment-id: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.portalhq.io/api/v3/auth/magic-links"
payload := strings.NewReader("{\n \"email\": \"user@example.com\",\n \"redirectUrl\": \"https://example.com/callback\",\n \"fromEmail\": \"hello@auth.example.com\",\n \"templateId\": \"clx1template000000000000\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-portal-auth-environment-id", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.portalhq.io/api/v3/auth/magic-links")
.header("x-portal-auth-environment-id", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"email\": \"user@example.com\",\n \"redirectUrl\": \"https://example.com/callback\",\n \"fromEmail\": \"hello@auth.example.com\",\n \"templateId\": \"clx1template000000000000\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.portalhq.io/api/v3/auth/magic-links")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-portal-auth-environment-id"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"email\": \"user@example.com\",\n \"redirectUrl\": \"https://example.com/callback\",\n \"fromEmail\": \"hello@auth.example.com\",\n \"templateId\": \"clx1template000000000000\"\n}"
response = http.request(request)
puts response.read_body{
"data": {
"sent": true
},
"metadata": null
}Magic Links
Send a magic link
Emails a sign-in link to the end user. Portal sends the email from a verified sending domain using one of your email templates.
Three of the fields must already be configured in the dashboard:
redirectUrlmust exactly match one of the environment’s Redirect URLs.fromEmailmust belong to a verified sending domain that is enabled for this environment.templateIdis the Portal template ID from Authentication > Templates.
isAccountAbstracted is optional and decides whether the client Portal
creates for this user uses Account Abstraction.
POST
/
magic-links
Send a magic link
curl --request POST \
--url https://api.portalhq.io/api/v3/auth/magic-links \
--header 'Content-Type: application/json' \
--header 'x-portal-auth-environment-id: <api-key>' \
--data '
{
"email": "user@example.com",
"redirectUrl": "https://example.com/callback",
"fromEmail": "hello@auth.example.com",
"templateId": "clx1template000000000000"
}
'import requests
url = "https://api.portalhq.io/api/v3/auth/magic-links"
payload = {
"email": "user@example.com",
"redirectUrl": "https://example.com/callback",
"fromEmail": "hello@auth.example.com",
"templateId": "clx1template000000000000"
}
headers = {
"x-portal-auth-environment-id": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'x-portal-auth-environment-id': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
email: 'user@example.com',
redirectUrl: 'https://example.com/callback',
fromEmail: 'hello@auth.example.com',
templateId: 'clx1template000000000000'
})
};
fetch('https://api.portalhq.io/api/v3/auth/magic-links', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.portalhq.io/api/v3/auth/magic-links",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'email' => 'user@example.com',
'redirectUrl' => 'https://example.com/callback',
'fromEmail' => 'hello@auth.example.com',
'templateId' => 'clx1template000000000000'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-portal-auth-environment-id: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.portalhq.io/api/v3/auth/magic-links"
payload := strings.NewReader("{\n \"email\": \"user@example.com\",\n \"redirectUrl\": \"https://example.com/callback\",\n \"fromEmail\": \"hello@auth.example.com\",\n \"templateId\": \"clx1template000000000000\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-portal-auth-environment-id", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.portalhq.io/api/v3/auth/magic-links")
.header("x-portal-auth-environment-id", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"email\": \"user@example.com\",\n \"redirectUrl\": \"https://example.com/callback\",\n \"fromEmail\": \"hello@auth.example.com\",\n \"templateId\": \"clx1template000000000000\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.portalhq.io/api/v3/auth/magic-links")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-portal-auth-environment-id"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"email\": \"user@example.com\",\n \"redirectUrl\": \"https://example.com/callback\",\n \"fromEmail\": \"hello@auth.example.com\",\n \"templateId\": \"clx1template000000000000\"\n}"
response = http.request(request)
puts response.read_body{
"data": {
"sent": true
},
"metadata": null
}Authorizations
Body
application/json
Whether the client created for this end user uses ERC-4337 Account
Abstraction. Omit it to inherit your organization's default. Sending
true requires Account Abstraction to be enabled for your
organization and configured for this environment, and is rejected
with 400 otherwise.
The flag only applies when the client is created, on the user's first sign-in. A returning user keeps the client they already have.
Was this page helpful?