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

How to Integrate Lovable with Campaign Monitor

To integrate Campaign Monitor with Lovable, store your Campaign Monitor API key in Cloud → Secrets and create an Edge Function that proxies calls to the Campaign Monitor API. Campaign Monitor is the design-first email platform — its template builder produces agency-quality emails that render perfectly across every email client. Unlike Brevo which focuses on combined transactional and marketing capability, Campaign Monitor is the right choice when beautiful, brand-consistent email design is the primary requirement.

What you'll learn

  • How to find your Campaign Monitor API key and list ID and store them in Lovable Cloud → Secrets
  • How to create an Edge Function that adds subscribers to a Campaign Monitor list with custom fields
  • How to handle subscriber resubscription and existing contact updates via the Campaign Monitor API
  • How to wire a Lovable signup form to call the Campaign Monitor Edge Function
  • When to choose Campaign Monitor over Brevo or Constant Contact for design-focused email marketing
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate16 min read25 minutesMarketingMarch 2026RapidDev Engineering Team
TL;DR

To integrate Campaign Monitor with Lovable, store your Campaign Monitor API key in Cloud → Secrets and create an Edge Function that proxies calls to the Campaign Monitor API. Campaign Monitor is the design-first email platform — its template builder produces agency-quality emails that render perfectly across every email client. Unlike Brevo which focuses on combined transactional and marketing capability, Campaign Monitor is the right choice when beautiful, brand-consistent email design is the primary requirement.

Integrate Campaign Monitor subscriber management into Lovable with a design-first approach

Campaign Monitor built its reputation on one thing: emails that look exactly as designed across every email client, every device, and every dark mode setting. Its template builder has been a reference standard for email design quality since before responsive email was common, and agencies worldwide use it to manage client email programs where brand consistency is non-negotiable. If your Lovable app serves clients or industries where professional email design directly impacts brand perception — real estate, fashion, professional services, luxury products — Campaign Monitor is worth the premium over simpler platforms.

Lovable does not have a native Campaign Monitor connector. Subscriber management flows through an Edge Function that calls the Campaign Monitor API. Your React form collects subscriber data, the Edge Function adds the subscriber to a Campaign Monitor list using HTTP Basic auth with your API key, and Campaign Monitor handles list management, segmentation, and campaign delivery. Custom fields let you pass additional data alongside the email address — source URL, signup date, plan tier, or any other attribute you want to use for segmentation in Campaign Monitor.

Campaign Monitor's API uses simple HTTP Basic auth where the username is your API key and the password can be any string. List IDs are long alphanumeric strings visible in the URL when you view a list in the Campaign Monitor interface. This guide covers finding both values, storing them as secrets, building the Edge Function, and connecting it to a Lovable frontend form.

Integration method

Edge Function Integration

Campaign Monitor has no native Lovable connector. Subscriber management, list operations, and custom field mapping are handled via a Lovable Edge Function that calls the Campaign Monitor API. The API key is stored in Cloud → Secrets and accessed via Deno.env.get(), keeping credentials server-side and avoiding the CORS errors that result from direct browser calls to the Campaign Monitor API.

Prerequisites

  • A Lovable project with Lovable Cloud enabled (Edge Functions require Lovable Cloud)
  • A Campaign Monitor account — paid plans start at $9/month for basic email marketing (campaignmonitor.com)
  • Your Campaign Monitor API key (Account Settings → API Keys → Generate API key)
  • A Campaign Monitor subscriber list already created — note the list ID from the URL when viewing the list
  • Optionally: custom fields configured in your Campaign Monitor list settings if you plan to pass additional data

Step-by-step guide

1

Get your Campaign Monitor API key and list ID

Gather the two key values you need from Campaign Monitor before building the integration: the API key and the subscriber list ID. To get your API key: log in to Campaign Monitor and click your account name in the top-right corner. Go to Account Settings, then look for the 'API keys' section (sometimes listed under 'Developer' or 'Integrations' depending on your plan level). Click 'Generate API key' or copy an existing key. Campaign Monitor API keys are long alphanumeric strings. This key goes in the HTTP Basic auth username field — the password can be literally any string (Campaign Monitor ignores it). To find your list ID: in Campaign Monitor, navigate to Lists & subscribers. Click on the list you want to use. Look at the browser URL when you are on the list overview page — the list ID is the long alphanumeric string in the URL path. It looks like a 30-40 character string mixing letters and numbers. Copy this entire string — it is your list ID. Optionally, if you have custom fields on your list (or want to add them): go to your list → Settings → Custom fields. Note the exact names of any custom fields you have configured. Custom field names are case-sensitive in the Campaign Monitor API, and using the wrong case in your API calls results in the custom field being silently ignored. Have both your API key and list ID ready before moving to the next step.

