Marketing & Advertising8 min read

How to Integrate Mailchimp with Your Headless CMS

Connect Mailchimp to your headless CMS so published content can create email campaign drafts, update audience tags, and keep marketing messages in sync without copy-paste work.

Published April 29, 2026
01 — Overview

What is Mailchimp?

Mailchimp is an email marketing and marketing automation platform from Intuit. Teams use it to build campaigns, maintain audiences, apply tags and segments, run Customer Journeys, and review email performance. It’s widely used by small businesses, publishers, ecommerce teams, and marketing teams that need email workflows without building their own sending infrastructure.


02 — The case for integration

Why integrate Mailchimp with a headless CMS?

Email teams often move faster than their tools allow. A product launch page goes live at 9:00 a.m., but the Mailchimp campaign still has yesterday’s headline because someone had to copy the title, teaser, image, CTA URL, and legal footer by hand. That manual step gets worse when you have multiple regions, weekly newsletters, product drops, event reminders, or audience-specific variants.

Connecting Mailchimp to a headless CMS category tool solves a practical problem: Mailchimp needs clean campaign data, and your content source already has it. With Sanity’s AI Content Operating System, structured content in the Content Lake can be queried as typed JSON, so a newsletter issue can include the subject line, preheader, article references, author names, canonical URLs, and locale-specific copy in one predictable payload. GROQ selects only the fields Mailchimp needs. Webhooks or Functions can react when an editor publishes, updates, or deletes content.

The alternative is a disconnected workflow. Editors publish in one place, marketers rebuild the same message in Mailchimp, QA checks two versions, and stale links slip through. An integration doesn’t remove every review step, and it shouldn’t auto-send campaigns without approval for most teams. But it can create accurate Mailchimp drafts, apply the right tags, and give marketers a safer starting point.


03 — Architecture

Architecture overview

A typical Mailchimp integration starts when an editor publishes a document in Sanity Studio, such as a newsletter issue, product announcement, event, or campaign landing page. A Sanity webhook fires only for the document types you choose, for example `_type == "newsletterIssue"`, and sends the changed document ID to a Sanity Function or your own webhook endpoint. That server-side handler uses `@sanity/client` to fetch the current document from the Content Lake with GROQ. The query can join referenced articles, authors, products, categories, and localized fields into one Mailchimp-ready object. The handler then calls Mailchimp’s Marketing API with the official `@mailchimp/mailchimp_marketing` SDK. For a campaign workflow, it can call `campaigns.create()` to create a regular email campaign for a specific audience list, then `campaigns.setContent()` to write the HTML body. For an audience workflow, it can call list member endpoints to add tags, update merge fields, or sync subscriber data. The end user receives the email through Mailchimp after your team reviews, tests, and sends the campaign, or after a Mailchimp Customer Journey uses the synced tags and audience data. Sanity remains the structured source for the content, while Mailchimp handles subscriber lists, compliance footers, delivery, segmentation, and reporting.


04 — Use cases

Common use cases

📨

Publish-to-draft newsletters

Create a Mailchimp campaign draft when a newsletter issue is published, including subject line, preheader, curated articles, and CTA links.

🎯

Topic-based audience targeting

Map Sanity topics, regions, or product categories to Mailchimp tags so campaigns can target the right subscriber groups.

🛍️

Product and event announcements

Sync launch copy, event dates, registration URLs, product summaries, and hero images into Mailchimp campaign content.

🌎

Localized campaign variants

Use GROQ to fetch locale-specific titles, excerpts, URLs, and legal text for region-specific Mailchimp drafts.


05 — Implementation

