First published timestamp
Automatically track when content was first published with a timestamp that sets once and never overwrites.
Deploy functions that respond to content changes or run on a schedule. Validate, enrich, sync, and integrate without external infrastructure.
Package functions as reusable modules to maintain consistent results and reduce code duplication. This approach allows you to build a library of tested, reliable functions that can be applied wherever needed.
Instantly create new functions from the CLI, test locally with the included development environment and deploy to production.
Use Functions to automatically translate new fields and documents, validate with AI, or invalidate the cache of your front-end.
The content automation toolkit
Turn any content change into a trigger using GROQ. Your functions can execute custom logics to maintain data consistency, trigger workflows, or perform automated tasks. No missed events, no delays.
import {defineBlueprint, defineDocumentFunction} from '@sanity/blueprints';
export default defineBlueprint({
resources: [
defineDocumentFunction({
name: "text-to-speech",
event: {
on: ["update"],
filter: "_type == 'event'",
projection: "{title, content}",
},
})
]
});Schedule recurring jobs in a Blueprint. No external cron tools to manage. Sync data nightly, invalidate caches, send scheduled notifications. Every Function runs with full access to your content.
// sanity.blueprint.ts
import {defineBlueprint, defineScheduledFunction} from '@sanity/blueprints';
export default defineBlueprint({
resources: [
defineScheduledFunction({
name: "nightly-sync",
event: {
expression: "0 0 * * *",
},
})
]
});Functions have you full access to your content model, documents and API capabilities, allowing them to perform complex operations while maintaining security. No more data transfers or permission juggling.
Functions makes every “if this, then that” scenario you’ve ever wanted possible. Make any mutation the beginning of any content process orchestration.
import { textToSpeech } from "./text-to-speech";
export const handler = documentEventHandler(async ({ context, event }) => {
const audio = await textToSpeech(event.doc.content);
const client = createClient({
...context.clientOptions,
apiVersion: "2025-05-08",
});
await client.assets.upload("file", audio, {
filename: `${event.doc.title}.mp3`,
contentType: "audio/mpeg",
});
console.log("Audio generated and uploaded successfully");
});Use Functions to invoke the Agent API in response to content updates or on a recurring cadence. Automate enrichment, tagging, localization, or rewriting, whether triggered by a publish event or a nightly cron job, directly inside your workflows.
Add a function from a recipe with a single command. The code is already written. The infrastructure is managed.
It's incredibly easy to push data into Sanity Content Lake from outbound systems. With the Sanity API, I'm not making 10,000 calls to update 10,000 items. I'm making one API call and the whole dataset is updated.
Kevin HarwoodCTO
Sign up for Sanity for free and start crafting your first project.
import {defineBlueprint, defineDocumentFunction} from '@sanity/blueprints';
export default defineBlueprint({
resources: [
defineDocumentFunction({
name: "text-to-speech",
event: {
on: ["update"],
filter: "_type == 'event'",
projection: "{title, content}",
},
})
]
});// sanity.blueprint.ts
import {defineBlueprint, defineScheduledFunction} from '@sanity/blueprints';
export default defineBlueprint({
resources: [
defineScheduledFunction({
name: "nightly-sync",
event: {
expression: "0 0 * * *",
},
})
]
});import { textToSpeech } from "./text-to-speech";
export const handler = documentEventHandler(async ({ context, event }) => {
const audio = await textToSpeech(event.doc.content);
const client = createClient({
...context.clientOptions,
apiVersion: "2025-05-08",
});
await client.assets.upload("file", audio, {
filename: `${event.doc.title}.mp3`,
contentType: "audio/mpeg",
});
console.log("Audio generated and uploaded successfully");
});