DAM & Media8 min read

How to Integrate Transloadit with Your Headless CMS

Send newly published media from your headless CMS to Transloadit for resizing, encoding, watermarking, and delivery without editors re-uploading files by hand.

Published April 29, 2026
01Overview

What is Transloadit?

Transloadit is a file processing platform for developers that handles uploads, imports, exports, and media processing through an API. Teams use it to resize images, encode video, extract thumbnails, scan files, add watermarks, convert documents, and move processed files into services like Amazon S3, Google Cloud Storage, or Azure Blob Storage. Its workflow model is built around Assemblies, which run ordered processing steps called Robots.


02The case for integration

Why integrate Transloadit with a headless CMS?

Media work gets messy when content and file processing live in separate places. An editor publishes a product page with a 4K demo video, but someone still has to upload that video to a processing tool, wait for HLS renditions, copy the final URLs, and paste them back into the entry. Multiply that by 50 product pages, 12 locales, and weekly campaign updates, and you’ve got a slow, error-prone workflow.

Connecting Transloadit to a headless CMS category tool solves that by letting the publishing event start the media pipeline. When an editor publishes content, your integration can send the asset URL and metadata to Transloadit, run a specific Assembly Template, store the outputs in your media bucket, and write the resulting URLs back to the content entry. With Sanity, structured content in the Content Lake means you can query exactly the media fields Transloadit needs. Webhooks or Functions can trigger the job the moment content changes.

The trade-off is that you’ll need to design the handoff carefully. Large private files need signed URLs or another secure import strategy, and long-running Transloadit jobs usually need a callback to update content after processing finishes. That’s still better than asking editors to track variants, thumbnails, captions, and encoding status in spreadsheets.


03Architecture

Architecture overview

A typical Sanity and Transloadit integration starts when an editor publishes a document that references a video, image, audio file, or document asset in the Content Lake. A Sanity webhook fires on the publish event and sends the document ID to a webhook listener, or a Sanity Function runs the same server-side logic without separate infrastructure. The handler uses GROQ to fetch only the fields needed for processing, such as the asset URL, title, alt text, locale, destination folder, and any referenced campaign or product data. It then calls Transloadit’s Node SDK or HTTP API to create an Assembly. The Assembly can import the Sanity asset URL with the /http/import Robot, process it with Robots like /image/resize, /video/encode, /video/thumbs, /audio/encode, or /file/viruscheck, and export the results with /s3/store or another storage Robot. After Transloadit completes the job, it can call a notify_url endpoint. That callback can patch the Sanity document with the Assembly ID, processing status, thumbnail URL, HLS playlist URL, file size, duration, or rendition metadata. From there, your frontend queries Sanity for the ready-to-render media fields and serves the processed assets to web, mobile, ecommerce, or app experiences.


04Use cases

Common use cases

🎬

Video renditions on publish

Publish a Sanity video entry and have Transloadit create HLS output, MP4 fallbacks, poster frames, and duration metadata.

🖼️

Campaign image variants

Generate square, landscape, portrait, and retina image sizes from one source asset when campaign content goes live.

🔐

File checks before distribution

Send uploaded PDFs, ZIP files, or user-submitted media through Transloadit virus scanning before exposing download links.

🌍

Localized media workflows

Use Sanity locale fields to route region-specific assets into different Transloadit export paths, buckets, or watermarked variants.


05Implementation

