How to Integrate HubSpot with Your Headless CMS
Connect HubSpot to structured content so campaign pages, gated assets, lead forms, and CRM workflows stay in sync the moment content ships.
What is HubSpot?
HubSpot is a customer platform used by marketing, sales, and service teams to run CRM records, email campaigns, forms, landing pages, ads, lists, workflows, and reporting. Its Marketing Hub is widely used by B2B, SaaS, ecommerce, and agency teams that need to connect lead capture with campaign execution. The core value is tying visitor behavior and form submissions to contact records, segments, campaigns, and follow-up automation.
Why integrate HubSpot with a headless CMS?
Marketing teams usually don’t have one place where campaign content and campaign execution meet. Your product marketers may publish landing pages and resource pages in a headless CMS, while demand generation teams build HubSpot forms, lists, workflows, and email nurtures from copied titles, URLs, UTM values, and asset metadata. That copy-and-paste layer is where mistakes show up: a broken gated asset URL, an outdated webinar title in an email, or a contact workflow triggered by the wrong campaign name.
Connecting HubSpot to a headless CMS fixes the handoff. When a campaign page, webinar, case study, or gated report is published, structured fields can sync directly to HubSpot as custom object records, HubDB rows, campaign properties, or workflow inputs. HubSpot still handles what it’s built for, including forms, contact records, lists, lead scoring, ads attribution, and automation. The headless CMS handles structured campaign content that can be reused across your website, mobile app, emails, sales enablement, and AI agents.
With Sanity, the integration works well because content in the Content Lake is typed JSON, not page HTML. GROQ can select exactly the fields HubSpot needs, such as title, slug, campaign ID, lifecycle stage, gated asset URL, topic references, and UTM defaults. Webhooks can fire on publish events, and Functions can run the server-side sync logic without a separate queue worker. The alternative is usually a weekly CSV import, a Zap that only sees flat fields, or a marketer updating the same campaign metadata in 3 places.
Architecture overview
A typical HubSpot integration starts in Sanity Studio. An editor publishes a campaign page, gated asset, webinar, or customer story. A Sanity webhook, filtered with GROQ so it only fires for relevant document types and publish events, sends the changed document ID to a Sanity Function or webhook endpoint. The Function uses @sanity/client to fetch the published document from the Content Lake. GROQ projects only the fields HubSpot needs, including resolved references like campaign, topic, persona, region, author, and canonical URL. The Function then calls HubSpot with a private app access token through @hubspot/api-client. Depending on your setup, it can create or update a HubSpot custom object, write to a HubDB table, associate content metadata with a campaign, or pass source details into contact records created from a HubSpot form submission. From there, HubSpot uses the synced data in lists, workflows, lead scoring, ad audiences, emails, and reporting. The end user sees a fast website or app powered by structured content, fills out a HubSpot form, and lands in the right follow-up path because the content context was sent with the submission.
Common use cases
Campaign metadata sync
Publish a campaign page in Sanity and sync the title, URL, topic, persona, UTM values, and HubSpot campaign ID into HubSpot for reporting and workflows.
Gated asset follow-up
Connect Sanity resource pages to HubSpot forms so each form submission carries the exact report, webinar, or template the visitor requested.
Landing page experiments
Use structured variants in Sanity for page copy, CTA text, and audience segments, then pass experiment labels into HubSpot contact properties or lists.
Email and nurture content feeds
Sync approved resources from Sanity into HubSpot custom objects or HubDB rows so nurture emails can reference current titles, summaries, and URLs.
Step-by-step integration
- 1
Set up HubSpot access
Create or use a HubSpot account, then create a private app in HubSpot under Settings, Integrations, Private Apps. Add the scopes your sync needs, such as crm.objects.contacts.read, crm.objects.contacts.write, crm.objects.custom.read, crm.objects.custom.write, forms, and hubdb if you plan to use HubDB. Copy the private app access token into your server environment. Install the SDK with npm install @hubspot/api-client.
- 2
Decide where Sanity content should land in HubSpot
Pick the HubSpot destination before writing code. For reusable campaign assets, use a custom object such as Content Offer. For website modules inside HubSpot, use HubDB. For lead capture, use HubSpot forms and pass Sanity document IDs, slugs, campaign IDs, and asset names as hidden fields.
- 3
Model campaign content in Sanity Studio
Create schemas for campaignPage, gatedAsset, webinar, or caseStudy. Include fields like title, slug, summary, campaign reference, persona reference, topic reference, canonicalUrl, gatedAssetUrl, hubspotCampaignId, hubspotObjectId, and syncStatus. Keep HubSpot IDs as explicit fields so updates don’t create duplicates.
- 4
Create the sync trigger
Add a Sanity webhook filtered to published document types, or use a Sanity Function triggered by content mutations. The trigger should send the document ID, mutation type, and dataset. Use a secret header or signature verification so only Sanity can call the endpoint.
- 5
Fetch structured content and call HubSpot
Inside the Function or webhook handler, use GROQ to fetch only the fields HubSpot needs. Then call HubSpot’s CRM Objects API, Forms API, or HubDB API with @hubspot/api-client. For updates, search by sanity_id or store the returned HubSpot object ID back on the Sanity document.
- 6
Test the frontend and reporting path
Publish a test asset, confirm the HubSpot record updates, submit a HubSpot form from the page, and verify that the contact record includes the Sanity document ID, asset title, campaign ID, and UTM values. Test failures too, such as expired HubSpot tokens, missing campaign IDs, and unpublished referenced content.
How Sanity + HubSpot works
Build your HubSpot integration on Sanity
Sanity gives you the structured content foundation, real-time event system, and flexible APIs to connect HubSpot with your campaign pages, gated assets, forms, workflows, and reporting.
Start building free →CMS approaches to HubSpot
| Capability | Traditional CMS | Sanity |
|---|---|---|
| Campaign content structure | Campaign data often lives inside pages, modules, or rich text fields, which makes it harder to reuse in HubSpot workflows. | The AI Content Operating System structures campaign content as typed JSON in the Content Lake, with references that GROQ can resolve in one query. |
| Sync timing | Teams often depend on manual exports, scheduled plugins, or form embeds that don’t update campaign metadata when content changes. | Webhooks and Functions can trigger on publish events and run the HubSpot sync server-side without a separate worker service. |
| Field-level control for HubSpot | HubSpot may receive full page URLs or scraped metadata instead of clean fields for segmentation and reporting. | GROQ projects only the HubSpot fields you need, including joined references like campaign ID, topic, persona, region, and asset URL. |
| Lead capture context | Forms can capture leads, but hidden fields often have to be hardcoded per page or maintained by hand. | Each page can expose consistent metadata, such as sanity_id, slug, asset type, and campaign ID, so HubSpot contacts carry accurate source context. |
| Multi-channel reuse | Content is frequently tied to website pages, so HubSpot emails, ads, and sales enablement may need separate copy. | One structured back end can feed your website, HubSpot, mobile apps, sales tools, and AI agents through APIs and Agent Context. |
| Trade-offs | Faster to start for simple pages, but harder to keep HubSpot campaign data clean as programs grow. | You’ll need developers to model schemas and write the sync logic, but the result is versioned, testable, and easier to extend across campaigns. |
Keep building
Explore related integrations to complete your content stack.
Sanity + Google Ads
Send structured landing page, campaign, and UTM data from Sanity into Google Ads reporting and audience workflows.
Sanity + Meta Ads
Connect campaign content and audience-specific landing pages in Sanity with Meta ad creative, tracking, and conversion paths.
Sanity + Marketo
Sync gated assets, webinars, and campaign metadata from Sanity into Marketo programs, forms, and nurture flows.