Guide Supabase
Une nouvelle ligne dans Supabase,
un email et un WhatsApp partent.
Un database webhook appelle une Edge Function à chaque insert, la fonction fait un appel API, et le message de bienvenue ou de commande part de votre boîte mail, de votre numéro WhatsApp ou de votre téléphone Android. Gratuit, avec le code et un prompt pour votre éditeur IA.
Pressé ? Résumez cet article avec une IA
La réponse courte
Comment envoyer email, SMS et WhatsApp depuis Supabase ?
Créez un database webhook sur votre table (profiles, orders) qui appelle une Edge Function Supabase à chaque INSERT. La fonction lit la nouvelle ligne et fait une requête POST /message à Unlimited Messaging, qui envoie l'email depuis votre boîte mail, le WhatsApp depuis votre numéro et le SMS depuis votre téléphone Android. Les database webhooks passent par pg_net : l'insert n'attend jamais le message.
Supabase n'a pas d'API pour les messages que votre application envoie. Son service d'email intégré sert aux emails d'Auth : il envoie 2 messages par heure, uniquement aux adresses de l'équipe du projet, et Supabase précise qu'il n'est pas prévu pour la production. Un email de bienvenue, une confirmation de commande ou un WhatsApp au client, c'est à vous de les envoyer.
Une Edge Function est le bon endroit : elle tourne côté serveur, lit les secrets avec Deno.env.get, et le plan Free de Supabase inclut 500 000 invocations. Le montage habituel, c'est un fournisseur par canal, une API email, Twilio pour le SMS, la Cloud API de Meta pour WhatsApp : trois clés, trois factures. Ici une seule requête couvre les trois canaux, et le plan Free d'Unlimited Messaging ne facture rien au message.
Ce guide couvre les messages envoyés par votre application. Les emails d'Auth (confirmation d'inscription, magic link, mot de passe oublié) et l'OTP par téléphone restent dans les réglages de Supabase Auth, où vous branchez un serveur SMTP ou un fournisseur SMS.
À lire aussi : email et WhatsApp en une seule requête API, et l'API SMS gratuite qui envoie depuis votre téléphone.

