Communication & Collaboration8 min read

How to Integrate Crisp with Your Headless CMS

Connect Crisp to structured content so support teams can publish approved answers, FAQs, and product guidance into chat without copying text between tools.

Published April 29, 2026
01 — Overview

What is Crisp?

Crisp is a customer communication platform for live chat, shared inboxes, chatbots, campaigns, and help center content. Teams use it to answer customer questions from a website widget, route conversations to operators, and keep support history tied to each visitor or account. It’s common with SaaS, ecommerce, and support-led teams that need chat, email, and knowledge base workflows in one place.


02 — The case for integration

Why integrate Crisp with a headless CMS?

Support conversations move fast, but the answers usually live somewhere else. A pricing question might depend on a plan document, a shipping answer might depend on a product policy, and a technical reply might need copy that legal has already approved. If Crisp agents copy and paste from docs, wikis, or published pages, answers drift. One agent says “7 business days,” another says “5 to 10 days,” and nobody knows which one is current.


03 — Architecture

Architecture overview

A typical Crisp integration starts with structured support content in Sanity’s Content Lake. In Sanity Studio, editors publish a support reply, FAQ, or product policy document. A Sanity webhook fires on the publish event, often filtered with GROQ so it only runs for content types like supportReply or faqArticle. The webhook calls a Sanity Function or your own HTTPS endpoint. That server-side code uses @sanity/client to fetch the full published document with GROQ, including referenced product, locale, category, and canonical URL fields. It then maps those fields into the Crisp shape you need. For conversation workflows, the code can call Crisp’s Node SDK method sendMessageInConversation with the website ID and Crisp session ID. For knowledge workflows, use Crisp’s REST API for the Helpdesk resources available on your Crisp plan. The end user sees the approved answer in the Crisp chat widget or help center, while the source text stays structured in Sanity.


04 — Use cases

Common use cases

đź’¬

Approved chat replies

Publish a reviewed supportReply document in Sanity, then send it into a specific Crisp conversation as an operator message.

📚

Help center article sync

Keep Crisp Helpdesk articles aligned with structured FAQs, product policies, and troubleshooting guides from Sanity.

🌍

Localized support answers

Use locale fields in Sanity to send the right English, Spanish, or French answer into Crisp based on the visitor’s language.

🏷️

Conversation context

Attach product, plan, or topic metadata from Sanity to Crisp workflows so support teams know what content a visitor is asking about.


05 — Implementation

Step-by-step integration

  1. 1

    Set up Crisp credentials

    Create or open your Crisp workspace, copy your Website ID from the website setup instructions, and create API credentials in Crisp. For server-side API access with the Node SDK, you’ll typically use a plugin identifier and plugin key with Crisp’s plugin authentication tier.

  2. 2

    Install the Crisp SDKs

    For the website widget, install crisp-sdk-web and call Crisp.configure with your Website ID in your frontend. For server-side sync, install crisp-api so your webhook handler or Sanity Function can send messages or update Crisp resources.

  3. 3

    Model support content in Sanity Studio

    Create schemas for faqArticle, supportReply, or productPolicy. Include fields Crisp needs, such as title, shortAnswer, body, locale, category, product reference, canonicalUrl, and, if you’re sending a reply into an open chat, crispSessionId.

  4. 4

    Create a publish trigger

    Add a Sanity webhook or Function that runs when support content is published. Use a GROQ filter like _type in ["supportReply", "faqArticle"] so product pages, marketing pages, and drafts don’t trigger the Crisp sync.

  5. 5

    Fetch only the fields Crisp needs

    Inside the handler, use @sanity/client and GROQ to fetch the published document with references resolved. Keep the payload small: title, answer text, URL, locale, and a conversation or Helpdesk target.

  6. 6

    Test in Crisp before going live

    Create a test conversation in Crisp, publish a test supportReply in Sanity, and confirm the message appears with the right formatting. Then test updates, deletes, missing session IDs, and locale-specific content.


06 — Code

Code example

Minimal webhook handler that receives a Sanity publish event, fetches the published support reply with GROQ, and sends it into a Crisp conversation.

typescript
import {createClient} from '@sanity/client';
import Crisp from 'crisp-api';

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

const crisp = new Crisp();
crisp.authenticateTier(
  'plugin',
  process.env.CRISP_PLUGIN_IDENTIFIER!,
  process.env.CRISP_PLUGIN_KEY!
);

export async function POST(req: Request) {
  const body = await req.json();
  const id = body._id?.replace(/^drafts\./, '');

  const reply = await sanity.fetch(
    `*[_id == $id][0]{
      title,
      shortAnswer,
      canonicalUrl,
      crispSessionId
    }`,
    {id}
  );

  if (!reply?.crispSessionId) {
    return Response.json({ok: true, skipped: 'Missing Crisp session ID'});
  }

  await crisp.website.sendMessageInConversation(
    process.env.CRISP_WEBSITE_ID!,
    reply.crispSessionId,
    {
      type: 'text',
      from: 'operator',
      origin: 'chat',
      content: `${reply.title}

${reply.shortAnswer}

${reply.canonicalUrl}`
    }
  );

  return Response.json({ok: true});
}

07 — Why Sanity

How Sanity + Crisp works

Build your Crisp integration on Sanity

Use Sanity’s AI Content Operating System to structure support content, trigger real-time sync, and connect precise content fields to Crisp.

Start building free →

08 — Comparison

CMS approaches to Crisp

CapabilityTraditional CMSSanity
Approved support repliesReplies are often copied from pages or internal docs, which makes it easy for agents to use old wording.Model supportReply documents with answer text, locale, product references, review status, and Crisp session targets.
Real-time sync to CrispPublish events may require plugins, queues, or custom cron jobs to reach Crisp.Webhooks and Functions can trigger on publish events and run the Crisp sync code without a separate server.
Field-level payload controlIntegrations often receive rendered HTML or large page payloads that need cleanup.GROQ fetches exactly the fields Crisp needs, including referenced product, category, and locale data.
Localized chat answersLocalized content is often organized by page, so mapping a chat answer to the visitor’s language can be manual.Locale, fallback, and approval fields can live in the schema, so the Crisp integration can send the right answer per visitor.
Content reuse across channelsA page-first model can make Crisp sync separate from website and app publishing.The same structured content can feed your site, mobile app, Crisp workflows, and AI agents through Agent Context.

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