Search…
Embedded Magic Links
Generate login links and deliver them to customers through your own channels.
Magic links are a great way to provide additional flexibility in your application's authentication system. With Passage, you have the ability to create magic links that can be delivered in any way you like - custom email templates, in-app chat messages, or anything else you can think of. Embedding magic links in your marketing emails, reminder texts, or other mediums can greatly reduce user friction and increase conversion rates.

Create a Magic Link

Magic links can be create via any of our backend SDKs or the management API. Authentication with an API Key is required to use this functionality. To create an API Key, visit the Passage Console.
To create a magic link, you must provide one of the following:
  • User ID
  • Email address
  • Phone number
If the user does not exist, they will be created before returning the magic link.
Node.js
Python
Go
Curl
Ruby
import Passage from "@passageidentity/passage-node";
​
let passageConfig = {
appID: "YOUR_APP_ID",
apiKey: "YOUR_API_KEY",
};
let passage = new Passage(passageConfig);
let magicLink = passage.createMagicLink({
email: "newEmai[email protected]",
redirect_url: "/custom-path/1234",
});
​
// use magicLink.url
console.log(magicLink.url)
from passageidentity import Passage
​
psg = Passage(PASSAGE_APP_ID, PASSAGE_API_KEY)
​
# create a magic link
magicLinkAttributes={
"email": "<[email protected]>",
"redirect_url": "/custom-path/1234"}
magicLink = psg.createMagicLink(magicLinkAttributes)
# use the 'url' parameter
print(magicLink.url)
import (
"github.com/passageidentity/passage-go"
"fmt"
)
​
func main() {
psg, err := passage.New(PASSAGE_APP_ID, &passage.Config{
APIKey: PASSAGE_API_KEY,
})
createMagicLinkBody := passage.CreateMagicLinkBody{
RedirectURL: "/custom-path/1234",
}
magicLink, err := psg.CreateMagicLink(createMagicLinkBody)
// use magicLink.URL
fmt.Println(magicLink.URL)
}
​
curl --request POST \
--url https://api.passage.id/v1/apps/<PASSAGE_APP_ID>/magic_link \
-H 'Authorization: Bearer <PASSAGE_API_KEY>' \
-H 'Content-Type: application/json' \
-d '{
"email": "[email protected]",
"redirect_url": "/custom-path/1234"
}'
require 'passageidentity'
​
PassageClient = Passage::Client.new(
app_id: PASSAGE_APP_ID,
api_key: PASSAGE_API_KEY
)
magic_link = PassageClient.create_magic_link(user_id: user_id)
magic_link = PassageClient.create_magic_link(
email: "[email protected]",
send: true,
channel: Passage::EMAIL_CHANNEL,
ttl: 120
)
There are a number of additional optional parameters you can provide to further customize the magic links. The full parameter list for the create magic link API endpoint is below.
Parameter
Description
user_id: string
[optional] Passage ID for user. Must provide one of: User ID, Email, Phone
email: string
[optional] Email for user. Must provide one of: User ID, Email, Phone
phone: string
[optional] Phone number for user. Must provide one of: User ID, Email, Phone
redirect_url: string
[optional] Specifies the redirect location for the user after successful authentication. Defaults to the app's redirect URL.
magic_link_path: string
[optional] Specifies the location of the Passage Element or Passage.js instance that will process the authentication. Defaults to the app's login URL.
send: boolean
[optional] Specifies if Passage will send the magic link or not. Defaults to false.
channel: string
[optional] Required if send is true. Must be "email" or "phone" to indicate the channel by which to send the magic link.
ttl: integer
[optional] The time to live in minutes for the magic link. Defaults to 60.
When a magic link is successfully created, the response will look like this. The magic_link.url value should be embedded into your custom delivery mechanism.
{
"magic_link": {
"id": "tiDy...fb9v",
"secret": "s0uv...Qz3Vm",
"activated": false,
"user_id": "M6SN...If9K",
"app_id": "3drf...lIj1",
"identifier": "[email protected]",
"type": "login",
"redirect_url": "/custom-path/1234",
"url": "http://localhost:8080/?psg_magic_link=ml.tiDyzZGmP7C4KbcAGolofb9v.M6SNdnnS6ZRjT2BctV67If9K.s0uvMvelBe6ZM4EfTgzQz3Vm",
"ttl": 60
}
}
Note: If you want to send a user a magic link via two different mediums (e.g. email and text), we recommend that you generate two different magic links since the link are one-time use only.

Example Use Cases

Not sure when to use embedded magic links? Here are a few use cases we've seen from customers. If you have another interesting application for embedded links tell us more about it in Discord or by emailing us at [email protected].

Sending Report Reminders from an Application

Acme has an application that uses Passage for biometric authentication. The application uses email addresses as the primary identifier for logging in. One feature of the application is weekly usage reports for their customers. Acme wants to email customers weekly to remind them to view their reports. They have noticed that their users will click the "View Report" button, but often not log in and they want to "View Report" button to include an embedded link.
Since users need to be logged in to view their report, Acme uses Passage Embedded Links to reduce user friction associated with logging in. The application can include an embedded link in the "View Report" button in the reminder emails. When users click the button, they skip the step where they enter their email and are instead immediately prompted for their biometric to log in and be redirected straight to their report.
Acme creates smart links with the following example code.
import Passage from "@passageidentity/passage-node";
​
let passageConfig = {
appID: "ACME_APP_ID",
apiKey: "ACME_API_KEY",
};
let passage = new Passage(passageConfig);
​
let magicLink = passage.createMagicLink({
redirect_url: "/reports/report-1234-5678",
});
​
// use magicLink.url
console.log(magicLink.url)

"Anonymous" Users Submitting Requests

Acme has an application that allows unauthenticated users to submit requests for a work quote. Users must provide an email address and phone number when submitting their request. Once the internal team has prepared the quote, they submit it to the application then notify the user via email and text.
Since these users do not have accounts on the application, Passage will create an account for them before sending the magic links. The application will create two magic links - one to send via email and one to send via text - since a magic link is one-time use only.
Acme create embedded links with following code.
import Passage from "@passageidentity/passage-node";
​
let passageConfig = {
appID: "ACME_APP_ID",
apiKey: "ACME_API_KEY",
};
let passage = new Passage(passageConfig);
​
//generate magic link for email address and create user
let magicLink = passage.createMagicLink({
phone: "+11234567890",
redirect_url: "/quotes/quoteid-1234-5678",
});
​
// generate another link to send via text, so they are both valid
let magicLink2 = passage.createMagicLink({
user_id: magicLink.user_id,
redirect_url: "/quotes/quoteid-1234-5678",
});
​
// send this one via email
console.log(magicLink.url)
// send this one via text
console.log(magicLink2.url)
Acme uses a Passage Element to handle the authentication when a user clicks the link to view their quote. If users want to see their quote in the future, they will be able to log in via the Passage Element using device biometrics or magic links since they have an account.

Security Considerations

The ability generate a magic link for any user is a powerful feature, but also comes with security risks if used incorrectly. The magic link URL should be carefully protected and only in rare circumstances be returned to the users of your application. The magic link URLs should be sent via secure means to your customers, since it provides a direct way to authenticate to your application.
Copy link
Outline
Create a Magic Link
Example Use Cases
Security Considerations