Workflows and Runs
Workflow list, dispatch, run status, run logs, and execution behavior for the Numora Public API developer preview.
Scope
This page defines how the public API should expose workflow execution and run history.
It covers:
- Workflow listing
- Manual dispatch
- Run status and derived outcomes
- Node-level execution logs
- Retry and execution guidance
Public Workflow Model
The public workflow surface should stay intentionally small.
Currently available in developer preview:
GET /v1/workflowsPOST /v1/workflows/{id}/dispatchGET /v1/runs/{id}GET /v1/runs/{id}/logs
The current app already has richer internal workflow routes, but the public contract should expose only stable workflow metadata and execution state first.
List Workflows
GET /v1/workflows
Recommended response:
{
"data": [
{
"id": "wf_01jpx8t0v5lg1sq3wy6c5c7h2x",
"name": "Reviewed Invoice Push",
"status": "active",
"version": 7,
"binding_count": 1,
"updated_at": "2026-03-21T16:00:00.000Z"
}
]
}Recommended public fields:
idnamestatusversionbinding_countupdated_at
The public workflow resource should not default to exposing the full definition JSON, connection snapshots, or editor-only metadata.
Dispatch a Workflow
POST /v1/workflows/{id}/dispatch
Use this endpoint to create a run for a specific document.
This endpoint is now available in developer preview. The first public version only supports execution_mode=queued and always uses the workflow's default binding.
Recommended request:
{
"document_id": "doc_01jpwq4q9m7q4q2k8dax1x1q5n",
"execution_mode": "queued"
}Recommended response:
{
"run_id": "run_01jpx91kby4k7saz7y2qf1k2nm",
"workflow_id": "wf_01jpx8t0v5lg1sq3wy6c5c7h2x",
"status": "queued",
"execution_mode": "queued"
}Notes:
- Clients should treat dispatch as asynchronous by default.
- The first public API version always returns
202 Acceptedand does not execute inline in the request. - If retry is needed, the safest public model is to create a new run through dispatch instead of mutating a finished run in place.
Run Status
The run resource should support these lifecycle values:
queuedrunningsuccessfailedcancelled
The current app already persists queued and running states, claims queued runs for execution, and recovers expired running runs as failed.
Derived Delivery Outcome
Run status alone is not always enough for operational debugging.
The current app already derives a higher-level delivery outcome from the node log. The public run resource should expose that summary directly.
Recommended outcome values:
queuedfailedwroteno_writecompleted
Recommended meanings:
wrote: at least one write node completed successfullyno_write: the run succeeded, but no downstream write occurredcompleted: the run succeeded without a write-focused outcome
Get Run Detail
GET /v1/runs/{id}
Recommended response:
{
"id": "run_01jpx91kby4k7saz7y2qf1k2nm",
"workflow_id": "wf_01jpx8t0v5lg1sq3wy6c5c7h2x",
"document_id": "doc_01jpwq4q9m7q4q2k8dax1x1q5n",
"status": "success",
"delivery_outcome": "wrote",
"delivery_outcome_reason": "dataverse_add_row created 1 row(s)",
"created_at": "2026-03-21T16:02:00.000Z",
"started_at": "2026-03-21T16:02:01.000Z",
"finished_at": "2026-03-21T16:02:04.000Z",
"error_summary": null
}Recommended public detail fields:
idworkflow_iddocument_idstatusdelivery_outcomedelivery_outcome_reasoncreated_atstarted_atfinished_aterror_summary
The current internal run record also stores definitionSnapshot, connectionSnapshot, triggerEventSnapshot, context, and nodeLog. Those are useful for audit and execution, but they should not all be dumped into the default public run response.
Get Run Logs
GET /v1/runs/{id}/logs
Node-level run logs are now available in developer preview.
Recommended response:
{
"data": [
{
"node_id": "node_ocr_confirmed",
"node_type": "load_ocr_confirmed_data",
"status": "success",
"attempts": 1,
"duration_ms": 42,
"started_at": "2026-03-21T16:02:01.000Z",
"finished_at": "2026-03-21T16:02:01.042Z",
"output": "loaded reviewed OCR data"
},
{
"node_id": "node_write",
"node_type": "dataverse_add_row",
"status": "success",
"attempts": 1,
"duration_ms": 261,
"started_at": "2026-03-21T16:02:03.000Z",
"finished_at": "2026-03-21T16:02:03.261Z",
"output": "dataverse_add_row created 1 row(s)"
}
]
}Recommended log entry fields:
node_idnode_typestatusattemptsduration_msstarted_atfinished_atoutputerrorerror_code
The current app already stores node log entries on the run record, and output or error text is truncated for storage safety. The public API should still split those logs into a dedicated endpoint.
Execution Behavior
The current app already uses a real queued-run model:
- New runs start as
queued. - A worker or cron claim moves them to
running. - A lease timeout can recover stale runs as
failed. - Manual dispatch may attempt inline execution for faster feedback.
Public guidance should therefore be:
- Always assume the run may complete after the dispatch response returns.
- Poll
GET /v1/runs/{id}or subscribe to webhook events. - Do not assume immediate success even if a preview environment occasionally returns inline completion.
Retry and Dry Run Guidance
Retry should be modeled carefully:
- A retry should create a new run instead of overwriting a finished run.
- The new run may reference the same workflow and document, but it should have a different run id.
The current app also supports internal dry-run tooling such as node dry run and path dry run. Those are useful for the product UI and operator workflows, but they should remain internal until the public execution contract is stable.