For AI agents: a documentation index is available at the root level at /llms.txt and /llms-full.txt. Append /llms.txt to any URL for a page-level index, or .md for the markdown version of any page.
GuidesAPI ReferenceChangelogModel Versioning
GuidesAPI ReferenceChangelogModel Versioning
    • Getting Started
    • Authentication
    • API Versioning
    • SDKs
    • Deployments
    • Error Codes
    • Async Processing
  • Endpoints
  • Webhook Events
  • Migration Guides
      • Workflow Runs
LogoLogo
On this page
  • What You Get
  • Quick Start: Common Patterns
  • Running a Workflow
  • Using Polling Helpers
  • Processing Multiple Files
  • Listing Workflow Runs
  • Getting a Workflow Run
  • Using Raw Text Instead of Files
  • Endpoint Changes Summary
  • Request Changes
  • File Properties (All Endpoints)
  • Creating a Workflow Run
  • Example: Create Request
  • Batch Run Request
  • Response Changes
  • Key Differences
  • Example: Create Response
  • Example: Completed Response with Step Runs
  • Example: List Response
  • Example: Delete Response
  • Removed Endpoint: Correct Workflow Run Outputs
  • SDK Method Reference
  • WorkflowRun Schema
  • WorkflowRunSummary Schema (List Response)
  • StepRun Schema
  • Need Help?
  • Migration Guides
Migration Guides2026-02-09

Workflow Runs Migration

Was this page helpful?
Previous

Changelog

Next
Built with

What You Get

  • Single-file runs — Each request processes one file, giving you a single WorkflowRun back instead of an array
  • Typed step runs — stepRuns now includes all step types (extraction, classification, splitting, etc.) with typed results, replacing the old outputs array
  • Cleaner request/response format — Simpler property names, unwrapped responses, predictable nullable fields
  • Polling helpers — createAndPoll / create_and_poll handles polling with exponential backoff

The old /workflow_runs request and response shapes from 2025-04-21 are not carried forward—you’ll need to update your integration to use the new format.


Quick Start: Common Patterns

Running a Workflow

TypeScript
Python
Java
Before (2025-04-21)
1const response = await client.workflowRun.create({
2 workflowId: "workflow_abc123",
3 files: [{ fileUrl: "https://example.com/invoice.pdf", fileName: "invoice.pdf" }],
4 version: "3",
5 metadata: { customerId: "cust_123" }
6});
7if (response.success) {
8 const run = response.workflowRuns[0]; // Array of runs, one per file
9 console.log(run.outputs); // ProcessorRun[]
10}
After (2026-02-09)
1const run = await client.workflowRuns.create({
2 workflow: { id: "workflow_abc123", version: "3" },
3 file: { url: "https://example.com/invoice.pdf", name: "invoice.pdf" },
4 metadata: { customerId: "cust_123" }
5});
6console.log(run.stepRuns); // Typed StepRun[] with all step types

Using Polling Helpers

The SDK provides createAndPoll / create_and_poll methods that handle polling automatically, returning when the run reaches a terminal state (PROCESSED, FAILED, CANCELLED, NEEDS_REVIEW, or REJECTED):

TypeScript
Python
Java
1const result = await client.workflowRuns.createAndPoll({
2 workflow: { id: "workflow_abc123" },
3 file: { url: "https://example.com/invoice.pdf" }
4});
5console.log(result.status);
6console.log(result.stepRuns);
Workflow runs can take a long time. Complex workflows may run for hours. For long-running workflows, consider using webhooks instead of polling.

Processing Multiple Files

The old API accepted an array of files in a single request. The new API processes one file at a time. To process multiple files, make separate requests or use the batch endpoint:

TypeScript
Python
Before (2025-04-21) — multiple files in one request
1const response = await client.workflowRun.create({
2 workflowId: "workflow_abc123",
3 files: [
4 { fileUrl: "https://example.com/file1.pdf" },
5 { fileUrl: "https://example.com/file2.pdf" },
6 { fileUrl: "https://example.com/file3.pdf" }
7 ]
8});
9const runs = response.workflowRuns; // 3 runs
After (2026-02-09) — one file per request
1// Option 1: Separate requests
2const run1 = await client.workflowRuns.create({
3 workflow: { id: "workflow_abc123" },
4 file: { url: "https://example.com/file1.pdf" }
5});
6
7// Option 2: Batch endpoint for bulk processing
8const batch = await client.workflowRuns.createBatch({
9 workflow: { id: "workflow_abc123" },
10 inputs: [
11 { file: { url: "https://example.com/file1.pdf" } },
12 { file: { url: "https://example.com/file2.pdf" } },
13 { file: { url: "https://example.com/file3.pdf" } }
14 ]
15});
16console.log(batch.batchId); // Use to track via webhooks or list endpoint