Pro tip: Campaign Monitor list IDs are significantly longer than those of other email platforms — they are typically 32+ character alphanumeric strings. Double-check that you copied the full ID from the URL when retrieving it, as truncating it results in a 400 error with a 'List does not exist' message.

Expected result: You have a Campaign Monitor API key and a full list ID (32+ character alphanumeric string from the list URL) ready to store as secrets.

2

Add Campaign Monitor credentials to Lovable Cloud Secrets

Store your Campaign Monitor credentials in Lovable's Cloud Secrets panel. Navigate to your Lovable project and click the '+' icon at the top of the editor to open the Cloud panel. Click the 'Secrets' tab and add the following secrets. First secret — Name: CAMPAIGN_MONITOR_API_KEY, Value: your full Campaign Monitor API key. Campaign Monitor uses HTTP Basic auth where the API key is the username and any non-empty string is the password. The Edge Function constructs the auth header by base64-encoding 'api-key:x' where 'api-key' is replaced with your actual key and 'x' is an arbitrary password string. Second secret — Name: CAMPAIGN_MONITOR_LIST_ID, Value: the full list ID copied from the Campaign Monitor list URL. This is a long alphanumeric string — make sure to include the complete value. After saving both secrets, the Edge Function will have everything it needs to authenticate and add subscribers to your Campaign Monitor list. The HTTP Basic auth pattern for Campaign Monitor is unusual — unlike most APIs, the password portion of the Basic auth credentials is completely ignored. Only the API key (in the username position) matters for authentication.

Pro tip: Campaign Monitor HTTP Basic auth base64-encodes 'your-api-key:any-password'. The standard convention is to use 'x' as the password value (e.g., btoa('apikey123:x')). The 'x' placeholder is visible in the code but does not need to be a secret — only the API key is sensitive.

Expected result: CAMPAIGN_MONITOR_API_KEY and CAMPAIGN_MONITOR_LIST_ID appear in your Cloud → Secrets panel with values masked.

3

Create the Campaign Monitor subscriber Edge Function

Create the Edge Function that manages subscribers in Campaign Monitor. The Campaign Monitor API v3.3 uses a REST-style endpoint where the list ID is embedded in the URL path: POST https://api.createsend.com/api/v3.3/subscribers/{listID}.json. The subscriber payload for new signups includes: EmailAddress (required), Name (optional), CustomFields (optional array of { Key, Value } objects), and Resubscribe (boolean — when true, if the email is unsubscribed in Campaign Monitor, the API will resubscribe them). Setting Resubscribe to true is the appropriate default for opt-in forms where the user has explicitly chosen to sign up again. The API uses HTTP Basic auth with the base64-encoded combination of your API key and a placeholder password. In Deno, the btoa() function handles the base64 encoding. The Authorization header format is 'Basic base64(api_key:x)'. Campaign Monitor returns 201 Created for successful new subscriber additions, and 200 for resubscriptions or existing subscriber updates. The response body for successful requests is just a string with the subscriber's email address. Error responses return JSON with Code and Message fields. The function below handles subscriber creation with optional custom fields and graceful handling of the 'already subscribed' case.

Lovable Prompt

Create an Edge Function called campaign-monitor-subscribe at supabase/functions/campaign-monitor-subscribe/index.ts. It accepts { email, name, customFields } where customFields is an optional array of { Key, Value } objects. Use CAMPAIGN_MONITOR_API_KEY and CAMPAIGN_MONITOR_LIST_ID from Deno env. Authenticate via HTTP Basic auth: btoa(apiKey + ':x'). Call POST https://api.createsend.com/api/v3.3/subscribers/{listID}.json with Resubscribe: true. Include CORS headers and return success or error.

Paste this in Lovable chat

