DAM & Media8 min read

How to Integrate Filestack with Your Headless CMS

Connect Filestack to your headless CMS so editors can publish structured content while Filestack handles uploads, transformations, file delivery, and media workflows.

Published April 29, 2026
01Overview

What is Filestack?

Filestack is a file upload, transformation, and delivery platform used by product teams that need users, editors, or internal systems to move files into an app safely and quickly. Its core tools include the File Picker, Upload API, Processing API, CDN delivery, and file intelligence features like metadata, virus detection, and image transformations. Teams use Filestack when they need media workflows that go beyond a basic image field, especially for user-generated content, product imagery, profile photos, documents, and large media libraries.


02The case for integration

Why integrate Filestack with a headless CMS?

Media workflows get messy when your content and files live in different places. Editors publish an article in one system, designers upload final images somewhere else, and developers end up copying URLs into fields by hand. That works for 20 assets. It breaks when you’re publishing 2,000 product images, collecting customer uploads, or generating multiple renditions for web, mobile, and email.,Connecting Filestack to a headless CMS lets you keep the editorial source of truth separate from the media processing layer. In a Sanity setup, your content stays structured in the Content Lake as typed JSON, while Filestack can handle file intake, storage, transformations, CDN URLs, and metadata. A product document can reference a hero image, a gallery, a PDF spec sheet, and a Filestack handle without mixing file processing logic into the editorial workflow.,The alternative is usually a manual checklist: upload file, copy URL, paste URL, publish, ask someone to resize it, then fix stale links later. With structured content and real-time webhooks, you can trigger a Filestack upload or transformation the moment a document is published. GROQ selects only the fields Filestack needs, and Functions can run the server-side sync logic without standing up a separate worker.


03Architecture

Architecture overview

A typical Sanity and Filestack integration starts when an editor publishes a document in Sanity Studio. The publish event writes structured JSON to the Content Lake. A webhook, filtered to the document types you care about, fires immediately and passes the document ID to a Sanity Function or webhook endpoint. That server-side code uses @sanity/client and a GROQ query to fetch exactly the media fields needed, such as title, slug, image asset URLs, alt text, and existing Filestack handles. For each Sanity asset URL that doesn’t already have a Filestack handle, the function calls the Filestack SDK, usually client.storeURL(assetUrl), to copy the file into Filestack storage. The response includes a handle, CDN URL, filename, MIME type, and size. You can patch those values back onto the Sanity document, then your frontend can render either the original Sanity asset, the Filestack CDN URL, or a Filestack transformation URL. The end user sees the final image, document, or transformed asset through your website, app, email, or another channel.


04Use cases

Common use cases

🖼️

Editorial image processing

Sync Sanity image assets to Filestack, then serve resized, cropped, or compressed versions for article pages, landing pages, and email.

📦

Product media pipelines

Publish product content in Sanity, copy new gallery images to Filestack, and generate consistent media URLs for PDPs, feeds, and mobile apps.

📄

Document upload and delivery

Attach PDFs, spec sheets, menus, or forms to structured Sanity documents, then use Filestack for upload handling, storage, and delivery.

🧪

User-generated content review

Send customer uploads through Filestack intake and file checks, then reference approved handles from structured Sanity content.


05Implementation

Step-by-step integration

  1. 1

    Create a Filestack app and get your API key

    Sign in to Filestack, create or select an app, and copy the API key from the developer settings. If you plan to upload from a trusted server, keep any security credentials in environment variables, not in Sanity Studio or frontend code.

  2. 2

    Install the SDKs

    Install Filestack’s JavaScript SDK and Sanity’s client package in the service that will run your sync logic: npm install filestack-js @sanity/client.

  3. 3

    Model Filestack fields in Sanity Studio

    Add fields for the original Sanity asset, alt text, and Filestack metadata. For example, an image object can include image, alt, filestackHandle, filestackUrl, mimeType, and fileSize. Keep the handle separate from the display URL so you can build transformation URLs later.

  4. 4

    Create the sync trigger

    Use a Sanity webhook filtered to published document types, or use a Sanity Function to run logic directly on content mutations. For example, trigger only when _type == 'product' or _type == 'post' and a media field exists.

  5. 5

    Call Filestack from server-side code

    In the webhook handler or Function, fetch the published document with GROQ, read the Sanity asset URL, call client.storeURL(assetUrl), and patch the returned Filestack handle and URL back to the document.

  6. 6

    Test the frontend experience

    Publish one document with a small image, one with a large image, and one with no image. Confirm the Filestack handle is written back, transformation URLs render correctly, and your frontend has a fallback when Filestack metadata is missing.


06Code

Code example

typescriptfilestack-sync.ts
import {createClient} from '@sanity/client'
import * as filestack from 'filestack-js'

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 fsClient = filestack.init(process.env.FILESTACK_API_KEY!)

export async function POST(req: Request) {
  const {ids} = await req.json()
  const id = ids?.created?.[0] || ids?.updated?.[0]
  if (!id) return new Response('No document ID', {status: 202})

  const doc = await sanity.fetch(
    `*[_id == $id][0]{
      _id,
      title,
      "imageUrl": mainImage.asset->url,
      "filename": mainImage.asset->originalFilename,
      filestackHandle
    }`,
    {id}
  )

  if (!doc?.imageUrl || doc.filestackHandle) {
    return Response.json({skipped: true})
  }

  const stored = await fsClient.storeURL(doc.imageUrl, {
    filename: doc.filename || `${doc._id}.jpg`,
  })

  await sanity.patch(doc._id).set({
    filestackHandle: stored.handle,
    filestackUrl: stored.url,
    filestackSize: stored.size,
    filestackMimeType: stored.mimetype,
  }).commit()

  return Response.json({handle: stored.handle, url: stored.url})
}

07Why Sanity

How Sanity + Filestack works

Build your Filestack integration on Sanity

Sanity gives you the structured content foundation, real-time event system, and flexible APIs to connect Filestack to the media workflows your team actually runs.

Start building free →

08Comparison

CMS approaches to Filestack

CapabilityTraditional CMSSanity
Media data structureMedia often sits inside page fields or HTML, so sync code may need to parse content before sending files to Filestack.Typed JSON in the Content Lake gives Filestack clean asset URLs, alt text, usage context, and related document data.
Sync timingTeams often rely on manual exports, scheduled jobs, or plugin-specific hooks.GROQ-filtered webhooks and Functions can run Filestack sync logic on specific publish events without a separate worker.
Field-level query controlIntegration code may receive entire pages and discard most of the payload.GROQ can select asset URLs, filenames, alt text, locale, and referenced product data in one focused query.
Editorial workflowEditors may need to upload in one tool, paste a URL into another, and remember which renditions are approved.Sanity Studio can show the Sanity asset, Filestack handle, generated URL, Tasks, and approval fields in one editing interface.
Frontend deliveryTemplates may be tied to one website, making reuse across apps or feeds harder.The same document can expose Filestack URLs to web, mobile, commerce feeds, and AI agents from one structured back end.

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