Skip to main content
RapidDev - Software Development Agency
lovable-integrationsEdge Function Integration

How to Integrate Lovable with Mailchimp

To integrate Mailchimp with Lovable, store your Mailchimp API key and server prefix in Cloud → Secrets, then create an Edge Function that calls the Mailchimp Marketing API to add subscribers, manage audience segments, and trigger automations. Unlike SendGrid (for transactional emails), Mailchimp is for email list management and marketing campaigns — the right tool when you need newsletter signups, audience segmentation, and bulk campaign automation.

What you'll learn

  • How to find your Mailchimp API key and server prefix and store them in Lovable Cloud → Secrets
  • How to create an Edge Function that adds subscribers to a Mailchimp audience list
  • How to handle double opt-in confirmation in the Mailchimp subscriber add flow
  • How to trigger Mailchimp automation workflows from a Lovable frontend action
  • When to use Mailchimp versus SendGrid or Lovable Cloud's built-in email for your use case
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate16 min read25 minutesCommunicationMarch 2026RapidDev Engineering Team
TL;DR

To integrate Mailchimp with Lovable, store your Mailchimp API key and server prefix in Cloud → Secrets, then create an Edge Function that calls the Mailchimp Marketing API to add subscribers, manage audience segments, and trigger automations. Unlike SendGrid (for transactional emails), Mailchimp is for email list management and marketing campaigns — the right tool when you need newsletter signups, audience segmentation, and bulk campaign automation.

Add Mailchimp subscriber management to Lovable with an Edge Function proxy

Mailchimp and SendGrid solve different email problems. SendGrid is designed for transactional emails — one event triggers one email to one specific recipient. Mailchimp is designed for email marketing — you build a list of subscribers, segment them by behavior or attributes, and send campaigns or automated sequences to groups of people. If you want a newsletter signup form, a drip email sequence for new users, or the ability to send a promotional campaign to your entire user base, Mailchimp is the right tool.

Lovable does not have a native Mailchimp connector, so the integration flows through an Edge Function. Your React signup or newsletter form calls the Edge Function; the function calls Mailchimp's Marketing API to add the subscriber to your audience list; Mailchimp handles the double opt-in confirmation email (if enabled), list management, and any automation workflows you have configured. This keeps your Mailchimp API key server-side and avoids the CORS errors that would occur if your frontend called Mailchimp directly.

The Mailchimp Marketing API v3 uses a slightly unusual URL pattern: each API request goes to a data-center-specific subdomain. When you create a Mailchimp API key, the last part of it (after the final hyphen) is your server prefix — for example, if your key ends in -us14, your API base URL is https://us14.api.mailchimp.com/3.0/. Getting this server prefix into your secrets separately from the API key is important, as using the wrong data center URL results in a confusing redirect or 401 error. This guide shows you exactly how to find and store both values.

Integration method

Edge Function Integration

Mailchimp has no native Lovable connector. Subscriber management and campaign triggers are handled via a Lovable Edge Function that calls the Mailchimp Marketing API v3. The API key and server prefix (e.g., us14) are stored in Cloud → Secrets and accessed via Deno.env.get(), keeping your credentials server-side and preventing CORS errors from direct browser calls.

Prerequisites

  • A Lovable project with at least one deployed app (Edge Functions require Lovable Cloud)
  • A Mailchimp account (free tier supports up to 500 subscribers and 1,000 emails/month)
  • A Mailchimp Audience (list) already created — go to Audience → All contacts in Mailchimp to find your audience ID
  • Your Mailchimp API key (Account → Extras → API keys → Create A Key) and your server prefix (the datacenter code at the end of your API key, e.g., us14)
  • Basic understanding of the difference between transactional email (one-to-one, triggered) and marketing email (one-to-many, campaign-based)

Step-by-step guide

1

Find your Mailchimp API key, server prefix, and audience list ID