supabase/functions/campaign-monitor-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, name = '', customFields = [] } = await req.json()
15
16 const apiKey = Deno.env.get('CAMPAIGN_MONITOR_API_KEY')
17 const listId = Deno.env.get('CAMPAIGN_MONITOR_LIST_ID')
18
19 if (!apiKey || !listId) {
20 throw new Error('Missing required secrets: CAMPAIGN_MONITOR_API_KEY and CAMPAIGN_MONITOR_LIST_ID')
21 }
22 if (!email || !email.includes('@')) {
23 return new Response(
24 JSON.stringify({ error: 'A valid email address is required' }),
25 { status: 400, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
26 )
27 }
28
29 // Campaign Monitor uses HTTP Basic auth: base64(apiKey:x)
30 const authHeader = 'Basic ' + btoa(`${apiKey}:x`)
31
32 const payload: Record<string, unknown> = {
33 EmailAddress: email,
34 Name: name,
35 Resubscribe: true,
36 ConsentToTrack: 'Yes',
37 }
38
39 if (customFields.length > 0) {
40 payload.CustomFields = customFields
41 }
42
43 const response = await fetch(
44 `https://api.createsend.com/api/v3.3/subscribers/${listId}.json`,
45 {
46 method: 'POST',
47 headers: {
48 Authorization: authHeader,
49 'Content-Type': 'application/json',
50 },
51 body: JSON.stringify(payload),
52 }
53 )
54
55 if (!response.ok) {
56 const errorData = await response.json()
57 throw new Error(`Campaign Monitor API error ${response.status}: ${errorData.Message || JSON.stringify(errorData)}`)
58 }
59
60 return new Response(
61 JSON.stringify({ success: true, message: 'Subscriber added successfully' }),
62 { headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
63 )
64 } catch (error) {
65 return new Response(
66 JSON.stringify({ error: error.message }),
67 { status: 500, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
68 )
69 }
70})

Pro tip: The ConsentToTrack field is required by Campaign Monitor for GDPR and privacy compliance. Accepted values are 'Yes', 'No', or 'Unchanged'. For opt-in forms where users have explicitly agreed to receive emails, use 'Yes'. Omitting this field may cause 400 errors on accounts with strict consent settings enabled.

Expected result: The campaign-monitor-subscribe Edge Function is deployed. Test it with your own email address — you should appear as an active subscriber in your Campaign Monitor list within seconds.

4

Build the Lovable signup form and wire it to the Edge Function

With the Edge Function deployed, build the subscriber signup form in your Lovable app and connect it to the Edge Function using supabase.functions.invoke(). Campaign Monitor is frequently used by brands and agencies where form aesthetics matter as much as functionality. Your Lovable signup form should reflect the same design quality that Campaign Monitor brings to email — use shadcn/ui components, Tailwind spacing, and a minimal, on-brand layout. The form should feel like a natural extension of the email campaigns subscribers will receive. Beyond the basic email and name fields, consider adding a campaign source indicator. When you know where a subscriber came from — a specific landing page, a blog post, a referral source — you can pass this as a custom field to Campaign Monitor and use it for segmentation in future campaigns. The custom field name must exactly match a field configured in your Campaign Monitor list settings. After submission, show a clear success state that sets expectations: tell subscribers what they will receive and when. For a design-focused brand, this confirmation message is also an opportunity to reinforce your brand voice and values — keep it on-brand rather than a generic 'You are subscribed!' message.

Lovable Prompt

Add a subscriber signup section to my page with fields for name and email. Style it cleanly with shadcn/ui components. When submitted, call the campaign-monitor-subscribe Edge Function with the email, name, and a customFields array containing { Key: 'SignupSource', Value: 'homepage' }. Show a loading state and success message in your brand's tone. Handle errors gracefully with a retry message.

Paste this in Lovable chat

src/components/CMSignupForm.tsx
1import { useState } from 'react'
2import { supabase } from '@/lib/supabase'
3import { Button } from '@/components/ui/button'
4import { Input } from '@/components/ui/input'
5import { Label } from '@/components/ui/label'
6import { toast } from '@/components/ui/use-toast'
7
8export const CMSignupForm = () => {
9 const [email, setEmail] = useState('')
10 const [name, setName] = useState('')
11 const [loading, setLoading] = useState(false)
12 const [subscribed, setSubscribed] = useState(false)
13
14 const handleSubmit = async (e: React.FormEvent) => {
15 e.preventDefault()
16 setLoading(true)
17 try {
18 const { error } = await supabase.functions.invoke('campaign-monitor-subscribe', {
19 body: {
20 email,
21 name,
22 customFields: [{ Key: 'SignupSource', Value: 'homepage' }],
23 },
24 })
25 if (error) throw error
26 setSubscribed(true)
27 } catch (err) {
28 toast({
29 title: 'Something went wrong',
30 description: 'Please try again or contact us directly.',
31 variant: 'destructive',
32 })
33 } finally {
34 setLoading(false)
35 }
36 }
37
38 if (subscribed) {
39 return (
40 <div className="py-8 text-center space-y-2">
41 <p className="font-semibold text-lg">You're on the list.</p>
42 <p className="text-muted-foreground text-sm">Expect beautiful things in your inbox soon.</p>
43 </div>
44 )
45 }
46
47 return (
48 <form onSubmit={handleSubmit} className="space-y-4 max-w-sm">
49 <div>
50 <Label htmlFor="name">Name</Label>
51 <Input id="name" value={name} onChange={(e) => setName(e.target.value)} placeholder="Your name" />
52 </div>
53 <div>
54 <Label htmlFor="email">Email *</Label>
55 <Input id="email" type="email" value={email} onChange={(e) => setEmail(e.target.value)} placeholder="you@example.com" required />
56 </div>
57 <Button type="submit" disabled={loading} className="w-full">
58 {loading ? 'Subscribing...' : 'Subscribe'}
59 </Button>
60 </form>
61 )
62}

