Developer guideIntegrations
Supabase Auth with custom SMTP
Get Supabase Auth confirmation emails, magic links and password resets delivered with Couryo's SMTP. Step by step in the dashboard, the CLI and the management API.
The email service built into Supabase is meant for testing: it has a very low hourly sending limit, and on new projects it only delivers to the project team's addresses. In production it is the classic cause of "the confirmation email never arrives". The fix is to turn on custom SMTP.
Before you start#
- In Couryo, verify the domain your emails will come from (for example,
example.com). - Create an API key with the
sendscope. It is the SMTP password.
1. Set it up in the Supabase dashboard#
In Authentication > Emails > SMTP Settings, turn on Enable Custom SMTP and fill in:
| Field | Value |
|---|---|
| Sender email | an address on the verified domain, such as no-reply@example.com |
| Sender name | your app's name |
| Host | smtp.couryo.com |
| Port number | 587 (or 465) |
| Username | couryo |
| Password | your API key (ck_live_...) |
Save. Then, in Authentication > Rate Limits, set the hourly email limit to your app's volume: with your own SMTP, that number is yours to choose.
Want to test the flow without delivering anything? Use a
ck_test_key. The confirmation email is captured and shows up in the Couryo dashboard, with a clickable link.
2. Or with the CLI (local development and versioned projects)#
[auth.email.smtp]
enabled = true
host = "smtp.couryo.com"
port = 587
user = "couryo"
pass = "env(COURYO_API_KEY)"
admin_email = "no-reply@example.com"
sender_name = "Example"3. Or with the management API#
curl -X PATCH "https://api.supabase.com/v1/projects/$PROJECT_REF/config/auth" \
-H "Authorization: Bearer $SUPABASE_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"external_email_enabled": true,
"smtp_admin_email": "no-reply@example.com",
"smtp_sender_name": "Example",
"smtp_host": "smtp.couryo.com",
"smtp_port": "587",
"smtp_user": "couryo",
"smtp_pass": "'"$COURYO_API_KEY"'"
}'4. Test it#
Sign up a test user in your app (or use Authentication > Users > Add user > Send invitation). In the Couryo dashboard, under Emails, the message shows up with its timeline: accepted, sent and delivered, with the destination server's answer. If it was refused, the explanation says why, in plain words.
Supabase email templates#
The texts live in Authentication > Emails > Templates and use variables such as {{ .ConfirmationURL }}. A few rules that help reach the inbox:
- Check the Site URL and Redirect URLs (Authentication > URL Configuration). A link pointing to
localhostor to another domain is the second most common reason for "the link does not work". - Write like a person: "Confirm your email to sign in to Example" as the subject, the app name in the body and a line saying why the person got it.
- Do not use link shorteners and avoid image-only emails.
- Prefer the 6-digit code (
{{ .Token }}) when your app runs on phones: some corporate providers open links before the person does to check them, which can use up a single-use link.
Still not arriving?#
| What to check | Where |
|---|---|
| Did Supabase send it? | Logs > Auth in Supabase. SMTP errors show up there, with the code |
| Did Couryo get it? | Emails in the Couryo dashboard, searching by recipient |
550 5.7.1 in the Supabase log |
the Sender email is not on a verified domain, or the account is still on level 0 (sandbox) |
535 5.7.8 |
username other than couryo, or a key that is invalid, revoked or without the send scope |
| Delivered, but the person cannot find it | spam folder or Gmail tabs. See Why emails go to spam |
over_email_send_rate_limit |
Supabase's Rate Limits setting, not Couryo's |
More causes, provider by provider, in the guide Confirmation email not arriving.