Listing Workflow Runs

TypeScript
Python
Before
1const response = await client.workflowRun.list({
2 workflowId: "workflow_abc123",
3 status: "PROCESSED"
4});
5const runs = response.workflowRuns;
After
1const response = await client.workflowRuns.list({
2 workflowId: "workflow_abc123",
3 status: "PROCESSED"
4});
5const runs = response.data;

Getting a Workflow Run

TypeScript
Python
Before
1const response = await client.workflowRun.get("workflow_run_abc123");
2const run = response.workflowRun;
3console.log(run.outputs);
After
1const run = await client.workflowRuns.retrieve("workflow_run_abc123");
2console.log(run.stepRuns);

Using Raw Text Instead of Files

TypeScript
Python
Before (2025-04-21)
1const response = await client.workflowRun.create({
2 workflowId: "workflow_abc123",
3 rawTexts: ["Invoice #123\nVendor: Acme Corp\nTotal: $500"]
4});
After (2026-02-09)
1const run = await client.workflowRuns.create({
2 workflow: { id: "workflow_abc123" },
3 file: { text: "Invoice #123\nVendor: Acme Corp\nTotal: $500" }
4});

Endpoint Changes Summary

Old EndpointNew EndpointNotes
POST /workflow_runsPOST /workflow_runsRequest/response shape changed significantly
GET /workflow_runsGET /workflow_runsResponse shape changed
GET /workflow_runs/{workflowRunId}GET /workflow_runs/{id}Path param renamed
POST /workflow_runs/{workflowRunId}POST /workflow_runs/{id}Path param renamed
DELETE /workflow_runs/{workflowRunId}DELETE /workflow_runs/{id}Path param renamed, response simplified
POST /workflow_runs/{workflowRunId}/cancelPOST /workflow_runs/{id}/cancelPath param renamed
POST /workflow_runs/{workflowRunId}/outputs/{outputId}(removed)Correct Outputs endpoint removed
POST /workflow_runs/batchPOST /workflow_runs/batchRequest shape changed

Request Changes

File Properties (All Endpoints)

OldNew
fileUrlurl
fileIdid
fileNamename
rawTexts (array)file.text (single string via FileFromText)

Creating a Workflow Run

OldNewNotes
workflowIdworkflow.idNested in workflow object
versionworkflow.versionNested in workflow object
files (array)file (single object)One file per request. Use batch endpoint for multiple files
files[].fileUrlfile.urlRenamed
files[].fileIdfile.idRenamed
files[].fileNamefile.nameRenamed
rawTextsfile.textUse FileFromText input
files[].outputsoutputsMoved to top-level
files[].outputs[].processorIdoutputs[].processorIdNow references extractor/classifier/splitter IDs (e.g., ex_, cl_, sp_ prefixed)
—secretsNew. Pass secrets to processors in the workflow

Breaking change: The files array has been replaced with a single file object. If you previously processed multiple files in one request, you’ll need to either make separate requests or use the Batch Run Workflow endpoint.

Example: Create Request

1{
2 "workflowId": "workflow_abc123",
3 "version": "3",
4 "files": [
5 {
6 "fileUrl": "https://example.com/invoice.pdf",
7 "fileName": "invoice.pdf"
8 }
9 ],
10 "metadata": { "customerId": "cust_123" }
11}

Batch Run Request

1{
2 "workflowId": "workflow_abc123",
3 "version": "2",
4 "inputs": [
5 {
6 "file": { "fileUrl": "https://example.com/file1.pdf", "fileName": "file1.pdf" },
7 "metadata": { "source": "upload" }
8 },
9 {
10 "rawText": "Raw invoice data here...",
11 "metadata": { "source": "email" }
12 }
13 ]
14}

Response Changes

