Workflow Versions API
Version snapshots, history, diff, publish, archive, rollback, and forking for workflow graphs
The Workflow Versions API manages version snapshots of a workflow graph (nodes & edges): history, diff, publish, archive, rollback, and forking.
- Version management base path:
/api/v1/workflow-versions(most success responses in this module do not use thecode/data/msgenvelope — they return the payload directly; errors still use the standard envelope) - Version snapshot base path:
/api/v1/workflows/{workflow_id}/versions(uses the standard{code, data, msg}envelope)
Two unrelated version APIs share similar naming. Decide which one you need first:
/api/v1/workflow-versions/... | /api/v1/workflows/{workflow_id}/versions | |
|---|---|---|
| Version identifier | Opaque string version_id (UUID) | Integer version (the workflow's version counter) |
| Response envelope | Most endpoints return the payload directly | Standard {code, data, msg} |
| Capabilities | History, diff, publish, archive, rollback, fork | Snapshot list, detail, create snapshot, restore |
Version Management (/api/v1/workflow-versions)
Endpoint Overview
| Method | Path | Purpose |
|---|---|---|
| POST | /api/v1/workflow-versions | Create a new version snapshot (write access) |
| GET | /api/v1/workflow-versions/{workflow_id}/history | Retrieve version history |
| GET | /api/v1/workflow-versions/{workflow_id}/version/{version_id} | Get a specific version |
| POST | /api/v1/workflow-versions/{workflow_id}/version/{version_id}/publish | Publish a version (requires workflow:publish) |
| POST | /api/v1/workflow-versions/{workflow_id}/version/{version_id}/archive | Archive a version (write access) |
| GET | /api/v1/workflow-versions/{workflow_id}/diff | Diff two versions (requires from_version and to_version) |
| POST | /api/v1/workflow-versions/{workflow_id}/rollback | Roll back to an earlier version (write access) |
| POST | /api/v1/workflow-versions/{workflow_id}/fork | Fork a version into another workflow (source readable, target write access) |
| GET | /api/v1/workflow-versions/{workflow_id}/stats | Version statistics (write access) |
Every endpoint requires an authenticated JWT user session, and the caller must be able to access the target workflow; "write access" means write access to the workflow (PRIVATE workflows are creator-only, team workflows need a team role). If version_id does not belong to that workflow, the call returns 404 workflow_version_not_found.
Version Status Enum
draft: Draft version under developmentpublished: The currently published version serving active runsarchived: Archived previous versiondeprecated: Deprecated version
1. Create a Version Snapshot
POST /api/v1/workflow-versions HTTP/1.1
Authorization: Bearer YOUR_TOKEN
Content-Type: application/json
{
"workflow_id": "550e8400-e29b-41d4-a716-446655440000",
"nodes": [
{"id": "node_1", "type": "start", "data": {}},
{"id": "node_2", "type": "llm", "data": {"prompt": "Summarize input"}}
],
"edges": [
{"id": "e1-2", "source": "node_1", "target": "node_2"}
],
"config": {},
"description": "Add LLM summarization step"
}config is optional (default {}) and is merged with nodes/edges into the version definition; description is optional (defaults to an empty string).
Response (200 OK, no envelope):
{
"version_id": "7f9c2d1e-1234-4567-89ab-cdef01234567",
"version_number": 3,
"status": "draft",
"created_at": "2026-09-14T10:30:00Z"
}2. View History
GET /api/v1/workflow-versions/{workflow_id}/history?limit=20&offset=0&status=published HTTP/1.1
Authorization: Bearer YOUR_TOKEN| Query parameter | Type | Required | Default | Description |
|---|---|---|---|---|
limit | integer | No | 20 | Number of versions, range 1-100 |
offset | integer | No | 0 | Offset, minimum 0 |
status | string | No | - | Filter by status: draft, published, archived, deprecated |
The response is { "versions": [...], "total": N }, where total is the number of versions returned in this call (not the database total).
3. Compare Versions (Diff)
GET /api/v1/workflow-versions/{workflow_id}/diff?from_version=v_1&to_version=v_2 HTTP/1.1
Authorization: Bearer YOUR_TOKENfrom_version and to_version are both required and are version IDs (version_id), not semantic version names or integer version numbers.
Response (200 OK, no envelope):
{
"from_version": "v_1",
"to_version": "v_2",
"diff": {
"from_version": "v_1",
"to_version": "v_2",
"nodes_added": [{"id": "node_2", "type": "llm", "label": "Summarize"}],
"nodes_removed": [],
"nodes_modified": [
{
"id": "node_http_query",
"type": "http",
"changes": [
{"field": "data.timeout", "from": 30, "to": 60},
{"field": "position", "type": "moved"}
]
}
],
"edges_added": [{"source": "node_1", "target": "node_2", "sourceHandle": null}],
"edges_removed": [],
"config_changes": {},
"has_changes": true,
"change_summary": "+1 nodes, ~1 nodes modified, +1 edges"
}
}The outer payload is always {from_version, to_version, diff}; the diff object contains nodes_added, nodes_removed, nodes_modified, edges_added, edges_removed, config_changes, has_changes, and change_summary. A missing workflow or a version that does not belong to it returns 404.
4. Publish a Version
POST /api/v1/workflow-versions/{workflow_id}/version/{version_id}/publish HTTP/1.1
Authorization: Bearer YOUR_TOKENBesides workflow write access, this requires the team permission workflow:publish.
Response (200 OK, no envelope):
{
"success": true,
"status": "published"
}5. Archive a Version
POST /api/v1/workflow-versions/{workflow_id}/version/{version_id}/archive HTTP/1.1
Authorization: Bearer YOUR_TOKENResponse (200 OK, no envelope):
{
"success": true,
"status": "archived"
}6. Rollback to a Version
POST /api/v1/workflow-versions/{workflow_id}/rollback HTTP/1.1
Authorization: Bearer YOUR_TOKEN
Content-Type: application/json
{
"version_id": "v_1",
"create_backup": true
}create_backup is optional and defaults to true.
Response (200 OK, no envelope):
{
"success": true,
"new_version_id": "v3-uuid",
"backup_version_id": null
}7. Fork a Workflow
Forking copies one version's graph definition into another existing workflow; both version_id (the source version) and new_workflow_id (the target workflow) are required.
POST /api/v1/workflow-versions/{workflow_id}/fork HTTP/1.1
Authorization: Bearer YOUR_TOKEN
Content-Type: application/json
{
"version_id": "v_1",
"new_workflow_id": "660e8400-e29b-41d4-a716-446655440001",
"new_name": "Forked Support Workflow"
}Response (200 OK, no envelope):
{
"success": true,
"new_version_id": "v1-uuid-fork"
}8. Version Statistics
GET /api/v1/workflow-versions/{workflow_id}/stats HTTP/1.1
Authorization: Bearer YOUR_TOKENRequires workflow write access. The payload is returned directly (no envelope):
{
"total_versions": 4,
"published_versions": 2,
"draft_versions": 1,
"archived_versions": 1,
"first_version_date": "2026-01-04T10:15:00",
"latest_version_date": "2026-02-11T09:02:31"
}Version Snapshots (/api/v1/workflows/{workflow_id}/versions)
These routes belong to the Workflows router and manage integer-numbered snapshots of a single workflow. They are separate from the /api/v1/workflow-versions/... routes above and use the standard {code, data, msg} envelope.
| Method | Path | Purpose | Permission |
|---|---|---|---|
| GET | /api/v1/workflows/{workflow_id}/versions | List snapshots (newest version first) | workflow:read + workflow access |
| GET | /api/v1/workflows/{workflow_id}/versions/{version} | Get a snapshot by integer version | workflow:read + workflow access |
| POST | /api/v1/workflows/{workflow_id}/versions | Snapshot the workflow's current state | Workflow write access + workflow:update |
| POST | /api/v1/workflows/{workflow_id}/versions/{version}/restore | Restore a snapshot | Workflow write access + workflow:update |
{version} is the workflow's version counter (an integer), not a UUID. page (default 1) and page_size (default 20) are query parameters for the list endpoint.
List Snapshots
GET /api/v1/workflows/{workflow_id}/versions?page=1&page_size=20 HTTP/1.1
Authorization: Bearer <token>Each item in data.items contains id, workflow_id, version, description, created_by_id, and created_at.
Create a Snapshot
POST /api/v1/workflows/{workflow_id}/versions HTTP/1.1
Authorization: Bearer <token>
Content-Type: application/json
{
"description": "Before refactor"
}This snapshots the workflow's current state at its current version number; the counter is not incremented. data is the created WorkflowVersionOut.
Restore a Snapshot
POST /api/v1/workflows/{workflow_id}/versions/3/restore HTTP/1.1
Authorization: Bearer <token>
Content-Type: application/json
{
"description": "Restored after bad edit"
}Restore first saves the current state as an automatic backup snapshot, then writes back the target snapshot's definition/variables/trigger_type/trigger_config, increments the workflow's version counter, and creates another snapshot for the restored state. description is optional; when omitted, a default localized description is generated. data is the updated WorkflowOut.
Workflow Template Marketplace
Not implemented / Roadmap
There is no workflow template marketplace HTTP API. A template manager, TemplateManager (backend/app/services/workflow/templates.py), exists in code and is unit-tested, but no router mounts it, so /api/v1/workflow-templates and all of the endpoints previously listed here (list, featured, search, categories, detail, publish, instantiate, rate, delete, stats) are not implemented. TemplateManager is service-only and cannot be reached over HTTP.
Error Codes
| Code | Identifier | Description |
|---|---|---|
2000 | UNAUTHORIZED | Authentication missing or invalid |
3000 | FORBIDDEN | Insufficient permissions or missing workflow:publish |
4000 | NOT_FOUND | Workflow or workflow version not found (workflow_version_not_found, workflow_version_diff_not_found) |
1001 | VALIDATION_ERROR | Invalid request parameters |
Last Updated: 2026-09-26
How is this guide?