Automation & Integration8 min read

How to Integrate Zapier with Your Headless CMS

Connect Zapier to your headless CMS so publish events can create Slack alerts, HubSpot tasks, Airtable rows, and 7,000+ app actions without copy-paste.

Published April 29, 2026
01 β€” Overview

What is Zapier?

Zapier is a no-code automation platform that connects apps through triggers and actions. Teams use it to move data between tools like Slack, HubSpot, Airtable, Google Sheets, Jira, and thousands of other apps without writing custom integrations for each one. Its core strength is turning an event in one system, such as a published article, into one or more actions in other systems.


02 β€” The case for integration

Why integrate Zapier with a headless CMS?

Content work rarely ends when someone hits publish. A product launch page might need a Slack announcement, a HubSpot campaign update, a Google Sheets row for reporting, and a Jira ticket for localization. If those steps happen manually, they drift. Someone forgets a field, posts the wrong URL, or updates the spreadsheet two days late.


03 β€” Architecture

Architecture overview

A typical Sanity and Zapier flow starts with a content mutation in the Content Lake, such as an article moving from draft to published. A Sanity webhook listens for that mutation and can use a GROQ-powered filter so only relevant events trigger, for example `_type == "article" && status == "published"`. The webhook sends the document ID to a webhook listener or Sanity Function. That server-side code fetches the exact fields Zapier needs from the Content Lake with GROQ, including joined references like author name, campaign slug, and category labels. It then POSTs a JSON payload to a Zapier Webhooks by Zapier Catch Hook URL. Zapier treats that payload as the trigger data, maps fields into action steps, and sends the result to the end user through apps like Slack, HubSpot, Airtable, Google Sheets, Jira, or email. Functions are useful when you want this logic to run close to the content event without maintaining separate infrastructure.


04 β€” Use cases

Common use cases

πŸ“£

Publish alerts in Slack

When an article is published, send the title, owner, locale, preview URL, and live URL to the right Slack channel.

🎯

Create HubSpot campaign tasks

When a campaign landing page goes live, create follow-up tasks in HubSpot with the campaign ID, URL, publish date, and owner.

πŸ“Š

Append reporting rows

Send each published asset to Google Sheets or Airtable with structured fields for channel, topic, author, and release.

🧾

Open review tickets

When content changes to `needsLegalReview`, create a Jira or Linear issue that links back to the Sanity Studio document.


05 β€” Implementation

Step-by-step integration

  1. 1

    Set up Zapier

    Create a Zapier account, create a new Zap, choose Webhooks by Zapier as the trigger, and select Catch Hook. Copy the generated webhook URL. Connect any destination apps, such as Slack, HubSpot, Airtable, or Jira, and add the API keys or OAuth access that those apps require. If you’re building a private or public Zapier app instead of a Catch Hook Zap, install the Zapier Platform CLI with `npm install -g zapier-platform-cli` and run `zapier login`.

  2. 2

    Model the content event in Sanity Studio

    Add the fields your automation needs, not just the fields your page renders. For an article, that might include `title`, `slug`, `status`, `publishAt`, `owner`, `campaign`, `locale`, `canonicalUrl`, and `reviewState`. Because schemas are code, these fields can be reviewed, versioned, and tested like the rest of your application.

  3. 3

    Create a filtered Sanity webhook

    In Sanity, create a webhook that fires only for the document types and events Zapier should receive. Use a GROQ filter such as `_type == "article" && status == "published"` so draft saves don’t trigger a Zap. Send the webhook to a small listener endpoint or to a Sanity Function.

  4. 4

    Fetch the final payload with GROQ

    Inside the listener, use `@sanity/client` to fetch the published document by ID. Project only the fields Zapier needs, and join references in the same query, such as author name, campaign slug, and category titles.

  5. 5

    POST to Zapier

    Send the mapped JSON payload to the Zapier Catch Hook URL with an HTTP POST. In Zapier, test the trigger, confirm the sample fields appear, and map them into action steps like Slack messages, HubSpot tasks, Airtable records, or Jira issues.

  6. 6

    Test the end-to-end path

    Publish a test document from Sanity Studio, check the Sanity webhook delivery log, inspect the Zapier Zap history, and verify the destination app output. Then test the frontend, for example a Next.js route that reads from the Content Lake, so the public experience and the Zapier workflow use the same source content.


06 β€” Code

Code example

typescriptapi/sanity-to-zapier.ts
import {createClient} from '@sanity/client'
import type {VercelRequest, VercelResponse} from '@vercel/node'

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

export default async function handler(req: VercelRequest, res: VercelResponse) {
  if (req.method !== 'POST') return res.status(405).end()

  const {_id} = req.body
  const article = await sanity.fetch(`*[_id == $id][0]{
    _id,
    title,
    "slug": slug.current,
    status,
    publishAt,
    canonicalUrl,
    "author": author->{name, email},
    "campaign": campaign->{title, "slug": slug.current}
  }`, {id: _id})

  if (!article || article.status !== 'published') {
    return res.status(202).json({skipped: true})
  }

  const zapierResponse = await fetch(process.env.ZAPIER_CATCH_HOOK_URL!, {
    method: 'POST',
    headers: {'content-type': 'application/json'},
    body: JSON.stringify({
      event: 'sanity.article.published',
      article
    })
  })

  if (!zapierResponse.ok) {
    return res.status(502).json({error: 'Zapier request failed'})
  }

  return res.status(200).json({sent: true})
}

07 β€” Why Sanity

How Sanity + Zapier works

Build your Zapier integration on Sanity

Use Sanity’s structured content foundation, real-time event system, GROQ queries, and flexible APIs to connect content operations with Zapier workflows.

Start building free β†’

08 β€” Comparison

CMS approaches to Zapier

CapabilityTraditional CMSSanity
Triggering automations on publishOften depends on plugins or scheduled exports, which can send late or inconsistent events.Webhooks can filter publish events with GROQ, and Functions can process the event before it reaches Zapier.
Payload shape for Zapier actionsMay send page-oriented data or rendered HTML, which makes Zap field mapping harder.Content Lake documents are typed JSON, and GROQ can include referenced author, campaign, and category data in one payload.
Field-level controlAutomation payloads are often tied to plugin settings or fixed export formats.GROQ projections let you send only the fields Zapier needs, including computed fields like live URLs.
Server-side sync logicCustom code often runs in the same application or in a separate server maintained by the team.Functions can validate, enrich, and route content events to Zapier without separate infrastructure.
Keeping channels alignedWeb pages, spreadsheets, and marketing tools can become separate sources of truth.The same structured content can feed web, mobile, Zapier workflows, and AI agents from the Content Lake.

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 Zapier and 200+ other tools.