Expected result: The signup form is live. When a visitor submits, they appear as an active subscriber in Campaign Monitor → Lists & subscribers → your list, with the custom field SignupSource set to 'homepage'.

Common use cases

Add subscribers to a Campaign Monitor list from a brand landing page

Build a visually polished landing page in Lovable. When a visitor enters their email and submits, the Edge Function adds them to a Campaign Monitor list with custom fields like source page and signup date. Campaign Monitor then delivers your designed welcome campaign sequence with the pixel-perfect rendering the platform is known for.

Lovable Prompt

Create an Edge Function called campaign-monitor-subscribe that accepts { email, name, customFields } and adds the subscriber to my Campaign Monitor list CAMPAIGN_MONITOR_LIST_ID using HTTP Basic auth with CAMPAIGN_MONITOR_API_KEY. The custom fields should include Source and SignupDate. Use the CM API endpoint POST /api/v3.3/subscribers/{listId}.json. Include CORS headers and return success or descriptive error.

Copy this prompt to try it in Lovable

Sync agency client signups to separate Campaign Monitor lists

If you manage multiple brands or clients with your Lovable app, the Edge Function can route subscribers to different Campaign Monitor lists based on which brand's form they submitted. Each list ID is stored as a separate secret, and the form passes a 'brand' parameter to the Edge Function to determine which list to add the subscriber to.

Lovable Prompt

Create an Edge Function that routes newsletter subscribers to different Campaign Monitor lists based on a 'brand' parameter in the request. If brand='acme', use CAMPAIGN_MONITOR_ACME_LIST_ID. If brand='brand2', use CAMPAIGN_MONITOR_BRAND2_LIST_ID. Add the subscriber with their email and name using CAMPAIGN_MONITOR_API_KEY. Return success with the list the subscriber was added to.

Copy this prompt to try it in Lovable

Pass custom field data for subscriber segmentation

Campaign Monitor supports custom fields on subscriber records, which are used for segmenting campaigns. From your Lovable app, pass additional data like user plan tier, industry, or geographic region as custom fields when adding a subscriber. This enables sending targeted campaigns to specific subscriber segments directly from Campaign Monitor without any additional code changes.

Lovable Prompt

Extend the campaign-monitor-subscribe Edge Function to accept a customFields object in the request body and pass it to Campaign Monitor's custom fields array. The fields should include UserType (e.g., 'free' or 'paid'), SignupSource (the page URL), and Country. Map each key-value pair to Campaign Monitor's customFields format: [{ Key: 'UserType', Value: 'free' }]. Validate that custom field names match the fields configured in my Campaign Monitor list.

Copy this prompt to try it in Lovable

Troubleshooting

Campaign Monitor API returns 401 Unauthorized

Cause: The HTTP Basic auth credentials are being encoded incorrectly, or the API key stored in CAMPAIGN_MONITOR_API_KEY is wrong. Campaign Monitor Basic auth requires base64-encoding of 'api-key:any-string' — if the key has special characters, they must be included in the base64 encoding.

Solution: Verify the CAMPAIGN_MONITOR_API_KEY in Cloud → Secrets is your exact API key from Campaign Monitor Account Settings → API Keys. The Edge Function encodes it as btoa(apiKey + ':x'). Check that there are no extra spaces in the secret value. Regenerate the API key in Campaign Monitor if needed and update the secret.

API returns 400 with 'List does not exist' error

Cause: The CAMPAIGN_MONITOR_LIST_ID is incorrect or truncated. Campaign Monitor list IDs are long alphanumeric strings (32+ characters) and are easy to accidentally truncate when copying from the URL.

Solution: Go to Campaign Monitor → Lists & subscribers → select your list → look at the browser URL. Copy the full list ID string — every character matters. Update CAMPAIGN_MONITOR_LIST_ID in Cloud → Secrets with the complete value. You can also retrieve list IDs via the API endpoint GET https://api.createsend.com/api/v3.3/clients/{clientId}/lists.json.

