Generate Passwordless Auth Code with AI in Minutes
Input this prompt in your IDE to analyze your existing code base and generate SCIM implementation code accordingly.
Compatible with Cursor, Windsurf, VS Code, and any AI-powered IDE
This guide explains how you can implement passwordless authentication using Scalekit’s APIs to send either verification codes or magic links to your user’s email address and verify their identity.
Before you begin, ensure you have:
Access to your Scalekit Account and the API credentials. If you don’t have a Scalekit account yet, you can signup here.
Installed Scalekit SDK into your project
npm install @scalekit-sdk/node
import { Scalekit } from '@scalekit-sdk/node';
const scalekit = new Scalekit( '<SCALEKIT_ENVIRONMENT_URL>', '<SCALEKIT_CLIENT_ID>', '<SCALEKIT_CLIENT_SECRET>',);
Generate Passwordless Auth Code with AI in Minutes
Input this prompt in your IDE to analyze your existing code base and generate SCIM implementation code accordingly.
Compatible with Cursor, Windsurf, VS Code, and any AI-powered IDE
Before implementing the code, ensure passwordless authentication is properly configured in your Scalekit dashboard:
The first step in the passwordless flow is to send a verification email to the user’s email. This verification email contains either a one-time passcode or a magic link or both based on your selection in the Scalekit dashboard (earlier step).
Follow these steps to implement the verification email flow:
POST /api/v1/passwordless/email/send
Example implementation
# Send a passwordless verification code to user's emailcurl -L '<SCALEKIT_ENVIRONMENT_URL>/api/v1/passwordless/email/send' \-H 'Content-Type: application/json' \-H 'Authorization: Bearer eyJh..' \--data-raw '{ "email": "john.doe@example.com", "expires_in": 300, "state": "jAy-state1-gM4fdZ...2nqm6Q", "template": "SIGNIN",
"magiclink_auth_uri": "https://yourapp.com/passwordless/verify", "template_variables": { "custom_variable_key": "custom_variable_value" }}'
# Response
# {
# "auth_request_id": "jAy-state1-gM4fdZ...2nqm6Q"
# "expires_at": "1748696575"
# "expires_in": 100
# "passwordless_type": "OTP" | "LINK" | "LINK_OTP"
# }
Parameter | Required | Description |
---|---|---|
email | Yes | Recipient’s email address string |
expires_in | No | Code expiration time in seconds (default: 300) number |
state | No | OIDC state parameter for request validation string |
template | No | Email template to use (SIGNIN or SIGNUP ) string |
magiclink_auth_uri | No | Magic Link URI that will be sent to your user to complete the authentication flow. If the URL is of the format https://yourapp.com/passwordless/verify , the magic link sent to your user via email will be https://yourapp.com/passwordless/verify?link_token=<link_token> . Required if you selected Link or Link + OTP as the passwordless option.string |
template_variables | No | Pass variables to be used in the email template sent to the user. You may include up to 30 key-value pairs to reference in the email template. object |
Parameters | Description |
---|---|
auth_request_id | A unique identifier for the authentication request that can be used to verify the code string |
expires_at | Unix timestamp indicating when the verification code will expire string |
expires_in | The time in seconds after which the verification code will expire. Default is 100 seconds number |
passwordless_type | The type of passwordless authentication to use. Currently supports OTP , LINK and LINK_OTP string |
const options = { template: "SIGNIN", state: "jAy-state1-...2nqm6Q", expiresIn: 300, // Required if you selected Link or Link+OTP as passwordless option magiclinkAuthUri: "https://yourapp.com/passwordless/verify", templateVariables: { employeeID: "EMP523", teamName: "Alpha Team", },};
const sendResponse = await scalekit.passwordless .sendPasswordlessEmail( "<john.doe@example.com>", options);
// sendResponse = {// authRequestId: string,// expiresAt: number, // seconds since epoch// expiresIn: number, // seconds// passwordlessType: string // "OTP" | "LINK" | "LINK_OTP"// }
Parameter | Required | Description |
---|---|---|
email | Yes | The email address to send the passwordless link to string |
template | No | The template type (SIGNIN /SIGNUP ) string |
state | No | Optional state parameter to maintain state between request and callback string |
expiresIn | No | Optional expiration time in seconds (default: 300) number |
magiclinkAuthUri | No | Magic Link URI that will be sent to your user to complete the authentication flow. If the URL is of the format https://yourapp.com/passwordless/verify , the magic link sent to your user via email will be https://yourapp.com/passwordless/verify?link_token=<link_token> . Required if you selected Link or Link + OTP as the passwordless option.string |
template_variables | No | Pass variables to be used in the email template sent to the user. You may include up to 30 key-value pairs to reference in the email template. object |
Parameters | Description |
---|---|
authRequestId | Unique identifier for the passwordless authentication request string |
expiresAt | Expiration time in seconds since epoch number |
expiresIn | Expiration time in seconds number |
passwordlessType | Type of passwordless authentication (OTP , LINK or LINK_OTP ) string |
// Send a passwordless email (assumes you have an initialized `client` and `ctx`)templateType := scalekit.TemplateTypeSigninresp, err := scalekitClient.Passwordless().SendPasswordlessEmail( ctx, "john.doe@example.com", &scalekit.SendPasswordlessOptions{ Template: &templateType, State: "jAy-state1-gM4fdZ...2nqm6Q", ExpiresIn: 300, MagiclinkAuthUri: "https://yourapp.com/passwordless/verify", // required if Link or Link+OTP TemplateVariables: map[string]string{ "employeeID": "EMP523", "teamName": "Alpha Team", }, },)
// resp contains: AuthRequestId, ExpiresAt, ExpiresIn, PasswordlessType
Parameter | Required | Description |
---|---|---|
email | Yes | The email address to send the passwordless link to string |
MagiclinkAuthUri | No | Magic Link URI for authentication string |
State | No | Optional state parameter string |
Template | No | Email template type (SIGNIN /SIGNUP ) string |
ExpiresIn | No | Expiration time in seconds number |
TemplateVariables | No | Key-value pairs for email template object |
Parameters | Description |
---|---|
AuthRequestId | Unique identifier for the passwordless authentication request string |
ExpiresAt | Expiration time in seconds since epoch number |
ExpiresIn | Expiration time in seconds number |
PasswordlessType | Type of passwordless authentication (OTP , LINK or LINK_OTP ) string |
Users can request a new verification email if they need one. Use the following endpoint to send a fresh email to verify using OTP or Magic Link.
curl -L '<SCALEKIT_ENVIRONMENT_URL>/api/v1/passwordless/email/resend' \-H 'Content-Type: application/json' \-H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsIm..' \-d '{ "auth_request_id": "jAy-state1-gM4fdZ...2nqm6Q"}'
# Response
# {
# "auth_request_id": "jAy-state1-gM4fdZ...2nqm6Q"
# "expires_at": "1748696575"
# "expires_in": 300
# "passwordless_type": "OTP" | "LINK" | "LINK_OTP"
# }
Parameters | Required | Description |
---|---|---|
auth_request_id | Yes | The unique identifier for the authentication request that was sent earlier string |
Parameters | Description |
---|---|
auth_request_id | A unique identifier for the authentication request that can be used to verify the code string |
expires_at | Unix timestamp indicating when the verification code will expire string |
expires_in | The time in seconds after which the verification code will expire. Default is 300 seconds number |
passwordless_type | The type of passwordless authentication to use. Currently supports OTP , LINK and LINK_OTP string |
const { authRequestId } = sendResponse;const resendResponse = await scalekit.passwordless.resendPasswordlessEmail( authRequestId);
// resendResponse = {// authRequestId: "jAy-state1-gM4fdZ...2nqm6Q",// expiresAt: "1748696575",// expiresIn: "300",// passwordlessType: "OTP" | "LINK" | "LINK_OTP"// }
Parameters | Required | Description |
---|---|---|
authRequestId | Yes | The unique identifier for the authentication request that was sent earlier string |
Parameters | Description |
---|---|
authRequestId | Unique identifier for the passwordless authentication request string |
expiresAt | Expiration time in seconds since epoch number |
expiresIn | Expiration time in seconds. Default is 300 seconds number |
passwordlessType | OTP , LINK or LINK_OTP string |
// Resend passwordless email for an existing auth requestresendResp, err := scalekitClient.Passwordless().ResendPasswordlessEmail( ctx, // context.Context (e.g., context.Background()) authRequestId, // string: from the send email response)
if err != nil { // handle error (log, return HTTP 400/500, etc.) // ...}
// resendResp is a pointer to ResendPasswordlessResponse struct:// type ResendPasswordlessResponse struct {// AuthRequestId string // Unique ID for the passwordless request// ExpiresAt int64 // Unix timestamp (seconds since epoch)// ExpiresIn int // Expiry duration in seconds// PasswordlessType string // "OTP", "LINK", or "LINK_OTP"// }
Parameters | Required | Description |
---|---|---|
authRequestId | Yes | The unique identifier for the authentication request that was sent earlier string |
Parameters | Description |
---|---|
AuthRequestId | Unique identifier for the passwordless authentication request string |
ExpiresAt | Expiration time in seconds since epoch number |
ExpiresIn | Expiration time in seconds. Default is 300 seconds number |
PasswordlessType | OTP , LINK or LINK_OTP string |
If you enabled Enable new passwordless credentials on resend in the Scalekit dashboard, a new verification code or magic link will be sent each time the user requests a new one.
Once the user receives the verification email,
link_token
request parameter from the URL and use it to verify the user’s email address.auth_request_id
to the verification endpoint.POST /api/v1/passwordless/email/verify
Example implementation
curl -L '<SCALEKIT_ENVIRONMENT_URL>/api/v1/passwordless/email/verify' \-H 'Content-Type: application/json' \-H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsIm..' \-d '{ "code": "123456", "auth_request_id": "YC4QR-dVZVtNNVHcHwrnHNDV..."}'
Parameters | Required | Description |
---|---|---|
code | Yes | The verification code entered by the user string |
auth_request_id | Yes | The request ID from the response when the verification email was sent string |
Parameters | Description |
---|---|
email | The email address of the user string |
state | The state parameter that was passed in the original request string |
template | The template that was used for the verification code string |
passwordless_type | The type of passwordless authentication to use. Currently supports OTP , LINK and LINK_OTP string |
const { authRequestId } = sendResponse;const verifyResponse = await scalekit.passwordless .verifyPasswordlessEmail( { code: "123456"}, authRequestId );
// verifyResponse = {// "email": "saifshine7@gmail.com",// "state": "jAy-state1-gM4fdZdV22nqm6Q_j..",// "template": "SIGNIN",// "passwordless_type": "OTP" | "LINK" | "LINK_OTP"// }
Parameters | Required | Description |
---|---|---|
options.code | Yes | The verification code received by the user string |
authRequestId | Yes | The unique identifier for the authentication request that was sent earlier string |
Parameters | Description |
---|---|
email | The email address of the user string |
state | The state parameter that was passed in the original request string |
template | The template that was used for the verification code string |
passwordlessType | The type of passwordless authentication to use. Currently supports OTP , LINK and LINK_OTP string |
// Verify with OTP codeverifyResponse, err := scalekitClient.Passwordless().VerifyPasswordlessEmail( ctx, &scalekit.VerifyPasswordlessOptions{ Code: "123456", // OTP code AuthRequestId: authRequestId, },)
if err != nil { // Handle error return}
// verifyResp contains the verified user's info// type VerifyPasswordLessResponse struct {// Email string// State string// Template string // SIGNIN | SIGNUP// PasswordlessType string // OTP | LINK | LINK_OTP// }
Parameters | Required | Description |
---|---|---|
options.Code | Yes | The verification code received by the user string |
options.AuthRequestId | Yes | The unique identifier for the authentication request that was sent earlier string |
Parameters | Description |
---|---|
Email | The email address of the user string |
State | The state parameter that was passed in the original request string |
Template | The template that was used (SIGNIN or SIGNUP ) string |
PasswordlessType | OTP , LINK or LINK_OTP string |
link_token
request parameter from the URL.POST /api/v1/passwordless/email/verify
Example implementation
curl -L '<SCALEKIT_ENVIRONMENT_URL>/api/v1/passwordless/email/verify' \-H 'Content-Type: application/json' \-H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsIm..' \-d '{ "link_token": "a4143d8f-...c846ed91e_l", "auth_request_id": "YC4QR-dVZVtNNVHcHwrnHNDV..." // (optional)}'
Parameters | Required | Description |
---|---|---|
link_token | Yes | The link token received by the user string |
auth_request_id | No | The request ID you received when the verification email was sent. string |
Parameters | Description |
---|---|
email | The email address of the user string |
state | The state parameter that was passed in the original request string |
template | The template that was used for the verification code string |
passwordless_type | The type of passwordless authentication to use. Currently supports OTP , LINK and LINK_OTP string |
// User clicks the magic link in their email// Example magic link: https://yourapp.com/passwordless/verify?link_token=a4143d8f-d13d-415c-8f5a-5a5c846ed91e_l
// 2. Express endpoint to handle the magic link verificationapp.get('/passwordless/verify', async (req, res) => { const { link_token } = req.query;
try { // 3. Verify the magic link token with Scalekit const verifyResponse = await scalekit.passwordless .verifyPasswordlessEmail( { linkToken: link_token }, authRequestId // (optional) sendResponse.authRequestId );7 collapsed lines
// 4. Successfully log the user in // Set session/token and redirect to dashboard res.redirect('/dashboard'); } catch (error) { res.status(400).json({ error: 'The magic link is invalid or has expired. Please request a new verification link.' }); }});
// verifyResponse = {// "email": "saifshine7@gmail.com",// "state": "jAy-state1-gM4fdZdV22nqm6Q_j..",// "template": "SIGNIN",// "passwordless_type": "OTP" | "LINK" | "LINK_OTP"// }
Parameters | Required | Description |
---|---|---|
options.linkToken | Yes | The link token received by the user string |
authRequestId | No | The unique identifier for the authentication request that was sent earlier. string |
Parameters | Description |
---|---|
email | The email address of the user string |
state | The state parameter that was passed in the original request string |
template | The template that was used for the verification code string |
passwordlessType | The type of passwordless authentication to use. Currently supports OTP , LINK and LINK_OTP string |
verifyResponse, err := scalekitClient.Passwordless().VerifyPasswordlessEmail( ctx, &scalekit.VerifyPasswordlessOptions{ LinkToken: linkToken, // Magic link token },)
if err != nil { // Handle error return}
// User verified successfullyuserEmail := verifyResponse.Email
Congratulations! You’ve successfully implemented passwordless authentication in your application. Users can now sign in securely without passwords by entering a verification code or clicking a magic link sent to their email.