Before adding secrets to Lovable, you need to gather three pieces of information from your Mailchimp account: the API key, the server prefix (data center code), and the audience list ID. To get your API key: in Mailchimp, click your profile icon in the top-right corner, then go to Account → Extras → API keys. Click 'Create A Key'. Give it a name like 'Lovable Integration' and click Generate Key. Mailchimp shows the key once — it looks like xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-us14 where the part after the hyphen is your server prefix. Copy the full key. Your server prefix is the data center code at the end of your API key after the last hyphen. Common values are us1, us2, us10, us14, us17, etc. If your key ends in -us14, your server prefix is us14. This determines which API endpoint you will use: https://us14.api.mailchimp.com/3.0/. Using the wrong prefix is one of the most common Mailchimp API errors. To find your audience list ID: in Mailchimp, go to Audience → All contacts → Settings → Audience name and defaults (or Audience → Manage Audience → Settings). Scroll down to find 'Audience ID' — it is a string like abc123def. Copy this value. If you have multiple audiences, make sure you are in the right one. Keep all three values — API key, server prefix, and audience list ID — ready to paste into Lovable's Secrets panel in the next step.

Pro tip: The server prefix is NOT the same as the datacenter in the API base URL. Your API key is xxxxxxxxxxxx-us14, so your server prefix secret should be 'us14' (without the hyphen). The Edge Function constructs the full URL as https://${serverPrefix}.api.mailchimp.com/3.0/.

Expected result: You have three pieces of information ready: a Mailchimp API key, a server prefix code (e.g., 'us14'), and an audience list ID (e.g., 'abc123def').

2

Add Mailchimp credentials to Lovable Cloud Secrets

Now store your Mailchimp credentials in Lovable's Cloud Secrets panel. These values will be accessed by your Edge Function via Deno.env.get() and must never appear in your frontend code or chat history. In your Lovable project, click the '+' icon at the top of the editor (next to the Preview label) to open the Cloud panel. Click the 'Secrets' tab. Add the following three secrets one at a time by clicking 'Add new secret' for each: First secret — Name: MAILCHIMP_API_KEY, Value: your full Mailchimp API key including the server suffix (e.g., xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-us14). This is used for API authentication via HTTP Basic auth (the username is any string, the password is the API key). Second secret — Name: MAILCHIMP_SERVER_PREFIX, Value: just the data center code extracted from your API key (e.g., us14 without the hyphen). This is used to construct the base URL. Third secret — Name: MAILCHIMP_LIST_ID, Value: your audience list ID from Mailchimp settings (e.g., abc123def). Storing this as a secret lets you change audiences without code changes. With all three secrets saved, your Edge Function will have everything it needs to authenticate and target the correct Mailchimp audience.

Pro tip: If you manage multiple Mailchimp audiences in a single Lovable app, store each list ID as a separate secret: MAILCHIMP_LIST_NEWSLETTER, MAILCHIMP_LIST_CUSTOMERS, etc.

Expected result: MAILCHIMP_API_KEY, MAILCHIMP_SERVER_PREFIX, and MAILCHIMP_LIST_ID appear in your Cloud → Secrets panel with masked values.

3

Create the Mailchimp subscriber Edge Function

