Publish the Workflow draft as a new version
POST /v1/workflows/{workflow_id}/versions
| Property | Value |
|---|---|
| Operation | publish_workflow_version |
| Group | Workflows |
| Scope | workflows:write |
| Route class | control |
| Idempotency | Idempotency-Key accepted: a retry with the same key replays the first answer |
| Audit | Audited workflow.version.publish (mutation) |
| Released in | 1.59.0 |
| Phase 0 host | Served (the hosted api pins 1.65.0) |
Publishes the draft that If-Match names as the next version once every check of a create passes again (1.59.0): it compiles the definition into the form the Session runs, records the digest, the format and engine versions and pins the default Agent's active version. With activate the new version becomes the active one, the version the next Agent version publish pins.
Request
Set VOCAL_API to the base URL of your API and VOCAL_API_KEY to an API key with the workflows:write scope (Authentication and keys). Replace each placeholder, such as agt_... or <name>, with your own value.
curl -X POST "$VOCAL_API/v1/workflows/wfl_.../versions" \
-H "Authorization: Bearer $VOCAL_API_KEY" \
-H 'If-Match: "1"' \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{}'const response = await fetch(`${process.env.VOCAL_API}/v1/workflows/wfl_.../versions`, {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.VOCAL_API_KEY}`,
'If-Match': '"1"',
'Idempotency-Key': crypto.randomUUID(),
'Content-Type': 'application/json',
},
body: JSON.stringify({}),
});
console.log(response.status, await response.text());import os
import uuid
import requests
response = requests.post(
f"{os.environ['VOCAL_API']}/v1/workflows/wfl_.../versions",
headers={
"Authorization": f"Bearer {os.environ['VOCAL_API_KEY']}",
"If-Match": '"1"',
"Idempotency-Key": str(uuid.uuid4()),
},
json={},
)
print(response.status_code, response.text)Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
workflow_id | path | WorkflowId | yes | The id of a Workflow: wfl_ and the row's UUIDv7 in 26 Crockford base32 characters. Opaque and safe to log. |
if-match | header | string | yes | The revision the change was made against, quoted as the ETag returns it, or * to overwrite. |
idempotency-key | header | string | no | A client-chosen key, kept 24 hours per Organization, environment and route. A replay returns the stored response. |
Request body
Content type application/json, required: WorkflowVersionPublishRequest.
| Field | Type | Required | Description |
|---|---|---|---|
activate | boolean | no | Make the new version the active one; false when omitted. |
notes | string | no | Why this version exists. |
Responses
| Status | Content type | Shape | Error codes |
|---|---|---|---|
201 | application/json | WorkflowVersion | |
400 | application/json | ErrorEnvelope | invalid_request |
401 | application/json | ErrorEnvelope | unauthenticated |
403 | application/json | ErrorEnvelope | forbidden, org_suspended |
404 | application/json | ErrorEnvelope | not_found |
409 | application/json | ErrorEnvelope | workflow_archived, idempotency_in_progress, idempotency_key_reused |
412 | application/json | ErrorEnvelope | revision_mismatch |
422 | application/json | ErrorEnvelope | validation_failed, capability_not_available |
428 | application/json | ErrorEnvelope | precondition_required |
429 | application/json | ErrorEnvelope | rate_limited |
500 | application/json | ErrorEnvelope | internal_error |
Fields of the 201 answer
The shape is WorkflowVersion.
| Field | Type | Required | Description |
|---|---|---|---|
active | boolean | yes | True for the active version: the one the next Agent version publish pins. |
agent_id | AgentId | no | Conversation scope only, and required there: the default Agent, which supplies voice, transcriber, model, Policies, Tools and destinations. |
correlation | WorkflowCorrelation | no | |
description | string or null | yes | |
engine_version | string | yes | The Zen engine version the version's decisions and expressions were checked under. |
entry | WorkflowNodeId | yes | |
format_version | integer | yes | The version of the compiled form the Session runs, 1 in this release. |
graph_sha256 | string | yes | The SHA-256 of the canonical JSON (RFC 8785) of the definition as published, in lowercase hex. |
inputs | map of WorkflowField | no | Call variables (conversation) or start inputs (process). |
limits | WorkflowLimits | yes | |
name | string | yes | Kebab-case, unique per Organization. |
nodes | array of WorkflowNode | yes | Exactly one entry node; at most 200 nodes, loop bodies included (target). |
notes | string or null | yes | |
object | "workflow_version" | yes | |
outputs | map of WorkflowField | no | The typed result returned to a parent or a starting Process. |
pins | WorkflowPins | yes | |
published_at | Timestamp | yes | |
published_by | ActorRef | yes | |
scope | WorkflowScope | yes | |
settings | map of WorkflowSetting | no | Process scope: named thresholds and constants that evaluate nodes read. |
slots | map of WorkflowField | no | Conversation scope: the Session's typed slots. |
source_revision | integer | yes | The draft revision this version was published from. |
status | WorkflowVersionStatus | yes | |
vars | map of WorkflowField | no | Process scope: the instance's working data. |
version | integer | yes | The snapshot number, from 1. |
workflow_id | WorkflowId | yes |