Skip to main content
Integrate Supabase with Lettr to send transactional emails from your Supabase project. This guide covers two approaches:
  • SMTP — Configure Supabase Auth to send confirmation, password reset, and magic link emails through Lettr
  • Edge Functions — Send emails programmatically from Supabase Edge Functions using Lettr’s HTTP API

Prerequisites

Before you begin, make sure you have: You’ll also need:
  • A Supabase project
  • A sender address on your verified domain (e.g. noreply@yourdomain.com)

Send Auth Emails via SMTP

Supabase Auth sends emails for user confirmations, password resets, magic links, and invitations. By default these go through Supabase’s built-in email service, which has strict rate limits. Connecting Lettr via SMTP removes those limits and gives you full delivery visibility.

SMTP Credentials

SettingValue
Hostsmtp.lettr.com
Port465
Usernamelettr
PasswordYour API key (starts with lttr_)

Configure Supabase Auth

1

Open SMTP settings

  1. Go to your Supabase project dashboard
  2. Click Authentication in the left sidebar
  3. Click SMTP Settings under the Email provider section
  4. Toggle Enable Custom SMTP on
2

Set sender details

Fill in your sender information:
  • Sender email: Your verified sending address (e.g. noreply@yourdomain.com)
  • Sender name: Your application name (e.g. My App)
The sender email must use a domain you’ve verified in the Lettr dashboard. Emails from unverified domains will be rejected.
3

Enter SMTP credentials

  • Host: smtp.lettr.com
  • Port number: 465
  • Username: lettr
  • Password: Your Lettr API key (starts with lttr_)
4

Save

Click Save. All Supabase Auth emails will now be sent through Lettr.

Customize Auth Email Templates

Supabase lets you customize the HTML for each auth email type:
  1. Go to AuthenticationEmail Templates in your Supabase dashboard
  2. Select the template type (Confirm signup, Invite user, Magic Link, Reset password)
  3. Edit the HTML and save
Supabase email templates use Go template syntax with variables like {{ .ConfirmationURL }}. These are processed by Supabase before the email is handed off to Lettr for delivery.

Send Emails from Edge Functions

For transactional emails beyond auth (order confirmations, notifications, etc.), use Supabase Edge Functions with Lettr’s HTTP API.

Set Up Your API Key

Store your Lettr API key as a Supabase secret:
supabase secrets set LETTR_API_KEY=lttr_your_api_key_here

Create an Edge Function

supabase functions new send-email
Replace the contents of supabase/functions/send-email/index.ts with:
Deno.serve(async (req) => {
  const { to, subject, html } = await req.json();

  const res = await fetch("https://app.lettr.com/api/emails", {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${Deno.env.get("LETTR_API_KEY")}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      from: "noreply@yourdomain.com",
      to: [to],
      subject,
      html,
    }),
  });

  const data = await res.json();

  return new Response(JSON.stringify(data), {
    status: res.status,
    headers: { "Content-Type": "application/json" },
  });
});

Deploy and Test

Deploy the function:
supabase functions deploy send-email
Send a test email:
curl -i --request POST \
  'https://<your-project-ref>.supabase.co/functions/v1/send-email' \
  --header 'Authorization: Bearer <your-anon-key>' \
  --header 'Content-Type: application/json' \
  --data '{
    "to": "recipient@example.com",
    "subject": "Hello from Supabase + Lettr",
    "html": "<h1>It works!</h1><p>This email was sent from a Supabase Edge Function using Lettr.</p>"
  }'

Call from Your App

Invoke the Edge Function from your client-side Supabase code:
import { createClient } from "@supabase/supabase-js";

const supabase = createClient(
  "https://<your-project-ref>.supabase.co",
  "<your-anon-key>"
);

const { data, error } = await supabase.functions.invoke("send-email", {
  body: {
    to: "recipient@example.com",
    subject: "Order Confirmation",
    html: "<h1>Thanks for your order!</h1>",
  },
});

Trigger from Database Webhooks

You can also trigger emails automatically when database rows change. Create a Database Webhook in Supabase that calls your Edge Function when a row is inserted into a table (e.g. orders):
  1. Go to DatabaseWebhooks in your Supabase dashboard
  2. Create a new webhook pointing to your send-email Edge Function
  3. Set the trigger event (e.g. INSERT on the orders table)
Deno.serve(async (req) => {
  const payload = await req.json();
  const record = payload.record;

  const res = await fetch("https://app.lettr.com/api/emails", {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${Deno.env.get("LETTR_API_KEY")}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      from: "orders@yourdomain.com",
      to: [record.customer_email],
      subject: `Order #${record.id} confirmed`,
      html: `<h1>Order Confirmed</h1><p>Thanks for your order, ${record.customer_name}!</p>`,
    }),
  });

  const data = await res.json();

  return new Response(JSON.stringify(data), {
    status: res.status,
    headers: { "Content-Type": "application/json" },
  });
});

Verify It Works

Check that emails are being delivered:
  1. Trigger a test email (auth action or Edge Function call)
  2. Verify delivery in the Lettr logs
  3. Check the recipient’s inbox
Every email sent through Lettr appears in your logs with full delivery status, so you can diagnose issues without guessing.

Troubleshooting

  • Verify the sender email uses a domain verified in Lettr
  • Double-check that the host is smtp.lettr.com and the port is 465
  • Ensure your API key is correct and starts with lttr_
  • Confirm the username is exactly lettr (lowercase)
  • Verify the LETTR_API_KEY secret is set: supabase secrets list
  • Ensure the API key starts with lttr_ and hasn’t been revoked
  • Redeploy the function after setting secrets: supabase functions deploy send-email
Supabase applies its own rate limits on auth emails (e.g. one confirmation per 60 seconds per address). These are separate from Lettr’s rate limits. Check your Supabase Auth settings under Rate Limits.
Make sure your sending domain has proper DNS records:
  • SPF — Authorizes Lettr to send on your behalf
  • DKIM — Cryptographically signs your emails
  • DMARC — Tells receivers how to handle unauthenticated mail
See Deliverability Best Practices for more tips.
If port 465 doesn’t work in your environment, use port 587 with STARTTLS instead. Both are secure.

Other Integrations

What’s Next