Skip to content

Workflow API

The Workflow API manages Automation definitions, immutable published versions, and queued Runs. Use it when a service needs to provision or invoke repeatable evidence workflows wit

View as Markdown Open the plain-text version of this page.

Base URL:

text
https://api.provon.dev/v1

Public routes use a project API key. The key selects the project:

http
Authorization: Bearer <PROVON_API_KEY>
Content-Type: application/json
Capability Access
workflows:read List and read definitions, versions, Runs, and Step Runs
workflows:write Create, update, delete, publish, invoke, and control Runs

The default project key includes workflows:read, not workflows:write.

Route Forms#

Every route has two forms:

Caller Form
Project API key /v1/workflows/...
Signed-in Workbench client /v1/projects/:projectId/workflows/...

The same rule applies to /workflow-runs. Public integrations should use the shorter API-key form and must not mix a path project ID with a key from another project.

Endpoints#

Definitions#

Method Path Purpose
GET /workflows List workflow definitions
POST /workflows Create an editable definition
GET /workflows/:id Read a definition and published versions
PATCH /workflows/:id Update the editable definition
DELETE /workflows/:id Delete a definition
POST /workflows/:id/publish Validate and publish a new version
POST /workflows/:id/runs Queue a manual Run

Runs#

Method Path Purpose
GET /workflow-runs List Runs
GET /workflow-runs/:id Read a Run with its definition and steps
POST /workflow-runs/:id/cancel Cancel queued or running work
POST /workflow-runs/:id/retry Requeue failed, dead-letter, or cancelled work
POST /workflow-runs/:id/resume Resume queued or failed work

Paths in the tables are relative to https://api.provon.dev/v1.

Definition Model#

A workflow definition contains:

json
{
  "id": "workflow_01J...",
  "name": "Review a risky run",
  "description": "Create a Finding from reviewed manual input.",
  "status": "draft",
  "graph": {
    "nodes": [],
    "edges": []
  },
  "owner": "Reliability",
  "activeVersionId": null,
  "createdAt": 1760000000000,
  "updatedAt": 1760000000000,
  "publishedAt": null
}

Status is draft, active, paused, or archived. The editable graph is not executed directly. Publishing snapshots it into an immutable version and sets activeVersionId.

Each graph node requires:

Field Purpose
id Unique node ID inside the graph
kind trigger, control, or operation
op Implemented operation identifier
label Human-readable label
description Optional explanation
params Operation-specific configuration

Each edge requires id, source, and target. Branching edges also carry a typed branch such as true, false, case, default, success, or failure.

See Automations for supported trigger and operation families. The Workbench builder is the recommended way to discover operation parameters; the API graph is the persisted contract, not a second user-facing workflow language.

Create A Workflow#

This minimal draft accepts manual input and creates a Finding:

http
POST /v1/workflows
json
{
  "name": "Manual risk review",
  "description": "Create a Finding from an explicit invocation.",
  "status": "draft",
  "owner": "Reliability",
  "graph": {
    "nodes": [
      {
        "id": "manual",
        "kind": "trigger",
        "op": "trigger.manual",
        "label": "Manual",
        "params": {
          "inputSchema": "{\"fields\":[{\"key\":\"summary\",\"label\":\"Summary\",\"type\":\"text\",\"required\":true}],\"allowExtraFields\":false}"
        }
      },
      {
        "id": "finding",
        "kind": "operation",
        "op": "diagnostics.finding.create",
        "label": "Create a finding",
        "params": {
          "title": "Manual review: {{input.summary}}",
          "severity": "medium",
          "summary": "{{input.summary}}"
        }
      }
    ],
    "edges": [
      {
        "id": "manual-to-finding",
        "source": "manual",
        "target": "finding"
      }
    ]
  }
}

Successful creation returns 201:

json
{
  "workflow": {
    "id": "workflow_01J...",
    "name": "Manual risk review",
    "status": "draft"
  }
}

Client-supplied workflow IDs are ignored. Names must be unique inside the project.

Update And Publish#

PATCH /workflows/:id accepts any non-empty subset of:

json
{
  "name": "Manual incident review",
  "description": "Updated purpose",
  "status": "paused",
  "owner": "Agent platform",
  "graph": {
    "nodes": [],
    "edges": []
  }
}

Publish after the draft graph is complete:

http
POST /v1/workflows/workflow_01J.../publish

Publishing validates:

  • graph structure and node IDs;
  • trigger count and edge topology;
  • required operation parameters;
  • artifact compatibility between connected nodes;
  • runtime support for every operation.

An invalid graph returns 400 with error: "invalid_workflow_graph" and an issues array. A runtime that cannot report its workflow capabilities returns 503 with error: "workflow_runtime_unavailable".

Queue A Manual Run#

http
POST /v1/workflows/workflow_01J.../runs
Idempotency-Key: incident-1842-review
json
{
  "input": {
    "summary": "The agent claimed success after the refund tool returned HTTP 400."
  }
}

The API validates manual input against the trigger's input schema and enqueues execution. It does not execute the graph inside the HTTP request. Successful enqueue returns 201 with the Run detail.

Use a stable Idempotency-Key for retried client requests. The key is scoped to the manual workflow invocation and is stored as a stable trigger reference.

List Definitions#

http
GET /v1/workflows?status=active&limit=50

Query parameters:

Parameter Values
status draft, active, paused, or archived
limit Positive integer page size
cursor Opaque pagination.nextCursor

List items omit the complete graph and add nodeCount, runCount, and triggerOp. Read one definition when graph or version detail is required.

List And Inspect Runs#

http
GET /v1/workflow-runs?workflowId=workflow_01J...&status=failed&limit=50

Run filters:

Parameter Values
workflowId One workflow ID
status queued, running, completed, failed, dead_letter, or cancelled
limit Positive integer page size
cursor Opaque pagination.nextCursor

GET /workflow-runs/:id returns:

  • the complete Run, including input and output;
  • the current workflow definition when it still exists;
  • the immutable version used by the Run;
  • ordered Step Runs with node operation, attempts, input, output, and error.

Run Control#

Action Allowed source statuses Result
Cancel queued, running Run becomes cancelled
Retry failed, dead_letter, cancelled Run is requeued with more attempts
Resume queued, failed Existing Run is made runnable

Invalid transitions return 409. Retry or resume only after correcting the dependency that caused the failure; otherwise the same side effect can fail again.

Pagination#

Definition and Run lists return:

json
{
  "pagination": {
    "limit": 50,
    "nextCursor": "1760000000000\tworkflow_01J..."
  }
}

Pass nextCursor unchanged. Do not parse it or derive a new cursor from timestamps.

Errors#

Status Meaning
400 Invalid JSON, graph, field, cursor, or manual Run input
401 Public route did not receive a valid project API key
403 API key lacks workflows:read or workflows:write
404 Workflow, version, or Run was not found in the project
409 Name conflict, inactive workflow, or invalid transition
503 Queue or workflow runtime capability service unavailable
504 A workflow node timed out

Workflow-domain errors generally return a short machine-readable error string and optional message. Authentication errors use the shared structured API error body.