Lovable transactional email is one of those features that feels small until your app needs to behave like a real product. A welcome email, password reset, receipt, or account alert should happen automatically, arrive from your own domain, and never expose an email API key in the browser.
If you are building with Lovable, the fastest practical route is usually not a special plugin. It is an authenticated API integration: Lovable creates a server-side Edge Function, stores your Volanea key as a secret, and calls Volanea from that function when an app event occurs. That gives your vibe-coded app a clean boundary between public UI code and private email infrastructure.
This page shows exactly what to tell Lovable, what the resulting Edge Function can look like, where the email trigger belongs in your app, and what to verify before you consider the flow production-ready.
Why Lovable transactional email needs a server-side integration
Transactional email is email caused by an individual product event. Someone signs up, requests a password reset, pays an invoice, submits a form, or gets assigned a task. The email is part of the application workflow, not a campaign sent to a list.
That distinction matters when you build with an AI coding tool. Your app may have a polished signup screen within minutes, but a browser-only integration is not enough for email sending. A secret API key placed in frontend code can be discovered by anyone using the app. At best, that lets strangers send messages at your expense. At worst, it can create a deliverability and security incident for your sending domain.
Lovable’s built-in backend is designed for the part of the app that cannot safely run in the browser. Its Edge Functions can make authenticated calls to external services, while project secrets are encrypted and available to those functions without being shipped to visitors’ browsers. That makes an Edge Function the natural place to call Volanea.
The practical architecture looks like this:
- A user completes an action in your Lovable app, such as creating an account.
- Your app calls a small backend function, or your backend triggers the function after the relevant data is written.
- The Edge Function validates the event and reads the Volanea API key from a secret.
- The Edge Function sends a
POSTrequest to Volanea’s email API. - Volanea accepts the message for processing and dispatch.
- Your app records or observes the result so a failed welcome email is not invisible.
This is a deliberately boring pattern, and that is a feature. It does not require adding an email SDK, placing provider credentials in React code, or giving your agent unnecessary freedom to invent a client-side workaround.
The honest state of Volanea and Lovable integration
Lovable can integrate with authenticated external APIs even when they are not presented as a first-party connector. Its documented approach is to use Cloud, project secrets, and an Edge Function for services requiring authentication.
That is the appropriate way to connect Volanea today. Do not assume there is a native Volanea button, a managed OAuth connection, or a dedicated Lovable plugin unless you see one in Lovable’s connector catalog at the time you build. An emerging integration category can be useful without being deeply productized.
The good news is that transactional email is unusually well suited to a generic API integration. The request is compact, the server-side responsibility is clear, and the core behavior is easy to test:
- accept a trusted application event;
- identify the intended recipient;
- render or select the message content;
- call a send endpoint with a private credential;
- return a safe result to the app;
- log failures without leaking email-provider details to end users.
MCP and tool calling may eventually make integrations more conversational. For example, an AI client could use a documented tool to inspect an email API, create a template, or help generate an Edge Function. But that is not necessary for the integration shown here, and it is not a reason to give a tool unrestricted access to production email credentials. A simple, reviewed server-side API call is more dependable than an imagined native integration.
What you need before you prompt Lovable
You can build the function first and add the sending key later, but email delivery cannot work until you complete a few prerequisites. Gather these before asking Lovable to wire up the feature.
A Volanea API key
Create a Volanea secret key for application sending. Keep it private. Do not paste it into a prompt, commit it to a repository, include it in a VITE_ variable, or place it in a frontend configuration file.
Use a clear name in Lovable’s secrets system, such as VOLANEA_API_KEY. A descriptive name makes it easier to audit the function later and helps your coding agent understand what it should request.
A verified sending domain and From address
Your application should send from an address on a verified domain you control, such as hello@updates.example.com or support@example.com. Verification is not cosmetic: it is part of establishing that your app is permitted to send as that domain.
Choose the address based on the message type. A welcome email may come from hello@, while password reset and security messages may be clearer from security@ or support@. Do not use a fake or unmonitored Reply-To address if recipients may reasonably reply.
A real trigger in your app
Decide what product event creates the message. “When the signup button is clicked” is usually too early, because the account creation may fail after the click. Better triggers include:
- after the user account has been successfully created;
- after the email address has been verified, if your onboarding requires verification;
- after a payment provider confirms payment;
- after a server-side password-reset token has been created;
- after a database row changes to a meaningful state, such as
invoice_paid.
For an early prototype, sending immediately after a confirmed signup can be reasonable. For a production app, put the trigger as close as possible to the source of truth for the event. That reduces duplicate sends and prevents an email from promising something the app failed to create.
A minimal email brief
Agents produce better results when you define the product behavior, not merely the provider. Write down the recipient, subject, sender, primary action, fallback text, and success condition.
For a welcome email, that might be:
- Recipient: the authenticated user who just created an account.
- From:
Acme <hello@updates.example.com>. - Subject:
Welcome to Acme. - Primary action: open the user’s dashboard.
- Fallback text: include a plain-text dashboard URL.
- Success condition: the app never reveals the API key, and an email request is made only after successful account creation.
The prompt to give Lovable
Lovable works best when you specify the endpoint, authentication method, headers, request shape, secret name, security constraints, and acceptance criteria. This prevents the agent from guessing at an API integration or taking an unsafe shortcut.
Here is a prompt you can paste into a Lovable project and adapt. Replace the addresses and dashboard URL before using it.
Add a transactional welcome email after a new user successfully signs up.
Use an Edge Function named send-welcome-email. Do not call the email provider from frontend code and do not expose any API key in the browser.
Use the Volanea REST API:
- Base URL: https://api.volanea.com
- Method and path: POST /v1/send
- Authentication: Authorization: Bearer <API key>
- Required header: Content-Type: application/json
- Add an Idempotency-Key header so a retry does not create duplicate welcome emails.
Store the API key as a Cloud secret named VOLANEA_API_KEY. Store the verified sender as VOLANEA_FROM_EMAIL. Ask me to enter both secrets securely; never put their values in source code.
The function should accept a trusted email and optional first name, validate the email, send a welcome message with both HTML and plain-text content, and return only a safe success or error response. Do not return the provider API key or raw provider response to the browser.
Use this sender: Acme <hello@updates.example.com>
Use this dashboard URL: https://app.example.com/dashboard
Subject: Welcome to Acme
Call this function only after account creation succeeds. Add a clear non-blocking UI message if sending fails, and log the server-side error for debugging. Then run backend verification for the function with a test payload.
There are two important details in that prompt. First, it tells Lovable to ask for secrets rather than asking you to paste them into code. Second, it asks for idempotency. Signup workflows can retry because of double-clicks, slow connections, browser refreshes, or backend retries. A duplicate welcome email is not catastrophic, but it is avoidable.
If your project already has authentication, strengthen the prompt further: tell Lovable to derive the recipient from the authenticated user on the server rather than accepting an arbitrary email field from a public browser request. That prevents one signed-in user from using your endpoint to email another address.
The resulting Volanea Edge Function code
Below is an example of the kind of Edge Function Lovable can generate. It uses web-standard fetch, so it does not need a Node-only email package. It also keeps credentials in the function environment and adds an idempotency key tied to the user and event.
This example is intentionally focused on a welcome email. It assumes that your application invokes it only after a successful signup and passes a trusted user identifier along with the email address. In a production app with authentication, ask Lovable to confirm the caller’s identity server-side and derive the email from the authenticated session whenever possible.
// supabase/functions/send-welcome-email/index.ts
const corsHeaders = {
"Access-Control-Allow-Origin": "https://app.example.com",
"Access-Control-Allow-Headers": "authorization, content-type",
"Access-Control-Allow-Methods": "POST, OPTIONS",
};
type WelcomeRequest = {
userId: string;
email: string;
firstName?: string;
};
function escapeHtml(value: string) {
return value
.replaceAll("&", "&")
.replaceAll("<", "<")
.replaceAll(">", ">")
.replaceAll('"', """)
.replaceAll("'", "'");
}
Deno.serve(async (request) => {
if (request.method === "OPTIONS") {
return new Response(null, { headers: corsHeaders });
}
if (request.method !== "POST") {
return Response.json(
{ error: "Method not allowed" },
{ status: 405, headers: corsHeaders },
);
}
try {
const apiKey = Deno.env.get("VOLANEA_API_KEY");
const from = Deno.env.get("VOLANEA_FROM_EMAIL");
if (!apiKey || !from) {
console.error("Volanea email secrets are not configured");
return Response.json(
{ error: "Email service is not configured" },
{ status: 500, headers: corsHeaders },
);
}
const { userId, email, firstName }: WelcomeRequest = await request.json();
const normalizedEmail = email?.trim().toLowerCase();
if (!userId || !normalizedEmail || !/^\S+@\S+\.\S+$/.test(normalizedEmail)) {
return Response.json(
{ error: "A valid user ID and email are required" },
{ status: 400, headers: corsHeaders },
);
}
const name = firstName?.trim() || "there";
const safeName = escapeHtml(name);
const dashboardUrl = "https://app.example.com/dashboard";
const emailResponse = await fetch("https://api.volanea.com/v1/send", {
method: "POST",
headers: {
"Authorization": `Bearer ${apiKey}`,
"Content-Type": "application/json",
"Idempotency-Key": `welcome:${userId}`,
},
body: JSON.stringify({
from,
to: normalizedEmail,
subject: "Welcome to Acme",
html: `
<h1>Welcome to Acme, ${safeName}.</h1>
<p>Your account is ready. Start by opening your dashboard.</p>
<p><a href="${dashboardUrl}">Open your dashboard</a></p>
<p>If you did not create this account, you can ignore this email.</p>
`,
text: `Welcome to Acme, ${name}.\n\nYour account is ready. Open your dashboard: ${dashboardUrl}\n\nIf you did not create this account, you can ignore this email.`,
}),
});
if (!emailResponse.ok) {
const responseText = await emailResponse.text();
console.error("Volanea send failed", {
status: emailResponse.status,
response: responseText,
});
return Response.json(
{ error: "Welcome email could not be sent" },
{ status: 502, headers: corsHeaders },
);
}
return Response.json(
{ ok: true },
{ status: 200, headers: corsHeaders },
);
} catch (error) {
console.error("send-welcome-email failed", error);
return Response.json(
{ error: "Unexpected email error" },
{ status: 500, headers: corsHeaders },
);
}
});
The key material in this code is never hard-coded. Deno.env.get("VOLANEA_API_KEY") reads a secret injected into the backend runtime, and the browser receives only an ok: true result or a safe generic error.
The Idempotency-Key is also intentional. The exact key strategy should match your event model. welcome:${userId} means each user gets no more than one welcome-email request for this workflow. For receipts, use a stable transaction or invoice ID instead. For password resets, use a unique reset-request ID because a user may legitimately request more than one reset email.
Before shipping, compare the request body to the current email API reference and setup guides. API fields and supported sending options can evolve, and a reviewed integration is better than a copied snippet that silently drifts from the provider contract.
Where to call the function after signup
The Edge Function sends email, but it should not become the authority on whether an account exists. Your signup flow remains responsible for creating the account. The email call happens after that succeeds.
In a simple app, Lovable may add a function invocation in the success branch of the signup UI. The frontend can call your backend function with the new user’s data, while the function keeps the Volanea key private.
A minimal client invocation can look like this:
const { error } = await supabase.functions.invoke("send-welcome-email", {
body: {
userId: user.id,
email: user.email,
firstName: profile.first_name,
},
});
if (error) {
console.error("Welcome email request failed", error);
// The account is still created. Show a non-blocking message if needed.
}
This is acceptable for a prototype when your function also authorizes the caller and does not trust arbitrary user-supplied recipient details. For higher-stakes flows, improve the design in one of two ways.
Option one: derive the recipient from the authenticated user
Have the Edge Function validate the incoming authentication token, retrieve the authenticated user on the server, and use that server-derived email address. The browser can then send only optional display data, such as a first name.
This eliminates a common agent-built-app mistake: an endpoint that lets any authenticated visitor submit someone else’s email address and cause your app to send messages to it.
Option two: trigger from the database or backend event
For email tied to a durable business event, let the backend trigger it after the database write commits. A paid invoice, completed order, team invitation, or password-reset token should already have a stable record in your database. Use that record’s ID for the idempotency key and for your delivery audit trail.
The second option takes a little more setup, but it produces cleaner behavior when your app grows. The email workflow becomes repeatable, observable, and separate from a particular button click or browser tab.
Add password resets, receipts, and alerts without rebuilding everything
Once the basic Lovable transactional email pattern works, most application emails are variations on the same design. Do not create a new secret or a new client-side email integration for every message type. Reuse the server-side Volanea connection, but keep each business event explicit.
Password reset emails
Password reset email is security-sensitive. The message must contain a one-time, expiring link generated by your authentication system, not a link assembled from an email address or an easily guessed user ID.
Your agent prompt should say:
- generate the reset token on the server or use your auth provider’s reset flow;
- never expose whether an email address is registered in the product response;
- send the reset link from a security-oriented sender address;
- use a unique reset-request ID as the idempotency key;
- provide a plain-text fallback URL;
- log the request without recording the raw reset token.
The email provider sends the message. It should not be the system deciding whether a reset is authorized.
Receipts and order confirmations
Receipts should be based on finalized transaction data, not values coming directly from the checkout page. If a payment webhook or payment-status update marks an order as paid, that confirmed event should be the trigger.
Include a recognizable order number, total, currency, item summary, support contact, and a durable link to the order details. Consider whether an attachment is actually necessary; a responsive HTML receipt and a hosted invoice page are often simpler than generating PDFs at the moment of payment.
Product alerts and invitations
Alerts work well when their content is concise and their trigger is unambiguous: a task was assigned, a report is ready, an account setting changed, or an invitation was created.
For invitations, do not send a link that grants access forever. Generate an invitation token with an expiry and make the accept flow verify the token on the server. The email should be a transport mechanism for an existing permission model, not the permission model itself.
Templates versus sending HTML from the function
The code example sends the HTML and text directly in the API request. That is useful for a first welcome email because everything is visible in one place. But as your app accumulates messages, inline HTML can become difficult to maintain.
Volanea supports reusable templates with variables resolved at send time. A template approach can separate message content from application logic: your Edge Function selects a template and passes a recipient-specific name, dashboard link, order number, or verification URL.
Use inline content when:
- you are proving the integration with one or two messages;
- the markup is short and tightly coupled to a feature;
- developers own both email content and release cadence;
- you need to iterate quickly during prototyping.
Use templates when:
- several workflows share branding and layout;
- non-engineers need to review message copy;
- localization is planned;
- you need a safer way to edit content without redeploying app code;
- you want consistent headers, sender identity, and footer content.
The important decision is not whether templates are more sophisticated. It is whether you can make a change confidently. For early Lovable projects, start with one well-tested message. Move repeated layout and copy into templates once you have enough repetition to justify it.
Deliverability starts before the first send
A working API call does not guarantee a good inbox experience. Transactional email is part of your product’s trust surface. If a customer cannot find a reset email or sees an unfamiliar sender, the app feels broken even if the database logic is perfect.
Start with sender identity. Use a domain you own, verify it in your email platform, and set up the DNS records the platform provides. Do not guess DNS values or copy records from another provider. Domain verification records are specific to the service and account.
Then make the message recognizable. The visible sender name, From address, subject line, and destination domain should all make sense together. A message titled “Reset your password” from a random-looking address with a button leading to a different domain creates unnecessary suspicion.
A practical transactional-email checklist includes:
- Send from a verified domain you control.
- Keep the From name consistent with your product name.
- Include a useful plain-text version for clients that do not render HTML well.
- Use a stable, product-owned destination domain for action links.
- Include a support route or reply address when the workflow calls for it.
- Do not put secrets, passwords, full payment data, or sensitive personal details in email content.
- Monitor bounces, complaints, and delivery failures instead of assuming every accepted request lands in an inbox.
- Keep marketing consent separate from essential account and security email.
Before importing a larger list of contacts or launching an announcement feature, validate addresses at collection time. A free email address verification tool can help reduce obvious invalid addresses before they become bounces, though verification should complement—not replace—clear consent and proper error handling.
Test the whole workflow, not just the API request
An AI-generated integration can appear complete while still failing at one of several boundaries: a missing secret, an unverified sending domain, a CORS mismatch, an incorrect function invocation, a response that the UI ignores, or a message whose link points to the wrong environment.
Test the entire customer path with a controlled address. Lovable can run backend verification and browser-based checks, so ask it to verify both the function response and the signup journey that calls it.
Use this test sequence:
- Add
VOLANEA_API_KEYandVOLANEA_FROM_EMAILthrough Lovable’s secure secret flow. - Confirm the From address belongs to a verified sending domain in Volanea.
- Invoke the Edge Function with a known test recipient and inspect the function result.
- Confirm the function did not log a secret or return provider details to the browser.
- Complete a real test signup and make sure account creation succeeds even if email delivery has a transient issue.
- Inspect the received message on desktop and mobile.
- Test the primary link in the email and confirm it points to the correct production or preview environment.
- Trigger the same event twice intentionally and confirm your idempotency strategy prevents unwanted duplicates.
- Check the Edge Function logs if the request fails.
Do not test only with your own inbox. Test at least one address on a different mailbox provider before launch. The goal is not to chase a perfect deliverability score from a single message; it is to catch obvious authentication, rendering, sender-identity, and link problems.
Common Lovable transactional email mistakes
The most common failures are architectural, not syntactic. A coding agent can produce a valid HTTP request while still attaching it to the wrong event or exposing more capability than the app needs.
Putting the Volanea key in frontend code
A public browser bundle is not a secret store. Do not accept a solution that uses VITE_VOLANEA_API_KEY, a hard-coded bearer token, a local storage value, or a request directly from the browser to the email provider.
Fix: store the key as a Cloud secret and call Volanea only from an Edge Function.
Trusting an arbitrary recipient address
A function that takes email from the browser without authorization can be misused as a bulk-email endpoint. Validation of email syntax is not authorization.
Fix: derive the recipient from the authenticated user or validate that the caller is allowed to act on the referenced resource. For administrative notifications, check the user’s role on the server.
Making email delivery block the main product event
A customer should not lose a successful signup or payment confirmation just because an email provider is slow for a few seconds. Conversely, you should not mark a critical workflow fully complete if the email itself is the only way a user can proceed.
Fix: decide deliberately. Welcome email can usually be non-blocking. A magic-link login or password reset requires a stronger delivery and retry plan because the email is central to access.
Retrying without idempotency
Retries are healthy. Duplicates are not. A generic retry loop can send multiple welcome emails, receipts, or invitations if it cannot tell whether the previous request was accepted.
Fix: attach an idempotency key based on the durable event ID, and keep your own record of the event state where appropriate.
Treating provider acceptance as inbox placement
A successful API response indicates the sending platform accepted your request. It does not prove that every recipient will see the email in the primary inbox, open it, or click the call to action.
Fix: authenticate the domain, monitor delivery events, make messages recognizable, and provide in-app fallbacks for critical actions.
A sensible path from prototype to production
You do not need enterprise email infrastructure before you send your first welcome email. You do need an upgrade path. The first integration should create a foundation rather than a throwaway shortcut.
For a prototype, one Edge Function, one verified sender, one welcome message, and one test recipient are enough. Keep the code explicit. Ask Lovable to document which action invokes the function and where the secrets live.
For an app with active users, add server-side authorization, durable event IDs, idempotency, function logs, templates, and tests for the top three customer journeys. Those are usually signup, password reset, and payment or order confirmation.
For a growing product, establish ownership. Someone should be able to answer these questions quickly: Which messages are transactional? Which sender addresses are active? Who can change a template? How are delivery failures reviewed? What happens if a sending key is rotated? Which events are safe to retry?
Volanea supports both REST API and SMTP sending, but Lovable’s Edge Function model makes the REST approach particularly straightforward because fetch is available in server-side runtimes. If you later move pieces of your app to a different backend, the same architectural boundary still applies: credentials remain server-side, business events drive messages, and the email provider is called from trusted code.
FAQ
Does Lovable have a native Volanea integration?
Treat Volanea as an authenticated external API integration unless Lovable’s current connector catalog explicitly shows a managed Volanea connector. You can still build the integration quickly with Cloud secrets and an Edge Function.
Can I send Volanea email directly from a Lovable frontend?
No. A browser-based request would expose or misuse the API credential. Send through a Lovable Edge Function so the Volanea API key remains in server-side secrets.
What is the fastest first email to add to a Lovable app?
A welcome email after successful signup is usually the best first workflow. It has a clear trigger, low complexity, and gives you a complete test of secrets, domain verification, API sending, message rendering, and links.
Should a failed welcome email stop signup?
Usually no. Create the account first, then attempt the welcome email as a non-blocking follow-up. Log the failure and provide an in-app onboarding path so the user can continue.
How do I prevent duplicate emails when Lovable retries a function?
Use the Idempotency-Key header with a stable key tied to the relevant business event. For a welcome email, a user ID can work; for a receipt, use an order or invoice ID; for a reset message, use the reset-request ID.