done, the user gets a “your export is ready” email with a download link.
Supabase Auth already sends its own emails (confirmation, magic link, reset), so don’t
rebuild those. The gap is app-domain notifications — “your export is ready,” “a new
comment,” “someone joined your waitlist” — none of which any platform sends for you. They
all reduce to the same pattern: a row changes, you call send().
You’ll need: a SenderKit account with an API key, a Supabase
project, and the Supabase CLI. The example
assumes an
exports table with email, file_name, download_url, and status
columns.1
2
Choose how the row change reaches SenderKit
Supabase can react to row changes two ways. Both are valid; pick based on whether you
need to keep your API key server-side and shape the payload.
- Edge Function (recommended)
- Database Webhook → Next.js route
A Database Webhook invokes a
Supabase Edge Function, which holds
your SenderKit key as a secret and calls the SDK. This keeps the key off the
database trigger and lets you transform or look up data before sending.Set the secrets and deploy. Webhook-invoked functions aren’t called with a Supabase
JWT, so deploy with
supabase/functions/notify-export/index.ts
--no-verify-jwt and rely on your own x-webhook-secret
header instead:3
Create the Database Webhook
In the Supabase Studio, go to Integrations → Webhooks → Create a new hook:
- Table:
exports - Events:
Update - Type: HTTP Request →
POST - URL: your Edge Function URL (
https://<project-ref>.supabase.co/functions/v1/notify-export) or your Next.js route - HTTP Headers: add
x-webhook-secretwith the value you generated above
{ type, table, schema, record, old_record } — on every matching row change.4
Verify it works
With an Watch the message appear in the SenderKit dashboard, running the full
lifecycle in test mode. The
sk_test_ key set as the function secret, flip a row to done:idempotencyKey: export:${id} means
a duplicate webhook delivery won’t email twice.5
Go live
Update the function secret to an
sk_live_ key (supabase secrets set SENDERKIT_API_KEY=sk_live_...
and redeploy). Same trigger, real delivery.What’s next
Send team invites
Another app-domain email, triggered from your own data.
Recover failed payments
Lifecycle emails from Stripe webhooks.
Sending
Idempotency and the accept-now / deliver-later model.
Messages
Filter sends by the
metadata you attached.