Publish content to Sanity from a workflow
Generate a Sanity document in a workflow, validate it against a schema, and publish it safely.
This guide publishes a document to a Sanity dataset from a workflow — for example, a case study generated from a recent customer conversation.
What You'll Build
A workflow that:
- Fetches a Sanity document schema.
- Uses an AI Prompt task to generate structured content.
- Publishes the document to Sanity.
- Optionally uploads images before publishing.
When to Use This
Use this pattern when GTM activity should create or update structured marketing content, such as case studies, customer stories, release notes, or sales enablement pages.
Estimated time: 20-30 minutes.
Concepts used: Workflows, Variables, AI Prompt task, Sanity tasks.
Prerequisites
You'll need:
- A Sanity project id.
- A dataset name, such as
production. - A document type to publish into, such as
caseStudy. - A non-production dataset for first tests, if possible.
1. Fetch the Schema
Add a Sanity Fetch Schema task as Step 1 of your workflow.
Configure:
- Project id: your Sanity project id
- Dataset: typically
production - Document type: the type you want to publish (for example
caseStudy)
The output exposes the schema as {{ steps.1.schema }}. Use it in the next step to make sure the document you build matches the schema.
2. Build the Document with an AI Prompt
Add an AI Prompt task and configure it to generate a structured object that matches the Sanity schema.
In the AI Prompt task, set:
- Generation type:
object - Output schema: generate one with the
generate_ai_schemautility — the workflow builder will offer this when generationType isobject. - System prompt: "You are an expert content writer for our marketing site. Produce a Sanity document that conforms exactly to the provided schema."
- User prompt:
Schema:
{{ steps.1.schema | json }}
Source material:
{{ inputs.transcript_summary }}
Produce a Sanity document of type "caseStudy" with all required fields populated.The | json filter is one of the available Liquid filters — others include json_compact, pluck, and typeof.
3. Publish the Document
Add a Sanity Publish Document task as Step 3.
Configure:
- Project id: the same Sanity project id
- Dataset: the same dataset
- Document id: generate a stable id, e.g.
case-study-{{ inputs.account_id }}. Reusing the id makes the publish idempotent — re-running the workflow updates the same document. - Document type:
caseStudy - Document:
{{ steps.2.object | json_compact }}
This task confirms the publish side effect at run time and validates that the JSON parses, but it does not re-validate the document against the schema — that's why Step 2 generated against the schema directly.
4. Upload Images (Optional)
If your document needs hosted images, use the Sanity task with mode: 'upload_image' before the publish step, and inline the returned asset reference into the document.
5. Test and Iterate
Run the workflow from the builder's Runs tab with a test account_id and a sample transcript_summary. The Sanity Studio for the project will show the published document.
If the document fails to validate in Sanity:
- Open the AI Prompt step's output and copy the generated JSON.
- Paste it into Sanity Studio's "create from JSON" or compare against the schema.
- Tighten the AI Prompt's
outputSchemaso the model produces conforming output every time.
Success Check
You are done when:
- The schema fetch step returns the expected document type.
- The AI Prompt step returns valid structured JSON.
- The publish step creates or updates the expected document id.
- The document appears in Sanity Studio with the expected fields populated.
Common Pitfalls
- The
apiVersionfield on Sanity tasks should match an api version your project supports (the default in newly-created tasks is2021-06-07, which is fine for most projects). - Re-running with the same
documentIdupdates the document. To create a new one each time, derivedocumentIdfrom a timestamp orrandom— but only do this if your editorial workflow can handle multiple drafts. - Side-effect tasks (publish, send email, Slack) run for real every time. Use the workflow builder's Test mode and start with a non-production dataset where possible.