ClouisleClouisle

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 the code/data/msg envelope — 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 identifierOpaque string version_id (UUID)Integer version (the workflow's version counter)
Response envelopeMost endpoints return the payload directlyStandard {code, data, msg}
CapabilitiesHistory, diff, publish, archive, rollback, forkSnapshot list, detail, create snapshot, restore

Version Management (/api/v1/workflow-versions)

Endpoint Overview

MethodPathPurpose
POST/api/v1/workflow-versionsCreate a new version snapshot (write access)
GET/api/v1/workflow-versions/{workflow_id}/historyRetrieve 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}/publishPublish a version (requires workflow:publish)
POST/api/v1/workflow-versions/{workflow_id}/version/{version_id}/archiveArchive a version (write access)
GET/api/v1/workflow-versions/{workflow_id}/diffDiff two versions (requires from_version and to_version)
POST/api/v1/workflow-versions/{workflow_id}/rollbackRoll back to an earlier version (write access)
POST/api/v1/workflow-versions/{workflow_id}/forkFork a version into another workflow (source readable, target write access)
GET/api/v1/workflow-versions/{workflow_id}/statsVersion 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 development
  • published: The currently published version serving active runs
  • archived: Archived previous version
  • deprecated: 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 parameterTypeRequiredDefaultDescription
limitintegerNo20Number of versions, range 1-100
offsetintegerNo0Offset, minimum 0
statusstringNo-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_TOKEN

from_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_TOKEN

Besides 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_TOKEN

Response (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_TOKEN

Requires 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.

MethodPathPurposePermission
GET/api/v1/workflows/{workflow_id}/versionsList snapshots (newest version first)workflow:read + workflow access
GET/api/v1/workflows/{workflow_id}/versions/{version}Get a snapshot by integer versionworkflow:read + workflow access
POST/api/v1/workflows/{workflow_id}/versionsSnapshot the workflow's current stateWorkflow write access + workflow:update
POST/api/v1/workflows/{workflow_id}/versions/{version}/restoreRestore a snapshotWorkflow 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

CodeIdentifierDescription
2000UNAUTHORIZEDAuthentication missing or invalid
3000FORBIDDENInsufficient permissions or missing workflow:publish
4000NOT_FOUNDWorkflow or workflow version not found (workflow_version_not_found, workflow_version_diff_not_found)
1001VALIDATION_ERRORInvalid request parameters

Last Updated: 2026-09-26

How is this guide?

On this page