Create the Edge Function that adds subscribers to your Mailchimp audience. The function will accept subscriber data from your frontend, authenticate to Mailchimp using HTTP Basic auth (Mailchimp's API uses username:api_key format with base64 encoding), and call the Mailchimp Marketing API's members endpoint. One critical detail: Mailchimp uses MD5 hashes of lowercase email addresses as subscriber IDs in the API. To check if a subscriber already exists or to update an existing subscriber, you would hash their email. For adding new subscribers, you use the POST /lists/{list_id}/members endpoint directly. The status field controls double opt-in behavior. Use 'pending' for the double opt-in flow (Mailchimp sends a confirmation email before adding the subscriber). Use 'subscribed' to add the subscriber directly without confirmation (appropriate when users have already confirmed their email elsewhere, like via Supabase Auth). The status_if_new field on PATCH requests lets you update existing subscribers without changing their opt-in status. The function below also demonstrates how to pass merge fields (Mailchimp's term for custom subscriber data like first name, last name, or any custom fields you have set up in your audience), and how to assign tags to the new subscriber for segmentation.

Lovable Prompt

Create an Edge Function called mailchimp-subscribe at supabase/functions/mailchimp-subscribe/index.ts. It should accept a POST with { email, firstName, lastName, tags, status } where status defaults to 'pending'. Use MAILCHIMP_API_KEY, MAILCHIMP_SERVER_PREFIX, and MAILCHIMP_LIST_ID from Deno environment variables. Call the Mailchimp Marketing API v3 to add the subscriber. Handle the case where the email is already subscribed (Mailchimp returns 400 with title 'Member Exists'). Return success or a clear error message. Include CORS headers.

Paste this in Lovable chat

supabase/functions/mailchimp-subscribe/index.ts
1import { serve } from 'https://deno.land/std@0.168.0/http/server.ts'
2
3const corsHeaders = {
4 'Access-Control-Allow-Origin': '*',
5 'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',
6}
7
8serve(async (req) => {
9 if (req.method === 'OPTIONS') {
10 return new Response('ok', { headers: corsHeaders })
11 }
12
13 try {
14 const { email, firstName = '', lastName = '', tags = [], status = 'pending' } = await req.json()
15
16 const apiKey = Deno.env.get('MAILCHIMP_API_KEY')
17 const serverPrefix = Deno.env.get('MAILCHIMP_SERVER_PREFIX')
18 const listId = Deno.env.get('MAILCHIMP_LIST_ID')
19
20 if (!apiKey || !serverPrefix || !listId) {
21 throw new Error('Missing Mailchimp secrets: MAILCHIMP_API_KEY, MAILCHIMP_SERVER_PREFIX, MAILCHIMP_LIST_ID')
22 }
23
24 if (!email || !email.includes('@')) {
25 return new Response(
26 JSON.stringify({ error: 'Valid email address is required' }),
27 { status: 400, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
28 )
29 }
30
31 const baseUrl = `https://${serverPrefix}.api.mailchimp.com/3.0`
32 const authHeader = 'Basic ' + btoa(`anystring:${apiKey}`)
33
34 const memberData: Record<string, unknown> = {
35 email_address: email,
36 status,
37 merge_fields: {
38 FNAME: firstName,
39 LNAME: lastName,
40 },
41 }
42
43 if (tags.length > 0) {
44 memberData.tags = tags
45 }
46
47 const response = await fetch(`${baseUrl}/lists/${listId}/members`, {
48 method: 'POST',
49 headers: {
50 Authorization: authHeader,
51 'Content-Type': 'application/json',
52 },
53 body: JSON.stringify(memberData),
54 })
55
56 const data = await response.json()
57
58 // Handle 'Member Exists' gracefully
59 if (!response.ok) {
60 if (data.title === 'Member Exists') {
61 return new Response(
62 JSON.stringify({ success: true, message: 'Already subscribed' }),
63 { headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
64 )
65 }
66 throw new Error(`Mailchimp API error: ${data.title || data.detail || response.status}`)
67 }
68
69 return new Response(
70 JSON.stringify({ success: true, id: data.id, status: data.status }),
71 { headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
72 )
73 } catch (error) {
74 return new Response(
75 JSON.stringify({ error: error.message }),
76 { status: 500, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
77 )
78 }
79})

Pro tip: Mailchimp's HTTP Basic auth format is unusual — the username can be any string (Mailchimp ignores it), and the password is your API key. The btoa() function in Deno handles the base64 encoding required for Basic auth.

Expected result: The mailchimp-subscribe Edge Function is deployed and visible in Cloud → Edge Functions. It accepts POST requests with subscriber data and adds members to your Mailchimp audience.

4

Add the newsletter signup form to your Lovable frontend

With the Edge Function deployed, create the user-facing signup form in your Lovable app. The form collects the subscriber's information and calls the Edge Function via supabase.functions.invoke(). A good newsletter signup form includes at minimum an email field, and optionally first name, last name, and any custom segments (e.g., a checkbox for the type of content they want). The form should handle three states: idle (default), loading (while the Edge Function runs), and success (after successful subscription). If the subscriber is already in your list, show a friendly message rather than an error. Consider whether to use double opt-in (status: 'pending') or single opt-in (status: 'subscribed'). Double opt-in is better for list quality and compliance with GDPR and CAN-SPAM — Mailchimp sends a confirmation email, and only confirmed subscribers enter your active list. Single opt-in gives higher signup conversion but may include more invalid or mistyped addresses. For most cases, double opt-in with a clear 'Check your email to confirm' message is the right default. After the form successfully calls the Edge Function, show a clear success state explaining what happens next — for double opt-in, tell users to check their inbox for a confirmation email from Mailchimp.

Lovable Prompt

Add a newsletter signup section to my homepage with an email input and a 'Subscribe' button. When submitted, call the mailchimp-subscribe Edge Function with the email address and status 'pending'. Show a loading spinner during the request. On success, show 'Thanks! Check your email to confirm your subscription.' On error, show a friendly error message. Handle the 'already subscribed' case with a message like 'You are already on the list!'

Paste this in Lovable chat

src/components/NewsletterSignup.tsx
1import { useState } from 'react'
2import { supabase } from '@/lib/supabase'
3import { Button } from '@/components/ui/button'
4import { Input } from '@/components/ui/input'
5import { toast } from '@/components/ui/use-toast'
6
7export const NewsletterSignup = () => {
8 const [email, setEmail] = useState('')
9 const [loading, setLoading] = useState(false)
10 const [subscribed, setSubscribed] = useState(false)
11
12 const handleSubmit = async (e: React.FormEvent) => {
13 e.preventDefault()
14 setLoading(true)
15
16 try {
17 const { data, error } = await supabase.functions.invoke('mailchimp-subscribe', {
18 body: { email, status: 'pending' },
19 })
20
21 if (error) throw error
22
23 if (data?.message === 'Already subscribed') {
24 toast({ title: 'You are already on the list!', description: 'Check your inbox for our latest emails.' })
25 } else {
26 setSubscribed(true)
27 }
28 } catch (err) {
29 toast({
30 title: 'Subscription failed',
31 description: 'Please check your email address and try again.',
32 variant: 'destructive',
33 })
34 } finally {
35 setLoading(false)
36 }
37 }
38
39 if (subscribed) {
40 return (
41 <div className="text-center py-8">
42 <p className="text-lg font-medium">Thanks for subscribing!</p>
43 <p className="text-muted-foreground mt-2">Check your email to confirm your subscription.</p>
44 </div>
45 )
46 }
47
48 return (
49 <form onSubmit={handleSubmit} className="flex gap-2 max-w-md mx-auto">
50 <Input
51 type="email"
52 placeholder="Enter your email"
53 value={email}
54 onChange={(e) => setEmail(e.target.value)}
55 required
56 />
57 <Button type="submit" disabled={loading}>
58 {loading ? 'Subscribing...' : 'Subscribe'}
59 </Button>
60 </form>
61 )
62}

Pro tip: For GDPR compliance, add a checkbox or link to your privacy policy near the subscribe button, and explicitly state what subscribers will receive. Mailchimp's double opt-in handles the technical compliance, but the UI should set expectations clearly.

Expected result: The newsletter signup form appears on your page. When a visitor enters their email and submits, they receive a Mailchimp confirmation email. After confirming, they appear as 'Subscribed' in your Mailchimp Audience → All contacts list.

Common use cases

Add newsletter subscribers from a landing page signup form

Build a landing page in Lovable with an email signup form. When a visitor submits their email, the Edge Function adds them to your Mailchimp audience with the 'pending' status for double opt-in confirmation. Mailchimp sends the confirmation email automatically, and when confirmed, Mailchimp adds them to the active subscriber list and triggers any welcome automations you have configured.

Lovable Prompt

Create an Edge Function called mailchimp-subscribe that accepts a POST with { email, firstName, lastName } and adds the subscriber to my Mailchimp audience list using MAILCHIMP_API_KEY and MAILCHIMP_SERVER_PREFIX from secrets. The list ID is MAILCHIMP_LIST_ID from secrets. Use pending status for double opt-in. Return success or error. Then add a newsletter signup form to my landing page that calls this function.

Copy this prompt to try it in Lovable

Sync new Lovable users to a Mailchimp onboarding sequence

When a user registers for your Lovable app via Supabase Auth, automatically add them to a Mailchimp audience and tag them as 'new-user'. This triggers a Mailchimp automation sequence — a welcome email on day 1, a feature highlight on day 3, a tips email on day 7. The user onboarding experience runs on Mailchimp without your team manually managing the sequence.

Lovable Prompt

After a user successfully signs up on my Lovable app with Supabase Auth, call the Mailchimp Marketing API to add them to my audience list with tags ['new-user', 'app-signup'] and merge fields for FNAME and LNAME. Use subscribed status (not pending since they already confirmed their email via Supabase Auth). Store API key and server prefix in secrets.

Copy this prompt to try it in Lovable

Trigger a Mailchimp automation when a user upgrades their plan

When a user upgrades from a free plan to a paid plan in your Lovable app, update their Mailchimp subscriber record with the new plan tag and trigger a 'new-paid-user' automation sequence. This could be a congratulations email, a getting-started guide for premium features, or a receipt with their subscription details.

Lovable Prompt

Create an Edge Function that updates an existing Mailchimp subscriber's tags when called. It should accept { email, addTags, removeTags } and use the Mailchimp API to add the 'paid-plan' tag and remove the 'free-plan' tag from the subscriber's record. Call this from my plan upgrade success handler.

Copy this prompt to try it in Lovable

Troubleshooting

Mailchimp API returns 401 Unauthorized with 'API Key Invalid' error

Cause: The API key stored in MAILCHIMP_API_KEY is incorrect, expired, or the server prefix in the URL does not match the actual data center of the API key.

Solution: Go to Cloud → Secrets and verify MAILCHIMP_API_KEY contains your full API key including the server suffix (e.g., xxxxxxxx-us14). Also verify that MAILCHIMP_SERVER_PREFIX contains only the data center code (e.g., us14) without the hyphen. You can regenerate a new API key in Mailchimp → Account → Extras → API keys and update the secret. Remember to redeploy the Edge Function after updating secrets.

Mailchimp API returns 400 with 'Invalid Resource' or the audience has no new members after subscribing

Cause: The MAILCHIMP_LIST_ID secret contains the wrong audience ID, or the audience ID format is incorrect (it should be an alphanumeric string like abc123def, not the audience name).

Solution: In Mailchimp, go to Audience → All contacts → Settings (gear icon) → Audience name and defaults. Scroll to find the 'Audience ID' field — it is an 8-10 character alphanumeric code. Copy this exact value and update MAILCHIMP_LIST_ID in Cloud → Secrets. Do not use the audience name (e.g., 'My Newsletter') — only the ID works in API calls.

Double opt-in confirmation emails are going to spam or not arriving

Cause: Mailchimp's confirmation emails come from Mailchimp's servers on behalf of your audience, and new Mailchimp accounts have lower sender reputation until the domain and email are verified.

Solution: In Mailchimp, go to Audience → Settings → Required email footer content and ensure your organization's physical address is filled in (required by CAN-SPAM). Also verify your sending domain at Account → Domains — a verified domain significantly improves confirmation email deliverability. For testing, use a real email address you control and check both inbox and spam. If issues persist, consider using Mailchimp's email design tools to create a clear, non-spammy confirmation email template.

Edge Function returns 'Missing Mailchimp secrets' error even after adding all three secrets

Cause: Edge Functions in Lovable need to be redeployed after new secrets are added — they do not automatically pick up secrets added after their last deployment.

Solution: Trigger a redeployment by asking Lovable in chat to 'add a code comment to the mailchimp-subscribe Edge Function and redeploy it'. Any code change, even a trivial comment, triggers a fresh deployment that picks up all current secrets.

Best practices

  • Use double opt-in (status: 'pending') for all marketing list signups to maintain list quality and comply with GDPR and CAN-SPAM regulations — confirmed subscribers have higher engagement rates and lower spam complaints.
  • Store MAILCHIMP_LIST_ID as a secret rather than hardcoding it, so you can point different environments (development, staging, production) at different Mailchimp audiences without code changes.
  • Always handle the 'Member Exists' case gracefully in your Edge Function — returning a friendly 'already subscribed' message rather than an error prevents frustrating user experiences for people who sign up multiple times.
  • Use Mailchimp tags to segment subscribers by source or behavior (e.g., 'landing-page', 'app-signup', 'paid-user') so you can send targeted campaigns to specific groups later.
  • Never use Mailchimp for transactional emails like order confirmations and password resets — Mailchimp's delivery infrastructure is optimized for marketing email, not triggered transactional email. Use SendGrid or Mailgun for those use cases.
  • Set up Mailchimp's webhook feature (Audience → Settings → Webhooks) to receive notifications when subscribers unsubscribe, so you can sync that status back to your Supabase database.
  • Test your subscription flow using Mailchimp's test mode or a personal email address before exposing the signup form to real users — verify that confirmation emails arrive, that tagging works correctly, and that existing subscribers are handled gracefully.

Alternatives

Frequently asked questions

What is the difference between using Mailchimp and using SendGrid from Lovable?

Mailchimp is for email marketing and list management — you maintain a subscriber list, send campaigns to groups of people, and set up automation sequences. SendGrid is for transactional email — you send one email to one specific person in response to a specific event (welcome, receipt, notification). For a typical Lovable app, you might use both: SendGrid for transactional emails triggered by Supabase events, and Mailchimp for marketing newsletters and drip campaigns to your subscriber list.

Does Mailchimp's free tier work for a Lovable production app?

Mailchimp's free tier allows up to 500 subscribers and 1,000 email sends per month, which is workable for early-stage apps. Once you exceed 500 subscribers, you need a paid plan starting at around $13/month for up to 500 contacts with 5,000 emails/month. The free tier also has Mailchimp branding in emails and limited automation capabilities, so factor that into your decision.

How do I make sure my Mailchimp signup is GDPR compliant?

GDPR compliance requires explicit consent and clear disclosure of what subscribers are signing up for. Use double opt-in (status: 'pending') so subscribers actively confirm their intent. Add a clear description of what they will receive near the signup form. Include a link to your privacy policy. Make sure your Mailchimp audience has a physical mailing address configured (required by both CAN-SPAM and GDPR). Mailchimp provides GDPR-specific form fields and consent tracking in Audience → Signup Forms → Form Builder.

Can I trigger a Mailchimp campaign from my Lovable app?

You can trigger Mailchimp automations (automated email sequences set up in Mailchimp) by adding a subscriber to a specific segment or applying a specific tag. Directly scheduling or sending a campaign via the Mailchimp API is also possible using the /campaigns endpoint, but it requires additional API calls for campaign creation, content setup, and send scheduling — a more complex Edge Function. For simple automation triggers, adding a tag to a subscriber is the simpler approach.

What happens if a user tries to subscribe with an email that is already on the list?

Mailchimp returns a 400 error with the title 'Member Exists' when you try to add an already-subscribed email. The Edge Function code in this guide handles this case by returning a success response with message 'Already subscribed', so your UI can show a friendly 'You are already on the list!' message instead of an error. This is the recommended pattern rather than pre-checking for existing subscribers with a separate API call.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.