Communication & Collaboration8 min read

How to Integrate Loom with Your Headless CMS

Connect Loom to your headless CMS so teams can record walkthroughs once, attach them to structured entries, and publish current video embeds across docs, support, and onboarding.

Published April 29, 2026
01 — Overview

What is Loom?

Loom is an async video messaging platform used by product, support, sales, education, and operations teams to record screen, camera, and microphone walkthroughs. Teams use it for onboarding, bug reports, release demos, support answers, and internal training when a written note would take longer to explain. Its core capability is fast recording and sharing, with embeddable videos, viewer permissions, transcripts, and APIs for connecting video metadata to other systems.


02 — The case for integration

Why integrate Loom with a headless CMS?

Loom videos often start as one-off links in Slack, docs, tickets, or onboarding checklists. That works for a week. Then the product UI changes, the help article moves, the release note gets archived, and nobody knows which Loom is still safe to share with customers.

Connecting Loom to a headless CMS gives each video a structured home. Instead of pasting an iframe into rich text, you can model a Loom video as fields like videoId, embedUrl, shareUrl, transcriptStatus, productArea, owner, and lastReviewedAt. With Sanity’s AI Content Operating System, that structured data lives in the Content Lake, and webhooks or Functions can run the moment a guide, lesson, or support article is published.

The practical difference is small but important. Manual setup means a teammate records a Loom, copies a link, pastes it into three places, updates the title in Loom, updates the title in the article, and hopes both stay in sync. An integrated setup lets your publishing event update Loom metadata, render the correct embed in your frontend, notify collaboration tools, and keep the same video attached to web, mobile, support, and AI agent experiences. The trade-off is that Loom remains the video system of record for recording and playback, so you still need to handle Loom OAuth tokens, permissions, and workspace access carefully.


03 — Architecture

Architecture overview

A common architecture starts in Sanity Studio, where editors attach a Loom video to a structured document, such as a help article, onboarding lesson, release note, or product walkthrough. The schema keeps Loom-specific fields like videoId, embedUrl, shareUrl, thumbnailUrl, duration, and transcriptStatus separate from the article body, so your frontend doesn’t need to parse HTML to find an iframe. When the document is published, a Sanity webhook fires with the document ID, or a Sanity Function runs directly on the content mutation. The handler uses GROQ to fetch exactly what Loom needs, for example the title, summary, canonical URL, product area, and Loom video ID. It can then call Loom’s REST API with an OAuth bearer token, commonly PATCHing the Loom video metadata so the video title and description match the published content. The end user sees the result in your site, app, or learning portal. Your frontend queries the Content Lake for the structured entry, renders the Loom embed URL, and can also show related content, transcript status, owner, or last review date. If you want recording inside an internal tool, use Loom’s Record SDK in the frontend to create the video, then write the returned Loom URL and video ID back to Sanity.


04 — Use cases

Common use cases

🎥

Product walkthroughs in documentation

Attach Loom demos to feature docs, then sync the Loom title and description whenever the article publishes.

🧑‍🏫

Onboarding lessons with owner tracking

Model each training video with owner, role, team, and review date fields, so stale Loom walkthroughs are easy to find.

🛟

Support answers with reusable videos

Connect Loom explainers to help articles, macros, and support flows without copying the same embed into multiple places.

🚀

Release notes with async demos

Publish a release note and update the connected Loom video metadata with the shipped feature name, summary, and canonical URL.


05 — Implementation

Step-by-step integration

  1. 1

    Set up Loom developer access

    Create a Loom developer app, configure OAuth for the REST API, and note the public app ID if you plan to use @loomhq/record-sdk for in-app recording. For production, store the Loom access token and refresh token in your server environment or secret manager, not in Sanity Studio.

  2. 2

    Install the packages you need

    Install @sanity/client for GROQ reads from the Content Lake. If editors will record Loom videos from your app, also install @loomhq/record-sdk or @loomhq/record-sdk-react in the browser app where recording happens.

  3. 3

    Model Loom fields in Sanity Studio

    Add a typed object for Loom data, such as videoId, shareUrl, embedUrl, thumbnailUrl, durationSeconds, transcriptStatus, and lastSyncedAt. Keep these fields separate from Portable Text so you can validate required URLs, query video entries, and render embeds safely.

  4. 4

    Create the sync trigger

    Use a Sanity webhook filtered to published documents that include loom.videoId, or use a Sanity Function triggered by content mutations. Send the document ID to your handler, then fetch the current document with GROQ before calling Loom.

  5. 5

    Call Loom’s REST API

    Use Loom’s API with an OAuth bearer token to read or update video metadata. A common publish flow updates the Loom video name and description from the Sanity document, including a canonical URL back to the live page.

  6. 6

    Test the frontend experience

    Publish a test article with a Loom video, confirm the webhook or Function runs, verify the Loom metadata changed, and render the embedUrl in your frontend. Also test failure cases, such as an expired Loom token, a deleted video, or a private video that the viewer can’t access.


06 — Code

Code example

Minimal publish webhook handler. It receives a Sanity webhook, fetches the current document with GROQ, and updates the connected Loom video metadata through Loom’s REST API.

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

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

export async function POST(req: Request) {
  const payload = await req.json()
  const id = payload._id || payload.documentId

  const doc = await sanity.fetch(`*[_id == $id][0]{
    title,
    "summary": pt::text(body)[0...700],
    "url": canonicalUrl,
    "loomVideoId": loom.videoId
  }`, {id})

  if (!doc?.loomVideoId) {
    return Response.json({skipped: true})
  }

  const res = await fetch(`https://api.loom.com/v1/videos/${doc.loomVideoId}`, {
    method: 'PATCH',
    headers: {
      Authorization: `Bearer ${process.env.LOOM_ACCESS_TOKEN}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      name: doc.title,
      description: `${doc.summary}

Read more: ${doc.url}`,
    }),
  })

  if (!res.ok) {
    throw new Error(`Loom update failed: ${res.status} ${await res.text()}`)
  }

  return Response.json({synced: true, loomVideoId: doc.loomVideoId})
}

07 — Why Sanity

How Sanity + Loom works

Build your Loom integration on Sanity

Sanity gives you the structured content foundation, real-time event system, and flexible APIs you need to connect Loom videos to docs, support, onboarding, and AI content workflows.

Start building free →

08 — Comparison

CMS approaches to Loom

CapabilityTraditional CMSSanity
Attaching Loom videos to contentEditors usually paste an iframe or share URL into a rich text field, which makes validation and reuse hard.Model Loom as a typed object with videoId, embedUrl, shareUrl, thumbnailUrl, transcriptStatus, owner, and review date.
Syncing on publishTeams often update Loom and the page by hand, so titles and descriptions drift over time.Webhooks or Functions can trigger on publish and call Loom immediately with the current document data.
Selecting context for Loom metadataThe integration may need to parse rendered HTML or fetch page data that includes more than Loom needs.GROQ can return the exact fields for the Loom update, including joined references, in one query.
Recording from editorial toolsEditors record in Loom, switch tabs, copy a link, paste it, and hope the embed format is right.Sanity Studio is React-based, so you can add a custom input that uses Loom’s Record SDK and writes the returned video data into structured fields.
Using Loom content across channelsVideo embeds are often tied to one page template, which limits reuse in apps, support tools, and AI agents.One structured back end can feed web, mobile, support surfaces, Loom sync jobs, and Agent Context for production AI agents.

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