Definitions and instances
A definition describes a process. An instance is one run of that process.
A workflow definition is the authored, deployable description of a process. It combines fields, stages and transitions, activities and actions, conditions, effects, and guards into one versioned contract.
An instance is the durable state of one run. One definition can produce many instances, each with its own field values, current stage, history, pending effects, and child workflows.
Define a workflow
Use defineWorkflow to author a definition:
const articleReview = defineWorkflow({
name: 'article-review',
title: 'Article review',
initialStage: 'drafting',
fields: [
defineField({
type: 'subject',
name: 'subject',
initialValue: {type: 'input'},
required: true,
}),
],
stages: [
defineStage({
name: 'drafting',
transitions: [defineTransition({name: 'submit', to: 'review', when: 'true'})],
}),
defineStage({name: 'review'}),
],
})The definition is the complete authored contract. Deployment validates cross-field invariants, expands authoring conveniences, and produces the stored form used by the engine.
Deployments are immutable versions
Deploying validates the definition, expands authoring conveniences into stored primitives, and stores a content-addressed version. Deploying identical content is a no-op; changing the definition creates the next version.
An instance pins the definition version and a frozen definition snapshot when it starts. Redeploying therefore changes future runs without silently changing work already in flight.
Start an instance
The optional start block controls discovery and requirements. See the Start block reference for its complete shape.
Starting an instance creates one durable run from a deployed definition. Pass the definition name and any declared workflow inputs to engine.startInstance:
import {gdrFromResource} from '@sanity/workflow-engine'
const subject = gdrFromResource(
{type: 'dataset', id: 'yourprojectid.production'},
'article-123',
)
const {instance} = await engine.startInstance({
definition: 'article-review',
initialFields: [
{
type: 'subject',
name: 'subject',
value: {id: subject, type: 'article'},
},
],
})This supplies the subject input declared in the definition above. See Fields for input and subject declarations, and Conditions for controlling when a workflow may start.
Initial fields are a strict contract
The engine rejects an initial field when:
- Its name is not declared at workflow scope.
- Its declaration is not input-sourced.
- Its type does not match the declaration.
- The same field appears more than once.
evaluateStart returns allowed: false with the invalid fields. No instance is written.
What an instance stores
An instance is an engine-owned sanity.workflow.instance document. It records the pinned definition, current stage, resolved fields, stage-visit history, effects, child workflows, audit history, and lifecycle timestamps for one run.
To update an instance, use the engine rather than ordinary content patches.
Reference
Workflow definition
This is the top-level object passed to defineWorkflow(...). The engine compiles and deploys it as the versioned definition that instances reference.
Definition properties
The top-level properties accepted by defineWorkflow(...).
name
string
Stable identity used in deployed document IDs and subworkflow references.
title / description
string
Presentation metadata; description is optional.
initialStage
string
The stage entered when an instance starts.
stages
Stage[]
One or more stage declarations.
fields
FieldEntry[]
Optional workflow-scope fields that live for the instance lifetime.
groups
Group[]
Optional presentation groups that fields, activities, and actions may join.
predicates
Record<string, Condition>
roleAliases
Record<string, string[]>
Deployment-specific equivalences for advisory role checks.
lifecycle
standalone | child
Child definitions are intended to be spawned by a parent.
start
AuthoringStartBlock
Optional configuration for standalone-start discovery and requirements.
Named predicate context
Named predicates use the GROQ variables defined by the Conditions reference. This table shows which are available at this site.
Unavailable
$actor, $assigned, $can, $params, $row
Named predicates cannot reference other named predicates. See Conditions.
Available
$self, $fields, $parent, $ancestors, $stage, $now, $context, $effects, $effectStatus, $activities, $allActivitiesDone, $anyActivityFailed, $subworkflows
Always-bound instance variables.
Start block
The optional start block configures discovery and fresh standalone starts. See Start filters and requirements for behavior and evaluation context.
start: {
kind: 'interactive',
filter: "status == 'draft'",
requirements: [
{
type: 'singleSubject',
name: 'one-open-review',
title: 'Review already in progress',
},
{
type: 'groq',
name: 'article-ready',
title: 'Article is not ready',
query: '$fields.ready == true',
},
],
}kind
'interactive' | 'autonomous' | undefined
Classifies who normally initiates the workflow. Defaults to interactive; it does not gate startInstance.
filter
string | undefined
GROQ visibility predicate used during discovery. It does not gate startInstance.
requirements
StartRequirement[] | undefined
Ordered requirements enforced before a fresh standalone start. Every requirement must pass.
GROQ start requirement
Use a GROQ requirement when readiness depends on supplied workflow inputs.
type
'groq'
Selects GROQ evaluation.
name
string
Unique name within the start requirements array. Verdicts identify the requirement by this name.
title
string | undefined
Optional editor-facing label.
description
string | undefined
Optional editor-facing explanation.
query
string
GROQ condition evaluated against the start input context.
Single-subject start requirement
Use a single-subject requirement to permit at most one unfinished run of this definition for the same subject. It requires one first-class input-sourced subject field; see Allow one active workflow per subject.
type
'singleSubject'
Selects definition-scoped subject exclusivity.
name
string
Unique name within the start requirements array. Verdicts identify the requirement by this name.
title
string | undefined
Optional editor-facing label.
description
string | undefined
Optional editor-facing explanation.
Workflow instance
A workflow instance is the engine-owned sanity.workflow.instance document returned by startInstance and subsequent engine verbs. Read it through the engine and change it only through engine verbs.
Identity and definition pin
These fields identify the run and preserve the definition it started with.
_id
string
Sanity document ID for the workflow instance.
_type
sanity.workflow.instance
Document type for a workflow instance.
tag
string
Engine environment partition that scopes instance reads.
workflowResource
WorkflowResource
Sanity resource where the instance is stored.
definition
string
Name of the deployed workflow definition.
pinnedVersion
number
Definition version selected when the instance started.
pinnedContentHash
string | undefined
Content hash of the pinned definition when available.
definitionSnapshot
string
Frozen JSON snapshot of the definition used at start.
State and hierarchy
These fields hold the instance’s resolved state and its place in a workflow hierarchy.
fields
ResolvedFieldEntry[]
Workflow-scope field values.
context
ContextEntry[]
Start context supplied once and read through $context.
ancestors
GlobalDocumentReference[]
Ancestor workflow instances, ordered root-first.
perspective
WorkflowPerspective | undefined
Perspective used for content reads.
currentStage
StageName
Name of the current stage.
stages
StageEntry[]
Stage visits in entry order; the current visit has no exitedAt.
subworkflows
SubworkflowEntry[] | undefined
Child workflows spawned by this instance.
Effects, history, and idempotency
These fields track queued work and committed engine activity.
pendingEffects
PendingEffect[]
Effects waiting to be claimed or completed.
effectHistory
EffectHistoryEntry[]
Completed effect results.
history
HistoryEntry[]
Committed engine events for the instance.
processedRequests
ProcessedRequest[] | undefined
Unexpired idempotency keys for committed operations.
Lifecycle and model compatibility
These fields record lifecycle timestamps and the persisted data-model contract.
startedAt
string
ISO-8601 timestamp set when the instance starts.
lastChangedAt
string
ISO-8601 timestamp of the latest engine commit.
completedAt
string | undefined
Set when the instance reaches any terminal state.
abortedAt
string | undefined
Set with completedAt when the instance is aborted.
modelVersion
number | undefined
Persisted data-model version written on the document.
minReaderModel
number | undefined
Oldest engine data model allowed to read the document.
Visiting agent?
Editorial Workflows includes an MCP server for inspecting, operating, authoring, validating, and deploying workflows. Ask your human to set up the MCP server.