Step-by-step integration

  1. 1

    Set up Mailchimp API access

    Create or open your Mailchimp account, choose the audience you want to send to, and copy its audience ID from Audience settings. Create an API key from your Mailchimp profile under Extras, API keys. Note the server prefix at the end of the key, such as `us21`. Keep the key server-side only.

  2. 2

    Install the SDKs

    In your Sanity Function, webhook service, or app route, install `@mailchimp/mailchimp_marketing` for Mailchimp API calls and `@sanity/client` for Content Lake reads.

  3. 3

    Model campaign-ready content in Sanity Studio

    Create a schema such as `newsletterIssue` with fields for `subject`, `preheader`, `audience`, `locale`, `articles`, `ctaLabel`, `ctaUrl`, and `mailchimpCampaignId`. Use references for articles or products so editors don’t paste duplicate copy.

  4. 4

    Create the publish trigger

    Add a Sanity webhook or Function that runs only when relevant content is published or updated. Use a webhook filter such as `_type == "newsletterIssue"` so unrelated edits don’t create Mailchimp drafts.

  5. 5

    Fetch structured content and call Mailchimp

    Use GROQ to fetch the exact fields Mailchimp needs, including referenced articles and canonical URLs. Then call Mailchimp’s Marketing API to create a campaign draft, set the campaign content, update merge fields, or apply tags.

  6. 6

    Test with a small audience first

    Use a Mailchimp test audience or internal segment. Check subject lines, preheaders, unsubscribe footer behavior, image URLs, merge tags, and tracked links. Then build the frontend archive, landing page, or preference center from the same Sanity content.


06 — Code

Code example

typescriptapp/api/sanity-mailchimp/route.ts
import {createClient} from '@sanity/client'
import mailchimp from '@mailchimp/mailchimp_marketing'

const sanity = createClient({
  projectId: process.env.SANITY_PROJECT_ID!,
  dataset: process.env.SANITY_DATASET!,
  apiVersion: '2025-01-01',
  token: process.env.SANITY_WRITE_TOKEN!,
  useCdn: false
})

mailchimp.setConfig({
  apiKey: process.env.MAILCHIMP_API_KEY!,
  server: process.env.MAILCHIMP_SERVER_PREFIX!
})

export async function POST(req: Request) {
  const {_id} = await req.json()

  const issue = await sanity.fetch(`*[_id == $id][0]{
    _id, subject, preheader,
    "items": articles[]->{title, excerpt, "slug": slug.current}
  }`, {id: _id})

  if (!issue) return Response.json({ok: false}, {status: 404})

  const campaign = await mailchimp.campaigns.create({
    type: 'regular',
    recipients: {list_id: process.env.MAILCHIMP_AUDIENCE_ID!},
    settings: {
      subject_line: issue.subject,
      preview_text: issue.preheader,
      title: issue.subject,
      from_name: 'Editorial Team',
      reply_to: 'newsletter@example.com'
    }
  })

  const html = `<h1>${issue.subject}</h1>` + issue.items.map((item: any) =>
    `<h2>${item.title}</h2><p>${item.excerpt}</p><a href="${process.env.SITE_URL}/${item.slug}">Read more</a>`
  ).join('')

  await mailchimp.campaigns.setContent(campaign.id, {html})
  await sanity.patch(issue._id).set({mailchimpCampaignId: campaign.id}).commit()

  return Response.json({ok: true, campaignId: campaign.id})
}

07 — Why Sanity

How Sanity + Mailchimp works

Build your Mailchimp integration on Sanity

Sanity gives you the structured content foundation, real-time event system, and flexible APIs to connect Mailchimp campaigns with the content your teams already publish.

Start building free →

08 — Comparison

CMS approaches to Mailchimp

CapabilityTraditional CMSSanity
Campaign content shapeThe Content Lake returns typed JSON, and GROQ can shape one Mailchimp-ready payload with subject, teaser, URLs, and referenced content.
Publish-triggered syncWebhooks and Functions can trigger on publish, update, or delete events and run the Mailchimp sync server-side.
Audience targeting dataYou can model topics, regions, lifecycle stages, and products, then map those fields to Mailchimp tags or draft variants.
Localized email campaignsGROQ can select the requested locale, fallback copy, region-specific URLs, and legal text before creating the Mailchimp draft.
Campaign QA before syncSchema validation, Tasks, and Content Agent can help flag missing campaign fields before a Mailchimp draft is created.

09 — Next steps

Keep building

Explore related integrations to complete your content stack.

Ready to try Sanity?

See how Sanity's Content Operating System powers integrations with Mailchimp and 200+ other tools.