Step-by-step integration

  1. 1

    Create your Transloadit account and credentials

    Create a Transloadit account, copy your Auth Key and Auth Secret from the dashboard, and decide whether you’ll use inline Assembly steps or an Assembly Template. For repeatable workflows, create a template with Robots such as /http/import, /image/resize, /video/encode, /video/thumbs, and /s3/store.

  2. 2

    Install the SDKs

    In your webhook service, Sanity Function, or middleware app, install the packages you need: transloadit for creating Assemblies and @sanity/client for fetching structured content with GROQ.

  3. 3

    Model media fields in Sanity Studio

    Add typed fields for the source asset, processing status, Assembly ID, output URLs, thumbnails, duration, alt text, and any routing metadata. For example, a video document might include sourceFile, transloaditStatus, hlsUrl, posterUrl, and durationSeconds.

  4. 4

    Create the publish trigger

    Add a Sanity webhook filtered to the media documents you want to process, such as _type == "video" && defined(sourceFile). Use a projection that sends the document ID. If you want the logic to run inside Sanity’s event system, use a Sanity Function instead of hosting your own listener.

  5. 5

    Call Transloadit and save the job state

    When the webhook fires, fetch the full document with GROQ, create a Transloadit Assembly, and patch the Sanity document with the Assembly ID and a processing status. Configure Transloadit notify_url so a completion callback can write final output URLs back to Sanity.

  6. 6

    Test the frontend experience

    Publish one test asset, confirm that Transloadit creates the expected outputs, and query Sanity from your frontend for the processed URLs. Show a processing state if transloaditStatus is pending, and render the final image, video, or download link when complete.


06Code

Code example

typescripttransloadit-webhook.ts
import express from 'express'
import Transloadit from 'transloadit'
import {createClient} from '@sanity/client'

const app = express()
app.use(express.json())

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
})

const transloadit = new Transloadit({
  authKey: process.env.TRANSLOADIT_AUTH_KEY!,
  authSecret: process.env.TRANSLOADIT_AUTH_SECRET!
})

app.post('/webhooks/sanity/transloadit', async (req, res) => {
  const id = req.body._id

  const video = await sanity.fetch(`*[_id == $id][0]{
    _id,
    title,
    "assetUrl": sourceFile.asset->url
  }`, {id})

  if (!video?.assetUrl) return res.status(204).end()

  const assembly = await transloadit.createAssembly({
    params: {
      notify_url: process.env.TRANSLOADIT_NOTIFY_URL,
      steps: {
        import: {robot: '/http/import', url: video.assetUrl},
        hls: {use: 'import', robot: '/video/encode', preset: 'hls'},
        poster: {use: 'import', robot: '/video/thumbs', count: 1},
        export: {
          use: ['hls', 'poster'],
          robot: '/s3/store',
          credentials: 'aws-prod',
          path: 'sanity/' + video._id + '/${file.url_name}'
        }
      }
    },
    fields: {sanityId: video._id, title: video.title}
  })

  await sanity.patch(video._id).set({
    transloaditStatus: 'processing',
    transloaditAssemblyId: assembly.assembly_id
  }).commit()

  res.json({assemblyId: assembly.assembly_id})
})

app.listen(3000)

07Why Sanity

How Sanity + Transloadit works

Build your Transloadit integration on Sanity

Sanity gives you the structured content foundation, real-time event system, and flexible APIs to connect publishing workflows with Transloadit media processing.

Start building free →

08Comparison

CMS approaches to Transloadit

CapabilityTraditional CMSSanity
Media data shapeMedia is often tied to pages, plugins, or editor fields, so custom processing may require parsing rendered content or plugin-specific tables.The Content Lake stores typed JSON, so Transloadit can receive exact asset URLs, metadata, references, and routing fields from one GROQ query.
Processing triggerProcessing commonly depends on upload hooks, scheduled jobs, or plugin behavior that may not match publish timing.Webhooks can filter publish events with GROQ, and Functions can run server-side processing logic without a separate worker service.
Field-level controlThe integration may receive too much page data or not enough linked metadata, especially for reused assets.GROQ can fetch the media asset, parent content, brand settings, locale, and destination path in one request.
Writing results backSaving HLS URLs, thumbnails, and processing status often needs custom plugin fields or database changes.Your schema can include processing status, Assembly IDs, output URLs, and editor-facing previews directly in Sanity Studio.
Multi-channel deliveryProcessed media is usually tied first to the website, with extra work needed for apps, kiosks, or AI agents.One structured back end can feed web, mobile, Transloadit workflows, and production AI agents through Agent Context.

09Next 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 Transloadit and 200+ other tools.