Password-based authentication adds friction at every step. Users forget passwords, pick weak ones, or reuse them across sites. Your app pays the cost in support tickets, reset flows, and abandoned signups.
Magic Link authentication removes the password entirely. A user enters their email address, gets a link, clicks it, and is logged in. No password to create, no password to remember, no reset flow to build.
Appwrite supports Magic Link authentication out of the box, with a clean two-step implementation that integrates with your existing auth setup.
How Magic Link authentication works
The flow has two phases: sending the magic link, and creating the session after the user clicks it.
When a user requests a magic link, Appwrite generates a short-lived token and sends it to their email address embedded in a URL. The URL points to a page you control in your app. When the user clicks the link, your app reads the token and user ID from the query parameters and exchanges them for a session.
That is the complete flow. There are no cookies to manage on the initial request, no passwords to hash, and no password reset infrastructure to maintain separately.
Implementing the two-step flow
Step 1: Request the magic link
Call account.createMagicURLToken with a unique user ID, the user's email address, and the URL in your app where you want to handle verification:
import { Client, Account, ID } from "appwrite";
const client = new Client()
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1')
.setProject('<PROJECT_ID>');
const account = new Account(client);
const token = await account.createMagicURLToken({
userId: ID.unique(),
email: 'user@example.com',
url: 'https://yourapp.com/verify'
});
Appwrite appends secret and userId as query parameters to the redirect URL before sending it in the email. The user receives a message with a link like:
https://yourapp.com/verify?userId=abc123&secret=xyz789
If the email address is new, Appwrite creates a new account using the userId you supplied. If the email is already attached to an existing account, Appwrite ignores the userId you provided and sends the magic link to the existing account owner.
Step 2: Create the session
Your verification page reads the query parameters and calls account.createSession:
import { Client, Account } from "appwrite";
const client = new Client()
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1')
.setProject('<PROJECT_ID>');
const account = new Account(client);
const urlParams = new URLSearchParams(window.location.search);
const secret = urlParams.get('secret');
const userId = urlParams.get('userId');
const session = await account.createSession({ userId, secret });
After this call succeeds, the user is authenticated. Appwrite sets the session cookie and the user can access protected resources. The token is single-use and expires, so replaying the URL after the session is created will fail.
UX benefits that compound over time
Removing passwords is not just a convenience improvement. It affects multiple points in the user journey:
Onboarding is faster. New users do not need to choose and confirm a password before they can see the app. The signup and login flows merge into a single action.
Support load drops. Password reset is one of the most common support requests for any app with user accounts. Magic Link eliminates it entirely for users who choose that method.
Security improves by default. There is no password database to breach, no weak passwords to crack, and no credential stuffing attacks against your users. The only attack surface is the user's email inbox, which is already a trust anchor for most authentication flows anyway.
Customer identity without the hassle
Add secure authentication in minutes, not weeks.
Built-in security and compliance
Multiple login methods
Custom authentication flows
Multi-factor authentication
When to use Magic Link vs other methods
Magic Link is not the right choice for every app or every user.
Use Magic Link when:
- Your users check email regularly, typically on desktop or in a professional context.
- You want to reduce support tickets from forgotten passwords.
- You are building a tool where the email inbox is already part of the workflow.
- You want fast onboarding for infrequent users who would otherwise forget their password between sessions.
Consider other methods when:
- Your users are on mobile and may not have easy access to their email client during the login flow.
- Low latency matters, such as in gaming or real-time collaboration apps. Waiting for an email introduces friction that passwords do not.
- Users are offline or in environments where email delivery is unreliable.
For mobile-first apps or users who want a faster in-app experience, email OTP is a close alternative. Instead of clicking a link, the user receives a short numeric code they enter directly in your app. The authentication logic is similar, but the UX fits mobile better and does not require leaving the app to check email.
Magic Link vs email OTP
Both Magic Link and Email OTP are passwordless and use the user's email as a trust anchor. The implementation is also similar: both involve a token that expires after a short window.
The difference is user experience. Magic Link sends users out of your app and back, which works well on desktop where switching to an email client is a single click. Email OTP keeps the user in the app, which is smoother on mobile.
Appwrite supports both. You can offer Magic Link for desktop users and Email OTP for mobile users, or let users choose their preferred method. Neither requires maintaining separate token infrastructure since Appwrite handles generation, delivery, and validation for both.



