Supabase OTP
This guide explains how to configure Supabase to send OTP tokens instead of magic links for email authentication.
🚨 Issue: Receiving Magic Links Instead of OTP Codes
When you request an email OTP, Supabase sends a magic link instead of a 6-digit OTP code. This happens because the default configuration prioritizes magic links over OTP codes.
🔧 Solution: Configure Supabase Project Settings
Step 1: Access Supabase Dashboard
Go to https://supabase.com/dashboard
Select your project.
Navigate to Authentication → Settings
Step 2: Configure Email Auth Settings
In the Auth Settings section:
Find "Email OTP" Settings:
Look for "Email OTP" configuration
Enable "Email OTP" if it's disabled
Disable Magic Links (if needed):
Look for "Magic Link" settings
Consider disabling magic links to force OTP usage
Email Template Settings:
Go to Authentication → Email Templates
Select "Magic Link" template
Change the template type or configure it for OTP
Step 3: Alternative Approach - Use Explicit OTP Configuration
// In your API call, specify the type explicitly
const { data, error } = await supabase.auth.signInWithOtp({
email: '[email protected]',
options: {
emailRedirectTo: undefined, // Don't set redirect URL for magic links
shouldCreateUser: true
}
});
📧 Email Template Configuration
Configure Email OTP Template
Go to Authentication → Email Templates
Select "Magic Link" or find "OTP" template
Ensure the template contains
{{ .Token }}
instead of{{ .ConfirmationURL }}
Example OTP email template:
<h2>Your verification code</h2>
<p>Enter this code to verify your email:</p>
<h1>{{ .Token }}</h1>
<p>This code expires in 5 minutes.</p>
🔍 Troubleshooting
Check Current Configuration
Run this test to see what type of email you're receiving:
curl -X POST "https://auth-test.serverlessapigw.com/api/v1/supabase/auth" \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]"}'
If Still Receiving Magic Links
Check Email Templates: Verify the template uses
{{ .Token }}
not{{ .ConfirmationURL }}
Project Settings: Ensure OTP is enabled in Auth settings
Cache: Clear browser cache and try again
Different Email: Try with a different email address
Alternative Solution: Use Phone OTP
If email OTP continues to send magic links, use phone OTP instead:
curl -X POST "https://auth-test.serverlessapigw.com/api/v1/supabase/auth" \
-H "Content-Type: application/json" \
-d '{"phone": "+1234567890"}'
🧪 Testing After Configuration
Test Email OTP:
# Send OTP
curl -X POST "https://auth-test.serverlessapigw.com/api/v1/supabase/auth" \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]"}'
# You should receive an email with a 6-digit code like: 123456
# Then verify with:
curl -X POST "https://auth-test.serverlessapigw.com/api/v1/supabase/verify" \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]", "token": "123456"}'
📱 Enable SMS OTP (Optional)
If you want phone OTP:
Go to Authentication → Settings
Find "Phone Auth" section
Configure your SMS provider (Twilio, MessageBird, etc.)
Enable phone authentication
🔧 Code-Level Fix (If Dashboard Doesn't Work)
If the dashboard configuration doesn't work, we can try a different approach in the code:
// Try using admin client with explicit OTP type
const supabase = createClient(
process.env.SUPABASE_URL,
process.env.SUPABASE_SERVICE_ROLE_KEY // Use service role key
);
const { data, error } = await supabase.auth.admin.generateLink({
type: 'signup', // or 'signin'
email: email,
options: {
redirectTo: undefined // No redirect for OTP
}
});
📞 Need Help?
If you're still receiving magic links after following these steps:
Check your Supabase project's Auth settings carefully
Try creating a new test project to verify OTP behavior
Contact Supabase support if the issue persists
Consider using phone OTP as an alternative
✅ Expected Behavior After Fix
After proper configuration:
Email OTP: You'll receive a 6-digit code like
123456
Response: API returns success message about OTP being sent
Verification: Use the 6-digit code to verify and get JWT tokens
The key is ensuring your Supabase project is configured to prioritize OTP codes over magic links in the authentication flow.
Last updated