Skip to main content

Lovable guide

Email, SMS and WhatsApp
in your Lovable app, free.

Paste one prompt into Lovable: it writes an Edge Function that sends the same message by email, WhatsApp and SMS, from your own mailbox, number and phone, with the API key kept server-side.

In a hurry? Summarize this article with an AI

The short answer

How do you send email, SMS and WhatsApp from a Lovable app?

Ask Lovable to create a Supabase Edge Function that calls one REST endpoint, POST https://api.unlimitedmessaging.app/message, with your API key stored in Lovable Secrets. One request sends the same message by email, WhatsApp and SMS, from your own mailbox, number and Android phone, on a free plan with no credit card.

Lovable writes the React frontend and, through Lovable Cloud or a connected Supabase project, the backend functions. Sending a message is backend work: the API key has to stay out of the browser bundle, so the call belongs in an Edge Function that your frontend invokes.

Unlimited Messaging is a messaging API that sends from accounts you already own: an email from your Gmail or domain mailbox over IMAP/SMTP, a WhatsApp message from your number linked like WhatsApp Web, and an SMS from your Android phone's SIM through a free app. The free plan charges nothing per message on any channel; messages end with a short "Sent with UnlimitedMessaging.app" line.

Lovable also has its own routes: built-in Lovable Emails for transactional email on paid Lovable plans, and connectors for Resend and Twilio. They are good tools. This guide is for when you want all three channels behind one call, without verifying a sending domain or paying per message while you test.

Same message on several channels: email and WhatsApp in one API request. Connecting Gmail: the app password guide. SMS from your phone: the Android app.

Illustration: one POST /message request branching to a chat bubble and an email, with the headline “Lovable app, three channels, one call”.

Why not hand-code it

Why is wiring SMTP, Twilio and Meta yourself so slow?

Each channel has its own provider, account, verification and rules. Here is what each one asks before your first real message goes out.

  1. Email: SMTP ports are blocked in Edge Functions

    Supabase does not allow outgoing connections to ports 25 and 587 from Edge Functions, so the classic nodemailer-over-SMTP snippet fails there. You end up with an email API such as Resend, which needs a verified domain: its shared [email protected] sender only delivers to your own address.

  2. SMS: a provider account, a number and registration

    With Twilio you rent a number and pay per segment, $0.0083 per segment in the US plus carrier fees. Texting US numbers from a regular long code also requires A2P 10DLC registration, with a $4.50 brand fee and vetting before you can send.

  3. WhatsApp: Meta's Business Platform rules

    The official Cloud API needs a Meta business setup, an approved template for any message sent outside the 24-hour customer service window (review takes up to 24 hours), a price per template message, and new accounts start at 250 unique recipients per 24 hours.

  4. Three SDKs, three webhooks, three bills

    Each provider has its own client library, error format and inbound webhook. That is three integrations for your AI builder to get right, three keys to store, and three invoices once you launch.

Side by side

Which way should a Lovable app send messages?

The four routes Lovable builders use most, on the points that matter for a prototype.

Which way should a Lovable app send messages?
Lovable EmailsBuilt-in transactional emailResend connectorEmail APITwilio connectorSMS and WhatsApp APIUnlimited MessagingEmail, SMS and WhatsApp API
ChannelsEmailEmailSMS and WhatsAppEmail, WhatsApp and SMS in one request
Free tierPaid Lovable plans only (50,000 emails a month included)3,000 emails a month, 100 a dayTrial credit, then pay per messageFree plan, no per-message fee, footer line on messages
Before the first real sendYour own domain and DNS recordsA domain verified in ResendA Twilio number, 10DLC for US SMS, Meta setup for WhatsAppLink a mailbox, scan a QR code, install the Android app
SenderYour domainYour domainA rented number or sender IDYour own mailbox, number and SIM
VolumeHourly caps (100 app emails an hour on Pro)Built for volumeBuilt for volumeHuman pace: mailbox limits, about 30 SMS per 30 minutes, no bulk
Official WhatsAppNo WhatsAppNo WhatsAppYes, Meta Business PlatformNo: linked device, ban risk if you spam