Custom fields are not appearing on subscriber records in Campaign Monitor

Cause: The custom field Key values in the API call do not exactly match the field names configured in Campaign Monitor list settings. Custom field names are case-sensitive.

Solution: Go to Campaign Monitor → your list → Settings → Custom fields. Note the exact names of your custom fields including their capitalization. Update your Edge Function or the customFields array in the frontend to use exactly matching Key values. If the field 'SignupSource' is configured in Campaign Monitor but you are sending 'signupSource' or 'Signup Source', the field will be silently ignored.

CORS error in the browser when the form submits

Cause: The frontend React component is making a direct call to the Campaign Monitor API URL instead of calling the Lovable Edge Function, or the Edge Function is missing the CORS preflight handler.

Solution: Confirm your frontend calls supabase.functions.invoke('campaign-monitor-subscribe', ...) and not a direct fetch to api.createsend.com. The Campaign Monitor API does not support direct browser calls due to CORS restrictions. The Edge Function acts as a server-side proxy to bypass this. Verify the Edge Function includes the OPTIONS handler returning corsHeaders.

Best practices

  • Always include ConsentToTrack: 'Yes' in your subscriber payload for opt-in forms — this is required for GDPR compliance and some Campaign Monitor accounts have it enforced at the account level.
  • Set Resubscribe: true in your subscriber payload to handle the common case of users who previously unsubscribed trying to sign up again — this allows them to resubscribe via your form rather than getting a confusing error.
  • Use custom fields to pass signup source information (which page, which campaign, which date) so you can segment subscribers by acquisition channel in Campaign Monitor campaign targeting.
  • Store the list ID as a secret rather than hardcoding it so you can point to a different Campaign Monitor list (e.g., staging vs production) by changing a secret value without code changes.
  • For multi-brand or agency use cases, create one Edge Function that accepts a list ID parameter from the frontend rather than separate functions per brand — validate that the passed list ID matches one of your known secret values to prevent injection.
  • Test email rendering in Campaign Monitor's preview tool after setting up your welcome campaign — Campaign Monitor's core value is rendering quality, so make sure your campaign design looks as intended before sending to real subscribers.
  • For complex subscriber management requirements like webhook-based unsubscribe sync, custom segmentation logic, or multi-account agency setups, RapidDev's team can help architect a robust Campaign Monitor integration.

Alternatives

Frequently asked questions

Does Campaign Monitor have a free plan?

Campaign Monitor does not offer a permanent free plan. They have a 'pay per campaign' option where you pay per send rather than a monthly subscription, which can work well for low-frequency sending. Monthly plans start at $9/month for basic features. The API is available on all paid plans. For testing the integration, Campaign Monitor allows test sends to your own email address during the trial period.

What makes Campaign Monitor better than Mailchimp for agency clients?

Campaign Monitor was designed for agencies managing multiple client accounts. Its multi-client account structure, white-label branding options, and superior template rendering quality make it the preferred choice for professional email marketers who need consistent results across hundreds of clients. Campaign Monitor's email template builder produces cleaner HTML that renders more reliably across Outlook, Gmail, Apple Mail, and other email clients than most competitors.

Can I create and send email campaigns from the Lovable integration?

The Campaign Monitor API supports creating and sending campaigns programmatically via the /campaigns endpoint, but this is typically more than needed for a Lovable integration. The most practical use case is using Lovable to collect subscribers and manage the contact list, while creating and sending email campaigns directly in the Campaign Monitor dashboard where the design tools are. Programmatic campaign sending from Lovable Edge Functions is feasible but adds significant complexity.

How do I set up Campaign Monitor webhook notifications for unsubscribes?

Campaign Monitor can notify your Lovable app when subscribers unsubscribe, bounce, or change their status via webhooks. In Campaign Monitor → your list → Settings → Webhooks, add a new webhook pointing to a separate Lovable Edge Function URL. Configure it to fire on subscribe, unsubscribe, bounce, and spam complaint events. The Edge Function should update a 'subscribed' flag in your Supabase database so your app respects opt-out preferences.

What is ConsentToTrack and do I need to include it?

ConsentToTrack tells Campaign Monitor whether the subscriber has consented to having their email engagement tracked (opens, clicks, etc.). Campaign Monitor started requiring this field for accounts in Australia and New Zealand due to privacy laws, but it is good practice globally. For opt-in forms where the user is explicitly signing up, use 'Yes'. If you are programmatically adding contacts who have not explicitly opted in to tracking, use 'No'. Omitting the field entirely may cause errors on accounts with strict privacy settings.

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.