Content releases and versions with @sanity/client
Learn how to create releases, manage document versions, and schedule publishing using the Sanity JavaScript client.
Content releases let you group document changes and publish them together. The @sanity/client library provides helper methods on the client.releases namespace for managing releases, along with top-level methods for working with document versions.
These methods require an authenticated client with a write token. See Getting started with @sanity/client for setup instructions.
For a conceptual overview of how content releases work, see the Content Releases user guide. For the underlying HTTP endpoints, see the Content Releases API.
Create a release
Use client.releases.create() to create a new release. The method returns an object containing the releaseId, which you use to add document versions to the release.
const {releaseId} = await client.releases.create({
metadata: {
title: 'Spring product launch',
releaseType: 'scheduled',
},
})
console.log('Created release:', releaseId)The releaseType can be scheduled, asap, or undecided.
Add document versions to a release
Use client.createVersion() to add a document version to a release. The most common case is versioning an existing published document. The example below shows the inline document form, which is appropriate when you want to set the version's content explicitly. To create a version of an existing published document while letting Sanity copy its current content for you, use baseId instead. See Choosing between baseId and inline document below.
await client.createVersion({
releaseId,
publishedId: 'product-123',
document: {
_type: 'product',
title: 'Updated spring collection',
price: 59.99,
},
})This creates a versioned document with the ID versions.<releaseId>.product-123 in your dataset. The published document remains unchanged until the release is published.
Choosing between baseId and inline document
When you create a version of an existing published document, prefer baseId. Sanity copies the current published content into the version for you, so you don't have to fetch and repackage it client-side. Pass an inline document only when you want to set the version's content explicitly, for example when creating a new document that doesn't exist in published form yet.
await client.createVersion({
releaseId,
publishedId: 'product-123',
baseId: 'product-123',
})This snapshots the current published product-123 into the release as a version. baseId is the source of the version's content; publishedId is the logical document the version refers to. In the common case where you are versioning a document's own published edition, both values are the same.
Mark a document for unpublishing
Use client.unpublishVersion() to mark a document for removal when the release runs. The document stays published until the release is executed.
await client.unpublishVersion({
releaseId,
publishedId: 'product-456',
})Get a release and its documents
Retrieve a release's metadata with client.releases.get(), and list its documents with client.releases.fetchDocuments().
// Get the release metadata
const release = await client.releases.get({releaseId})
console.log(release.metadata.title) // 'Spring product launch'
console.log(release.state) // 'active'
// List all documents in the release
const {result: documents} = await client.releases.fetchDocuments({releaseId})
console.log(`Release contains ${documents.length} documents`)Schedule a release
Schedule a release to publish at a specific time with client.releases.schedule(). Pass an ISO 8601 date string as the publishAt value.
// Schedule the release for one hour from now
const publishAt = new Date(Date.now() + 60 * 60 * 1000).toISOString()
await client.releases.schedule({
releaseId,
publishAt,
})
console.log(`Release scheduled for ${publishAt}`)Delete a release after publishing
After a release has been published, you can clean it up with client.releases.delete(). Check the release state first to confirm it has completed successfully.
const release = await client.releases.get({releaseId})
if (release.state === 'published' && !release.error) {
await client.releases.delete({releaseId})
console.log('Release deleted')
}Full example: create and schedule a release
Here's a complete workflow that creates a release, adds document versions, and schedules it to publish:
import {createClient} from '@sanity/client'
const client = createClient({
projectId: 'YOUR_PROJECT_ID',
dataset: 'YOUR_DATASET',
apiVersion: '2026-03-01',
useCdn: false,
token: process.env.SANITY_TOKEN,
})
// 1. Create a release
const {releaseId} = await client.releases.create({
metadata: {
title: 'Spring product launch',
releaseType: 'scheduled',
},
})
// 2. Add a new version of an existing product
await client.createVersion({
releaseId,
publishedId: 'product-123',
document: {
_type: 'product',
title: 'Updated spring jacket',
price: 89.99,
},
})
// 3. Mark an old product for removal
await client.unpublishVersion({
releaseId,
publishedId: 'product-old-winter-coat',
})
// 4. Verify the release contents
const {result: documents} = await client.releases.fetchDocuments({releaseId})
console.log(`Release contains ${documents.length} document(s)`)
// 5. Schedule the release
await client.releases.schedule({
releaseId,
publishAt: '2026-04-01T09:00:00.000Z',
})
console.log('Release scheduled for April 1')Release actions with the Actions API
The helper methods shown above use the client.action() method under the hood. If you need more control, you can dispatch release actions directly. This lets you archive, unarchive, and unschedule releases, as well as create, discard, and replace individual document versions.
For example, to archive and then unarchive a release:
// Archive a release
await client.action({
actionType: 'sanity.action.release.archive',
releaseId: 'spring-launch',
})
// Unarchive it later
await client.action({
actionType: 'sanity.action.release.unarchive',
releaseId: 'spring-launch',
})You can also manage individual document versions through actions:
// Create a version of a document in a release
await client.action({
actionType: 'sanity.action.document.version.create',
publishedId: 'product-123',
document: {
_id: 'versions.spring-launch.product-123',
_type: 'product',
},
})
// Discard a version
await client.action({
actionType: 'sanity.action.document.version.discard',
versionId: 'versions.spring-launch.product-123',
})
// Replace a version's contents
await client.action({
actionType: 'sanity.action.document.version.replace',
document: {
_id: 'versions.spring-launch.product-123',
_type: 'product',
title: 'Revised spring jacket',
price: 79.99,
},
})For the full list of available action types and their options, see Mutate documents with actions.
Next steps
- Content Releases user guide: Learn how releases work in Sanity Studio.
- Content Releases API: HTTP endpoint reference for the releases API.
- Mutate documents with actions: Dispatch release and version actions directly through the Actions API.
- Release Actions: Reference for all release action types.