Pas à pas
Comment le mettre en place, étape par étape ?
Cinq étapes, environ 15 minutes. Il vous faut un projet Supabase, la CLI Supabase et un compte Unlimited Messaging gratuit.
Connectez vos canaux et créez une clé API
Dans l'application Unlimited Messaging, liez votre numéro WhatsApp par QR code, connectez votre boîte mail en IMAP/SMTP (un mot de passe d'application Gmail suffit) et, pour le SMS, connectez-vous à l'application Android gratuite sur un téléphone avec une SIM. Ne connectez que les canaux utiles, puis créez une clé API.
supabase/functions/.env.env# supabase/functions/.env (gitignored, local only) # Created at app.unlimitedmessaging.app > API keys UM_API_KEY=um_live_xxxx # Any long random string, shared with the database webhook WEBHOOK_SECRET=change-me-to-a-long-random-stringCréez la fonction et enregistrez les secrets
Créez la fonction avec la CLI et poussez les deux secrets dans votre projet. Ils restent dans l'environnement de la fonction : ne mettez jamais la clé API dans une variable VITE_ ou NEXT_PUBLIC_, ni nulle part dans le code frontend.
TerminalSupabase CLIsupabase functions new notify-signup # Push the secrets to your project (never to the frontend) supabase secrets set --env-file supabase/functions/.env supabase secrets listÉcrivez la fonction
La fonction vérifie le secret partagé, lit la ligne insérée, envoie l'email à chaque fois et le WhatsApp seulement si la ligne a un numéro. priority: transactional fait passer le message devant un envoi en masse déjà dans votre file.
notify-signup/index.tsDeno / TypeScript// supabase/functions/notify-signup/index.ts type Profile = { id: string; email: string; phone: string | null; full_name: string | null }; type WebhookPayload = { type: 'INSERT' | 'UPDATE' | 'DELETE'; table: string; schema: string; record: Profile; old_record: Profile | null; }; Deno.serve(async (req) => { // The database webhook sends this header; nobody else knows it if (req.headers.get('x-webhook-secret') !== Deno.env.get('WEBHOOK_SECRET')) { return new Response('Unauthorized', { status: 401 }); } const { record } = (await req.json()) as WebhookPayload; const name = record.full_name ?? 'there'; // Email always, WhatsApp when the row has a phone (E.164: +33612345678). // Use { channel: 'SMS' } instead for people who are not on WhatsApp. const channels: Array<{ channel: 'EMAIL' | 'WHATSAPP' | 'SMS' }> = [{ channel: 'EMAIL' }]; if (record.phone) channels.push({ channel: 'WHATSAPP' }); const res = await fetch('https://api.unlimitedmessaging.app/message', { method: 'POST', headers: { Authorization: `Bearer ${Deno.env.get('UM_API_KEY')}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ to: { email: record.email, phone: record.phone ?? undefined }, channels, subject: 'Welcome aboard', text: `Hi ${name}, your account is ready. Reply to this message if you need anything.`, priority: 'transactional', }), }); if (!res.ok) console.error('Unlimited Messaging', res.status, await res.text()); return new Response(null, { status: res.ok ? 200 : 502 }); });Déployez-la, protégée par votre propre secret
Un database webhook n'envoie pas de JWT utilisateur : désactivez la vérification de la plateforme pour cette seule fonction (--no-verify-jwt, ou verify_jwt = false dans config.toml). L'en-tête x-webhook-secret vérifié par la fonction bloque les inconnus.
TerminalSupabase CLI# A database webhook sends no user JWT: turn the platform check off # for this function only, the x-webhook-secret header protects it supabase functions deploy notify-signup --no-verify-jwt # Or keep it in supabase/config.toml: # [functions.notify-signup] # verify_jwt = falseCréez le database webhook
Dans le dashboard, Database > Webhooks : choisissez la table (profiles ici), l'événement Insert, le type Supabase Edge Functions et la fonction notify-signup, puis ajoutez un en-tête x-webhook-secret avec la même valeur. Insérez une ligne de test : voici le corps que reçoit la fonction.
Corps du POSTWebhook payload{ "type": "INSERT", "table": "profiles", "schema": "public", "record": { "id": "8f1c2d3e-0000-4000-8000-000000000000", "email": "[email protected]", "phone": "+33612345678", "full_name": "Lea" }, "old_record": null }
Vibe coding
Vous codez avec Lovable, Cursor ou Claude Code ? Collez ce prompt
Le prompt donne à votre éditeur IA le bon schéma : une Edge Function, les secrets dans Supabase, un appel REST. Il vous demande avant tout envoi réel.
Ajoute des notifications transactionnelles à ce projet Supabase avec Unlimited Messaging (email, WhatsApp et SMS envoyés depuis mes propres comptes).
1. Crée une Edge Function Supabase nommée notify-signup. Lis UM_API_KEY et WEBHOOK_SECRET avec Deno.env.get. Ne mets jamais la clé dans le code frontend ni dans une variable VITE_ / NEXT_PUBLIC_.
2. La fonction reçoit le payload d'un database webhook Supabase { type, table, schema, record, old_record }. Renvoie 401 si l'en-tête x-webhook-secret est différent de WEBHOOK_SECRET.
3. Envoie un POST https://api.unlimitedmessaging.app/message avec l'en-tête Authorization: Bearer UM_API_KEY et le JSON { to: { email, phone }, channels: [{ channel: 'EMAIL' }, { channel: 'WHATSAPP' }], subject, text, priority: 'transactional' }. N'ajoute WHATSAPP (ou SMS) que si la ligne a un numéro au format E.164.
4. Donne-moi les commandes : supabase secrets set, supabase functions deploy notify-signup --no-verify-jwt, et comment créer le database webhook sur INSERT de ma table avec l'en-tête x-webhook-secret.
5. Référence de l'API : https://docs.unlimitedmessaging.app. Je crée la clé API sur https://app.unlimitedmessaging.app.
Demande-moi quelle table et quel texte de message utiliser avant d'écrire le code.Les options
Quelle solution pour envoyer des messages depuis Supabase ?
Quatre façons d'envoyer une notification quand une ligne arrive dans votre base, du service intégré à une seule API pour tous les canaux.
| Email intégré SupabaseEmails d'Auth uniquement | Resend depuis une fonctionAPI email | Twilio depuis une fonctionAPI SMS et WhatsApp | Unlimited MessagingEmail, WhatsApp et SMS | |
|---|---|---|---|---|
| Canaux | Emails d'Auth uniquement | SMS et WhatsApp, facturés au message | Email, WhatsApp et SMS en une requête | |
| Gratuit | 2 emails par heure, adresses de l'équipe uniquement | 3 000 emails par mois, 100 par jour | Essai : 5 numéros vérifiés au maximum | Plan Free sans frais par message |
| Expéditeur | L'adresse de Supabase | Votre domaine vérifié | Un numéro Twilio ou un expéditeur WhatsApp enregistré | Votre boîte mail, votre numéro WhatsApp et votre téléphone |
| Messages WhatsApp | Non | Non | Modèles approuvés par Meta pour ouvrir une conversation | Texte libre depuis votre numéro lié |
| Mise en place | Aucune | Enregistrements DNS de votre domaine | Compte, numéro, enregistrement de l'expéditeur WhatsApp | QR code, identifiants IMAP/SMTP, application Android |
| Idéal pour | Tester les flux d'Auth | L'email en gros volume | Le SMS en volume, le WhatsApp officiel | Les messages d'une app un par un, gratuit pendant la croissance |
Vérifié le 9 novembre 2026 sur supabase.com, resend.com/pricing et la documentation d'essai de Twilio (liens dans les sources). Les offres gratuites changent : suivez les liens avant de construire dessus.
Les contreparties
Quelles sont les limites ?
Gratuit supprime la facture au message. Pas les règles de WhatsApp, de votre téléphone ou de votre boîte mail.
WhatsApp est non officiel, et le spam fait bannir les numéros
Votre numéro est lié comme un appareil, hors de la plateforme Business de Meta. Écrire à des clients inscrits qui attendent le message est peu risqué ; des envois en masse à des inconnus peuvent faire bannir le numéro. Gardez WhatsApp pour le transactionnel.
Le SMS demande un téléphone Android allumé
Les SMS partent de la SIM du téléphone, sur votre forfait. Android demande une confirmation au-delà de 30 SMS en 30 minutes, l'application espace donc les envois à environ 30 toutes les 30 minutes : parfait pour des inscriptions et des commandes, pas pour un envoi massif le jour du lancement.
L'email suit les limites de votre boîte mail
Les emails partent de votre boîte en SMTP, son plafond quotidien s'applique donc : 500 par jour sur un compte Gmail. Pour une newsletter à des milliers de personnes, prenez un service d'emailing.
Les messages du plan Free portent une signature
Sur le plan Free, les messages se terminent par une courte ligne "Sent with UnlimitedMessaging.app", et les médias et les webhooks sont payants. Medium et Max retirent la ligne.
L'insert n'attend pas le message
pg_net envoie la requête de façon asynchrone : une fonction en erreur n'annule jamais l'insert. Journalisez la réponse de l'API dans la fonction et surveillez ses logs.
La clé reste côté serveur
Quiconque ouvre votre bundle frontend peut réutiliser une clé qui s'y trouve. La clé va dans les secrets de l'Edge Function, et le secret du webhook empêche les inconnus d'appeler votre fonction.
FAQ
Questions sur l'envoi de messages depuis Supabase
Sources
Sources & références
Pour vérifier par vous-même les informations de cet article :
- Database WebhooksSupabase Docs
- Managing secrets (environment variables) for Edge FunctionsSupabase Docs
- Function configuration (verify_jwt)Supabase Docs
- Send emails with custom SMTP (limite intégrée : 2 messages par heure)Supabase Docs
- Pricing (500 000 invocations d'Edge Functions en Free)Supabase
- Pricing (Free : 3 000 emails par mois, 100 par jour)Resend
- How to use your free trial account (Messaging)Twilio Docs
- Message templatesMeta for Developers
- Limites d'envoi et de réception (500 emails par jour)Aide Gmail
- SmsUsageMonitor (seuil de 30 SMS en 30 minutes)Android Open Source Project
- Référence de l'API : POST /messageUnlimited Messaging Docs

Écrit par
Ilian · Senior Software Engineer
Ingénieur logiciel senior, il fonde et dirige plusieurs sociétés tech. Il conçoit des produits autour des API de messagerie, de l’automatisation et de l’intégration de l’IA, et partage ici ce qu’il apprend en construisant.
Envoyez votre première notification Supabase aujourd'hui.
Créez un compte gratuit, connectez une boîte mail ou un numéro WhatsApp, collez la fonction. Sans carte bancaire, sans frais par message.