Prices and limits from each vendor's own page, checked on 9 November 2026. On WhatsApp, Twilio also passes on Meta's fee per template message.

Step by step

From zero to a first message in five steps

  1. 01

    Create a free account

    Sign up at app.unlimitedmessaging.app with Google, GitHub or your email address. No credit card; the Free plan is permanent.

  2. 02

    Connect the channels you need

    Add your mailbox (Gmail with an app password, or any IMAP/SMTP host), scan a QR code to link your WhatsApp number, and install the Android app on a phone with a SIM for SMS. One channel is enough to start.

  3. 03

    Create an API key

    In the dashboard, open the API section and create a key. Copy it right away and keep it out of your code.

  4. 04

    Store it in Lovable Secrets

    Open Settings, then Secrets, and add UM_API_KEY, or use the secure input Lovable shows when a feature needs a key. Lovable injects it into Edge Functions only.

  5. 05

    Paste the prompt below

    Lovable writes the Edge Function and the trigger that calls it. Send the first test to your own number and inbox.

Copy, paste

What prompt do you paste into Lovable?

Paste this into the Lovable chat. It asks for an Edge Function, the key from Secrets and a welcome message on signup. Change the trigger and the text to fit your app.

Prompt for LovablePrompt
Add messaging to this app with Unlimited Messaging (REST API, docs: https://docs.unlimitedmessaging.app).

1. Create a Supabase Edge Function named notify-user. It reads the API key from the secret UM_API_KEY: ask me to add it in Secrets, never put it in frontend code or in a VITE_ variable.
2. The function calls POST https://api.unlimitedmessaging.app/message with the header "Authorization: Bearer <UM_API_KEY>" and this JSON body: { "to": { "phone": "<E.164 number>", "email": "<email>" }, "subject": "...", "text": "...", "channels": [{ "channel": "EMAIL" }, { "channel": "WHATSAPP" }, { "channel": "SMS" }] }.
3. Keep JWT verification on and only send to the signed-in user's own email and phone, loaded on the server, never to an address taken from the request body.
4. Call the function right after signup with a short welcome message, and log the API response so errors are visible.
5. Before testing, ask me for my own phone number and email.
The API is plain HTTPS, so the same prompt works in Bolt, v0, Cursor or Claude Code with a different first line.
Edge FunctionDeno / Supabase
// supabase/functions/notify-user/index.ts
const cors = {
  'Access-Control-Allow-Origin': '*',
  'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',
};

Deno.serve(async (req) => {
  if (req.method === 'OPTIONS') return new Response('ok', { headers: cors });
  const { phone, email, name } = await req.json();

  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: { phone, email },
      subject: 'Welcome aboard',
      text: `Hi ${name}, your account is ready.`,
      channels: [{ channel: 'EMAIL' }, { channel: 'WHATSAPP' }, { channel: 'SMS' }],
    }),
  });

  return new Response(await res.text(), {
    status: res.status,
    headers: { ...cors, 'Content-Type': 'application/json' },
  });
});
What the Edge Function looks like. Minimal version: in production, load the signed-in user's email and phone from your database rather than trusting the request body. Remove a channel from the list if you have not connected it.
supabase.functions.invokeReact
// In a React component: the browser never sees UM_API_KEY
const { data, error } = await supabase.functions.invoke('notify-user', {
  body: { phone: '+33612345678', email: '[email protected]', name: 'Lea' },
});
The frontend only calls the function. supabase.functions.invoke sends the user's session token, and Supabase checks it before running the function.

Safety

Where should the API key live in a Lovable app?

