Envello
Tutorial

Sending email from Supabase Edge Functions

Envello Team·2026-07-17·4 min read

Supabase Edge Functions run on Deno, which has fetch built in globally, so sending a transactional email doesn't need a dependency at all, just an HTTP call to Envello's API from inside the function.

The function

  • Store the key with supabase secrets set ENVELLO_API_KEY=env_live_..., read it with Deno.env.get('ENVELLO_API_KEY') inside the function
  • const res = await fetch('https://api.envello.dev/emails', { method: 'POST', headers: { Authorization: `Bearer ${apiKey}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ from, to, subject, html }) })
  • Return an appropriate response status from the Edge Function based on res.ok, so whatever called the function (a client, a webhook, a trigger) knows whether the send actually succeeded

Triggering it from a database event

A common pattern: a Supabase Database Webhook fires the Edge Function on an insert or update (a new signup row, a status change), and the function builds the email content from the row data before calling Envello. This keeps the send logic out of client-side code entirely, which matters since a client-side call would otherwise need to expose your API key.

Never call this from the client directly

The whole point of routing this through an Edge Function rather than calling Envello's API from a browser or mobile client is keeping the API key server-side. If your Edge Function is triggered by a client request rather than a database event, validate that request server-side (Supabase's row-level security or your own auth check) before sending, rather than letting an unauthenticated request trigger an arbitrary email send.

Envello

EU-hosted transactional email, done right by default.