Response shape changes: Single object responses are now returned directly (no wrapper key), and list responses use { "object": "list", "data": [...] } format. See Simplified Response Shapes for details.

Key Differences

OldNewNotes
success: true(removed)Use HTTP status codes
{ workflowRuns: [...] } (create)Direct WorkflowRun objectSingle file = single response
{ workflowRun: {...} } (get/update)Direct WorkflowRun objectUnwrapped
{ workflowRuns: [...] } (list){ object: "list", data: [...] }Standardized list format
run.urlrun.dashboardUrlRenamed
run.name(removed)No longer on the run object
run.workflow (flat object)run.workflow + run.workflowVersionSplit into two objects
run.workflow.versionrun.workflowVersion.versionMoved to separate object
run.outputs (ProcessorRun[])(removed)Replaced by stepRuns
run.stepRuns (validation only)run.stepRuns (all step types)Now includes extraction, classification, splitting, etc.
run.reviewedByrun.reviewedByUserRenamed
Optional fields (may be absent)Required but nullable (always present)Predictable response shape

Example: Create Response

1{
2 "success": true,
3 "workflowRuns": [
4 {
5 "object": "workflow_run",
6 "id": "workflow_run_abc123",
7 "name": "invoice.pdf",
8 "url": "https://dashboard.extend.ai/workflows/workflow_abc?workflowRunId=workflow_run_abc123",
9 "status": "PENDING",
10 "metadata": {},
11 "batchId": "batch_xyz",
12 "files": [{ "id": "file_123", "name": "invoice.pdf", "type": "PDF" }],
13 "outputs": [],
14 "stepRuns": [],
15 "workflow": {
16 "object": "workflow",
17 "id": "workflow_abc",
18 "version": "3",
19 "name": "Invoice Processing"
20 }
21 }
22 ]
23}

Example: Completed Response with Step Runs

The biggest change is how processor results are returned. Previously, results lived in the outputs array as ProcessorRun objects. Now, results are in stepRuns as typed StepRun objects:

1{
2 "success": true,
3 "workflowRun": {
4 "id": "workflow_run_abc123",
5 "status": "PROCESSED",
6 "outputs": [
7 {
8 "object": "document_processor_run",
9 "id": "dpr_extract1",
10 "type": "EXTRACT",
11 "status": "PROCESSED",
12 "output": {
13 "value": { "vendorName": "Acme Corp", "total": 500.00 }
14 }
15 },
16 {
17 "object": "document_processor_run",
18 "id": "dpr_classify1",
19 "type": "CLASSIFY",
20 "status": "PROCESSED",
21 "output": {
22 "type": "INVOICE",
23 "confidence": 0.98
24 }
25 }
26 ],
27 "stepRuns": []
28 }
29}

Example: List Response

1{
2 "success": true,
3 "workflowRuns": [
4 {
5 "id": "workflow_run_abc123",
6 "status": "PROCESSED",
7 "workflowId": "workflow_abc",
8 "workflowName": "Invoice Processing",
9 "workflowVersionId": "workflow_version_xyz",
10 "createdAt": "2024-03-21T15:29:55Z",
11 "updatedAt": "2024-03-21T16:45:00Z"
12 }
13 ],
14 "nextPageToken": "..."
15}

Example: Delete Response

1{
2 "success": true,
3 "workflowRunId": "workflow_run_abc123",
4 "message": "Workflow run data has been successfully deleted."
5}

Removed Endpoint: Correct Workflow Run Outputs

The POST /workflow_runs/{workflowRunId}/outputs/{outputId} endpoint for submitting corrected outputs has been removed. This was deprecated in the 2025-04-21 API.


SDK Method Reference

Old MethodNew Method
client.workflowRun.create()client.workflowRuns.create()
client.workflowRun.get()client.workflowRuns.retrieve()
client.workflowRun.list()client.workflowRuns.list()
client.workflowRun.update()client.workflowRuns.update()
client.workflowRun.delete()client.workflowRuns.delete()
client.workflowRun.cancel()client.workflowRuns.cancel()
client.batchWorkflowRun.create()client.workflowRuns.createBatch()
client.workflowRunOutput.update()(removed)
—client.workflowRuns.createAndPoll() (new)

Detailed Schema Changes

WorkflowRun Schema