Server-side only. Lovable's own docs draw the line: secrets for Edge Functions, VITE_ variables for values that can be public.

  1. In Secrets, read by the Edge Function

    Lovable stores secrets encrypted, injects them into Edge Functions at runtime and never includes them in frontend code. The function reads the key with Deno.env.get('UM_API_KEY').

  2. Never in a VITE_ variable

    Lovable's docs state that VITE_ variables are embedded into the client bundle at build time. Anyone can read them in the browser's developer tools, then send messages from your accounts.

  3. Not in the chat either

    Do not paste the key as plain text in a prompt. Lovable shows a secure input when a feature needs a secret; use it, or the Secrets page.

  4. No open relay

    A function that sends any text to any number from the request body lets strangers use your WhatsApp and mailbox. Keep JWT verification on, look the recipient up on the server, and limit sends per user.

  5. One key per environment

    Create one key for testing and one for production, so you can revoke a leaked key without breaking the live app.

Replies

How do you receive replies in your Lovable app?

On every plan, replies land in the Unlimited Messaging inbox: emails grouped by thread, WhatsApp chats, and SMS received by the Android app after sign-in. To push them into your own app, you need webhooks, which come with the paid plans: Medium at €19 a month and Max at €29 a month.

Ask Lovable for a second Edge Function, for example um-webhook, register its URL on the Webhooks page of the dashboard, and subscribe to message.received (an inbound message) and message.status (sent, delivered, read, failed). Unlimited Messaging calls this function, not a signed-in user, so turn JWT verification off for it and check the signature instead.

Each delivery is signed per the Standard Webhooks spec, with an HMAC-SHA256 in the webhook-signature header. Answer with a 2xx within 10 seconds and do the work afterwards. Failed deliveries are retried for a little more than 3 days, so deduplicate on eventId.

message.receivedJSON
{
  "type": "message.received",
  "eventId": "whd_...",
  "occurredAt": "2026-11-09T10:00:01.000Z",
  "data": {
    "channel": "WHATSAPP",
    "message": {
      "text": "Yes, see you Monday!"
    }
  }
}
A message.received event, shortened. data.message carries the sender and the text, plus the subject and attachments for an email.
verify-webhook.tsTypeScript
import { createHmac } from 'node:crypto';
import { Buffer } from 'node:buffer';

// Standard Webhooks signature check, before trusting the body.
export function isValid(rawBody: string, h: Headers, secret: string) {
  const id = h.get('webhook-id');
  const ts = h.get('webhook-timestamp');
  const sig = h.get('webhook-signature') ?? '';
  if (!id || !ts || Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false;
  const key = Buffer.from(secret.replace(/^whsec_/, ''), 'base64');
  const expected = createHmac('sha256', key)
    .update(`${id}.${ts}.${rawBody}`)
    .digest('base64');
  return sig.split(' ').some((s) => s === `v1,${expected}`);
}
A signature check that runs in an Edge Function (Deno) or in Node.js. Store the whsec_ secret as a second secret, for example UM_WEBHOOK_SECRET.

Limits

What are the limits, honestly?

Unlimited Messaging sends from personal accounts at a human pace. That suits notifications, reminders and conversations, not mass mailings.

  1. WhatsApp is unofficial

    Your number is linked as a device, like WhatsApp Web, not through Meta's Business Platform. Messaging people who never asked for it gets numbers banned. For marketing at scale, Meta's official Cloud API is the right tool.

  2. Email follows your mailbox's limits

    A personal Gmail account sends up to 500 emails a day. Use a Workspace or domain mailbox for more, and an email service provider for newsletters.

  3. SMS goes at Android's pace

    Android asks for confirmation beyond 30 SMS in 30 minutes, so the app spaces messages out. Each SMS counts against your carrier plan, and the sending phone has to be an Android.

  4. What the free plan leaves out

    Messages on Free end with "Sent with UnlimitedMessaging.app". Media, voice messages and webhooks need a paid plan, which also removes the footer.

FAQ

Questions about messaging from Lovable

Ilian, senior software engineer

Written by

· Senior Software Engineer

A senior software engineer, he founds and runs several tech companies. He builds products around messaging APIs, automation and AI integration, and shares here what he learns while building.

View LinkedIn profileUpdated

Ship the notifications today. Pay later, if ever.

Create a free account, connect a mailbox, a number or a phone, and paste the prompt into Lovable.