Skip to content

Sanity

Two-way sync Sanity documents with Airtable, Notion, Google Sheets, and more. Covers Studio schema deployment, API tokens, supported fields, and publishing.

This guide covers how to connect Whalesync to a Sanity project, what you need to do in Sanity first, and which fields sync.

In Whalesync terms, a Sanity dataset is the base you pick, each document type in your Studio schema is a table, and each document is a record.

Before you connect: deploy your Studio schema

Section titled “Before you connect: deploy your Studio schema”

Deploying takes one command in your Sanity Studio project (Studio 3.88 or newer):

Terminal window
npx sanity schema deploy

Run it as a logged-in Studio developer, or with an Editor-role token in SANITY_AUTH_TOKEN. See Sanity's guide: Schema deployment.

Whenever you change your Studio schema, deploy it again and then refresh the schema in Whalesync so the new fields appear.

Whalesync connects with a Sanity API token. See Authorize Sanity for the steps to create one.

  1. In Whalesync, choose Sanity and paste the token.
  2. If the token can access more than one project, enter the Project ID as well. Robot tokens are usually scoped to one project, so most people can leave it blank.
  3. Pick the dataset to sync. Datasets without a deployed schema are listed but cannot be selected until you deploy one.

Every document type in the deployed schema is available as a table, including types that have no documents yet. Nested objects (for example an seo object with metaTitle and metaDescription) appear as separate fields named seo / Meta title, so each part can be mapped on its own.

Whalesync does not support every Sanity field type yet. If you need one that is missing, reach out and let us know.

Sanity typeStatusNotes
String✅ SupportedA string with an options.list is offered as a select, but Whalesync does not enforce the list.
Text✅ Supported
Number✅ Supported
Boolean✅ Supported
Date✅ SupportedDate only, no time.
Datetime✅ Supported
URL✅ Supported
Email✅ Supported
Slug✅ SupportedSynced as the slug text.
Reference (one target type)✅ SupportedSynced as a link to the target document type. Weak references stay weak.
Array of references✅ SupportedSynced as a multi-link field.
Array of strings✅ Supported
Portable Text (block content)✅ SupportedSynced as HTML, including image and code blocks when your Studio schema allows them.
Image✅ SupportedSynced as the image's CDN URL. Writing a URL uploads the image to Sanity.
File✅ SupportedSynced as the file's CDN URL. Writing a URL uploads the file to Sanity.
Object✅ SupportedFlattened into one field per sub-field, up to three levels deep. Deeper objects are synced as JSON, read only.
Reference (several target types)➡️ Supported (1-Way)Read only. Whalesync links point at one table, so the target document id is synced as text.
Geopoint✅ Supported (as JSON)Read only.
Array of objects or images✅ Supported (as JSON)Read only.
Fields marked readOnly in the Studio➡️ Supported (1-Way)Read only in Whalesync too.
Cross-dataset and global references✅ Supported (as JSON)Read only.

Whalesync adds fields that are not part of your Studio schema.

FieldExplanationWritable
Record IDThe document's _id. When creating a document from another app, map this field to choose the id; it cannot be changed afterwards.Once, on create
StatusDraft, Changed, or Published. Shows which versions of the document exist, and setting it publishes the document, keeps your edits unpublished, or unpublishes it. Must be mapped. See Status field.Yes
Created atThe document's _createdAt.No
Updated atThe document's _updatedAt. When a draft exists, this is the draft's timestamp.No

Sanity stores a document's published version and its draft as two separate documents. So you can sync a whole document type to one table in your other app, Whalesync shows the pair as one record and adds a Status field that says which versions exist. When a draft exists, the record shows the draft's values.

Every Sanity table mapping must include Status. Whalesync uses it to tell an edit meant for the live document from one meant for a pending draft, so the field mapping screen shows an error until it's mapped.

Status Draft exists? Published exists? What it means
Draft ✅ ❌ The document only exists as a draft: it has never been published, or it was unpublished. Your edits go to the draft. To publish it, change Status to Published.
Published ❌ ✅ The document is live and hasn't changed since it was last published. Edits from your other app go live right away. To keep edits unpublished, change Status to Changed first. If someone edits the document in the Studio, the Studio creates a draft and Status becomes Changed.
Changed ✅ ✅ The document is live, and it has changed since it was last published. Your edits go to the draft. To publish them, change Status to Published. To unpublish the document, change Status to Draft.
Change Result
Draft → Published Publishes the document for the first time.
Published → Changed Starts a new version by copying the live document into a draft. Any other edits in the same change go into the draft. Editing in the Studio does this automatically.
Changed → Published Publishes the draft, including any other edits made in the same change, and removes the draft.
Published → Draft, or Changed → Draft Unpublishes the document. It's taken down, and its content, including any pending edits and any other edits in the same change, is kept as a draft.
Draft → Changed Not allowed. Changed means a live document with pending edits, and this one has never been published.
Status cleared (empty) Not allowed.

Discarding a draft can only be done in the Studio.

When a change isn't allowed, nothing is written to Sanity, and the record shows a sync issue until Status is set to an allowed value. The issue says one of:

  • "Status Changed means a published document with unpublished edits, and this document has never been published. Set Status to Draft or Published."
  • "A Sanity document's Status can't be empty. Set it to Draft, Changed, or Published."
  • Status empty or Published: the document is created and published.
  • Status Draft: the document is created as a draft.
  • Status Changed: not allowed, since a new document has no live version.
  • Your other app is the source of truth: keep Status at Published, and every edit goes live.
  • Review before publishing: create records with Status set to Draft. An editor reviews and publishes them in the Studio, or you set Status to Published.
  • Prepare the next version of a live page: set Status to Changed, edit the record over as many syncs as you like, then set Status to Published to put the edits live.
  • Take a page down: set Status to Draft. The content is kept as a draft, so you can publish it again later.

Deleting a record removes both the published document and its draft.

  • The deployed schema is the schema. A field you add in Studio code does not exist for Whalesync until you run npx sanity schema deploy again and refresh the schema in Whalesync.
  • The token needs the Editor role. A Viewer token can read your dataset but every create, update, and delete fails with a permissions error.
  • Sanity refuses to delete a referenced document. If another document holds a strong reference to it, Sanity blocks the delete until the reference is removed or made weak.
  • Content Releases are not synced. Documents that only exist inside a release are ignored.
  • Studio autosaves as you type, so a document you are editing in the Studio updates its draft many times. Whalesync syncs the latest state.