PropertyOld (2025-04-21)New (2026-02-09)Change
object"workflow_run""workflow_run"No change
idRequired stringRequired stringNo change
nameRequired string—Removed
urlRequired string—Renamed to dashboardUrl
dashboardUrl—Required stringNew (replaces url)
statusRequiredRequiredNo change
metadataOptional JsonObjectRequired RunMetadataNow required
batchIdOptional stringRequired but nullable stringNow required
filesRequired File[]Required FileSummary[]Simplified file objects
workflowWorkflow (with version)WorkflowSummary (no version)Split into two fields
workflowVersion—Required WorkflowVersionSummaryNew (version info moved here)
outputsRequired ProcessorRun[]—Removed. Use stepRuns
stepRunsRequired (validation types only)Required (all step types)Expanded. Now includes PARSE, EXTRACT, CLASSIFY, SPLIT, MERGE_EXTRACT, CONDITIONAL_EXTRACT, RULE_VALIDATION, and EXTERNAL_DATA_VALIDATION
failureReasonOptional stringRequired but nullable stringNow required
failureMessageOptional stringRequired but nullable stringNow required
initialRunAtRequired date-timeRequired but nullable date-timeNow nullable
reviewedByOptional string—Renamed to reviewedByUser
reviewedByUser—Required but nullable stringNew (replaces reviewedBy)
reviewedRequired booleanRequired booleanNo change
rejectionNoteOptional stringRequired but nullable stringNow required
reviewedAtOptional date-timeRequired but nullable date-timeNow required
startTimeOptional date-timeRequired but nullable date-timeNow required
endTimeOptional date-timeRequired but nullable date-timeNow required
usageOptional WorkflowRunCreditsRequired but nullable RunUsageNow required, type changed

WorkflowRunSummary Schema (List Response)

PropertyOld (2025-04-21)New (2026-02-09)Change
object—"workflow_run"New
idRequired stringRequired stringNo change
statusRequiredRequiredNo change
workflowIdRequired string—Removed, see workflow.id
workflowNameRequired string—Removed, see workflow.name
workflowVersionIdRequired string—Removed, see workflowVersion.id
workflow—Required WorkflowSummaryNew
workflowVersion—Required WorkflowVersionSummaryNew
dashboardUrl—Required stringNew
createdAtRequired date-timeRequired date-timeNo change
updatedAtRequired date-timeRequired date-timeNo change
reviewedByUserOptional stringRequired but nullable stringNow required
reviewedAtOptional date-timeRequired but nullable date-timeNow required
initialRunAtOptional date-timeRequired date-timeNow required
startTimeOptional date-timeRequired date-timeNow required
endTimeOptional date-timeRequired date-timeNow required
batchId—Required but nullable stringNew
rejectionNote—Required but nullable stringNew
usage—Required but nullable RunUsageSummaryNew

StepRun Schema

Old (2025-04-21)New (2026-02-09)
Simple object typeDiscriminated union (oneOf)
step.type: EXTERNAL_DATA_VALIDATION, RULE_VALIDATION onlystep.type: PARSE, EXTRACT, CLASSIFY, SPLIT, MERGE_EXTRACT, CONDITIONAL_EXTRACT, RULE_VALIDATION, EXTERNAL_DATA_VALIDATION
output fieldresult field (typed per step type)
No workflowRunIdworkflowRunId included
No filesfiles array included
Status: PENDING, PROCESSING, PROCESSED, FAILED, CANCELLEDStatus: adds WAITING

Need Help?

If you encounter any issues while migrating, please contact our support team at support@extend.app.


Migration Guides

GuideMigrating FromMigrating To
Overview—What’s new and how to upgrade
Extract Runs/processor_runs/extract_runs + /extract
Classify Runs/processor_runs/classify_runs + /classify
Split Runs/processor_runs/split_runs + /split
Parse Runs/parse, /parse/async/parse_runs + /parse
Edit Runs/edit, /edit/async/edit_runs + /edit
Extractors/processors/extractors
Classifiers/processors/classifiers
Splitters/processors/splitters
Files/files/files (breaking changes)
Evaluation Setsevaluation endpointsUpdated evaluation endpoints
Workflow Runs/workflow_runs/workflow_runs (breaking changes)
Webhooksprocessor_run.* eventsextract_run.*, classify_run.*, etc.