> This page is for version v2026-02-09 (default).
> For other versions, use one of these documentation indexes:
> - v2026-02-09 (default): https://docs.extend.ai/2026-02-09/llms.txt
> - v2025-04-21: https://docs.extend.ai/2025-04-21/llms.txt
> - v2024-12-23: https://docs.extend.ai/2024-12-23/llms.txt

> ## Documentation Index
> Fetch the complete documentation index at: https://docs.extend.ai/llms.txt
> Use this file to discover all available pages before exploring further.
>
> ## API version
> The current API version is `2026-02-09`, served at the site root (no version prefix in URLs).
> If this page URL contains `/2025-04-21/` or `/2024-12-23/`, you are reading an older API version.
> Prefer the current docs at https://docs.extend.ai/llms.txt unless the user explicitly needs that older version.
> Do not treat older-version pages as the source of truth for new integrations.

# Workflow Runs Migration

> Migrate your /workflow_runs integration from 2025-04-21 to 2026-02-09

## 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

> **Note**
>
> 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

**`Before (2025-04-21)`**

```typescript title="Before (2025-04-21)"
const response = await client.workflowRun.create({
  workflowId: "workflow_abc123",
  files: [{ fileUrl: "https://example.com/invoice.pdf", fileName: "invoice.pdf" }],
  version: "3",
  metadata: { customerId: "cust_123" }
});
if (response.success) {
  const run = response.workflowRuns[0]; // Array of runs, one per file
  console.log(run.outputs); // ProcessorRun[]
}
```

**`After (2026-02-09)`**

```typescript title="After (2026-02-09)"
const run = await client.workflowRuns.create({
  workflow: { id: "workflow_abc123", version: "3" },
  file: { url: "https://example.com/invoice.pdf", name: "invoice.pdf" },
  metadata: { customerId: "cust_123" }
});
console.log(run.stepRuns); // Typed StepRun[] with all step types
```

#### Python

**`Before (2025-04-21)`**

```python title="Before (2025-04-21)"
response = client.workflow_run.create(
    workflow_id="workflow_abc123",
    files=[{"file_url": "https://example.com/invoice.pdf", "file_name": "invoice.pdf"}],
    version="3",
    metadata={"customerId": "cust_123"}
)
if response.success:
    run = response.workflow_runs[0]
    print(run.outputs)
```

**`After (2026-02-09)`**

```python title="After (2026-02-09)"
run = client.workflow_runs.create(
    workflow={"id": "workflow_abc123", "version": "3"},
    file={"url": "https://example.com/invoice.pdf", "name": "invoice.pdf"},
    metadata={"customerId": "cust_123"}
)
print(run.step_runs)
```

#### Java

**`After (2026-02-09)`**

```java title="After (2026-02-09)"
var run = client.workflowRuns().create(WorkflowRunsCreateRequest.builder()
    .workflow(WorkflowReference.builder().id("workflow_abc123").version("3").build())
    .file(WorkflowRunsCreateRequestFile.of(FileFromUrl.builder().url("https://example.com/invoice.pdf").name("invoice.pdf").build()))
    .metadata(Map.of("customerId", "cust_123"))
    .build());
System.out.println(run.getStepRuns());
```

### 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

```typescript
const result = await client.workflowRuns.createAndPoll({
  workflow: { id: "workflow_abc123" },
  file: { url: "https://example.com/invoice.pdf" }
});
console.log(result.status);
console.log(result.stepRuns);
```

#### Python

```python
result = client.workflow_runs.create_and_poll(
    workflow={"id": "workflow_abc123"},
    file={"url": "https://example.com/invoice.pdf"}
)
print(result.status)
print(result.step_runs)
```

#### Java

```java
var result = client.workflowRuns().createAndPoll(WorkflowRunsCreateRequest.builder()
    .workflow(WorkflowReference.builder().id("workflow_abc123").build())
    .file(WorkflowRunsCreateRequestFile.of(FileFromUrl.builder().url("https://example.com/invoice.pdf").build()))
    .build());
System.out.println(result.getStatus());
System.out.println(result.getStepRuns());
```

> **Warning**
>
> Workflow runs can take a long time. Complex workflows may run for hours. For long-running workflows, consider using [webhooks](/webhooks/configuration) 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

**`Before (2025-04-21) — multiple files in one request`**

```typescript title="Before (2025-04-21) — multiple files in one request"
const response = await client.workflowRun.create({
  workflowId: "workflow_abc123",
  files: [
    { fileUrl: "https://example.com/file1.pdf" },
    { fileUrl: "https://example.com/file2.pdf" },
    { fileUrl: "https://example.com/file3.pdf" }
  ]
});
const runs = response.workflowRuns; // 3 runs
```

**`After (2026-02-09) — one file per request`**

```typescript title="After (2026-02-09) — one file per request"
// Option 1: Separate requests
const run1 = await client.workflowRuns.create({
  workflow: { id: "workflow_abc123" },
  file: { url: "https://example.com/file1.pdf" }
});

// Option 2: Batch endpoint for bulk processing
const batch = await client.workflowRuns.createBatch({
  workflow: { id: "workflow_abc123" },
  inputs: [
    { file: { url: "https://example.com/file1.pdf" } },
    { file: { url: "https://example.com/file2.pdf" } },
    { file: { url: "https://example.com/file3.pdf" } }
  ]
});
console.log(batch.batchId); // Use to track via webhooks or list endpoint
```

#### Python

**`Before (2025-04-21) — multiple files in one request`**

```python title="Before (2025-04-21) — multiple files in one request"
response = client.workflow_run.create(
    workflow_id="workflow_abc123",
    files=[
        {"file_url": "https://example.com/file1.pdf"},
        {"file_url": "https://example.com/file2.pdf"},
        {"file_url": "https://example.com/file3.pdf"}
    ]
)
runs = response.workflow_runs  # 3 runs
```

**`After (2026-02-09) — one file per request`**

```python title="After (2026-02-09) — one file per request"
# Option 1: Separate requests
run1 = client.workflow_runs.create(
    workflow={"id": "workflow_abc123"},
    file={"url": "https://example.com/file1.pdf"}
)

# Option 2: Batch endpoint for bulk processing
batch = client.workflow_runs.create_batch(
    workflow={"id": "workflow_abc123"},
    inputs=[
        {"file": {"url": "https://example.com/file1.pdf"}},
        {"file": {"url": "https://example.com/file2.pdf"}},
        {"file": {"url": "https://example.com/file3.pdf"}}
    ]
)
print(batch.batch_id)
```

### Listing Workflow Runs

#### TypeScript

**`Before`**

```typescript title="Before"
const response = await client.workflowRun.list({
  workflowId: "workflow_abc123",
  status: "PROCESSED"
});
const runs = response.workflowRuns;
```

**`After`**

```typescript title="After"
const response = await client.workflowRuns.list({
  workflowId: "workflow_abc123",
  status: "PROCESSED"
});
const runs = response.data;
```

#### Python

**`Before`**

```python title="Before"
response = client.workflow_run.list(
    workflow_id="workflow_abc123",
    status="PROCESSED"
)
runs = response.workflow_runs
```

**`After`**

```python title="After"
response = client.workflow_runs.list(
    workflow_id="workflow_abc123",
    status="PROCESSED"
)
runs = response.data
```

### Getting a Workflow Run

#### TypeScript

**`Before`**

```typescript title="Before"
const response = await client.workflowRun.get("workflow_run_abc123");
const run = response.workflowRun;
console.log(run.outputs);
```

**`After`**

```typescript title="After"
const run = await client.workflowRuns.retrieve("workflow_run_abc123");
console.log(run.stepRuns);
```

#### Python

**`Before`**

```python title="Before"
response = client.workflow_run.get("workflow_run_abc123")
run = response.workflow_run
print(run.outputs)
```

**`After`**

```python title="After"
run = client.workflow_runs.retrieve("workflow_run_abc123")
print(run.step_runs)
```

### Using Raw Text Instead of Files

#### TypeScript

**`Before (2025-04-21)`**

```typescript title="Before (2025-04-21)"
const response = await client.workflowRun.create({
  workflowId: "workflow_abc123",
  rawTexts: ["Invoice #123\nVendor: Acme Corp\nTotal: $500"]
});
```

**`After (2026-02-09)`**

```typescript title="After (2026-02-09)"
const run = await client.workflowRuns.create({
  workflow: { id: "workflow_abc123" },
  file: { text: "Invoice #123\nVendor: Acme Corp\nTotal: $500" }
});
```

#### Python

**`Before (2025-04-21)`**

```python title="Before (2025-04-21)"
response = client.workflow_run.create(
    workflow_id="workflow_abc123",
    raw_texts=["Invoice #123\nVendor: Acme Corp\nTotal: $500"]
)
```

**`After (2026-02-09)`**

```python title="After (2026-02-09)"
run = client.workflow_runs.create(
    workflow={"id": "workflow_abc123"},
    file={"text": "Invoice #123\nVendor: Acme Corp\nTotal: $500"}
)
```

---

## Endpoint Changes Summary

| Old Endpoint                                             | New Endpoint                      | Notes                                        |
| -------------------------------------------------------- | --------------------------------- | -------------------------------------------- |
| `POST /workflow_runs`                                    | `POST /workflow_runs`             | Request/response shape changed significantly |
| `GET /workflow_runs`                                     | `GET /workflow_runs`              | Response 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}/cancel`             | `POST /workflow_runs/{id}/cancel` | Path param renamed                           |
| `POST /workflow_runs/{workflowRunId}/outputs/{outputId}` | *(removed)*                       | Correct Outputs endpoint removed             |
| `POST /workflow_runs/batch`                              | `POST /workflow_runs/batch`       | Request shape changed                        |

---

## Request Changes

### File Properties (All Endpoints)

| Old                | New                                            |
| ------------------ | ---------------------------------------------- |
| `fileUrl`          | `url`                                          |
| `fileId`           | `id`                                           |
| `fileName`         | `name`                                         |
| `rawTexts` (array) | `file.text` (single string via `FileFromText`) |

### Creating a Workflow Run

| Old                             | New                     | Notes                                                                                 |
| ------------------------------- | ----------------------- | ------------------------------------------------------------------------------------- |
| `workflowId`                    | `workflow.id`           | Nested in `workflow` object                                                           |
| `version`                       | `workflow.version`      | Nested in `workflow` object                                                           |
| `files` (array)                 | `file` (single object)  | **One file per request.** Use batch endpoint for multiple files                       |
| `files[].fileUrl`               | `file.url`              | Renamed                                                                               |
| `files[].fileId`                | `file.id`               | Renamed                                                                               |
| `files[].fileName`              | `file.name`             | Renamed                                                                               |
| `rawTexts`                      | `file.text`             | Use `FileFromText` input                                                              |
| `files[].outputs`               | `outputs`               | Moved to top-level                                                                    |
| `files[].outputs[].processorId` | `outputs[].processorId` | Now references extractor/classifier/splitter IDs (e.g., `ex_`, `cl_`, `sp_` prefixed) |
| —                               | `secrets`               | **New.** Pass secrets to processors in the workflow                                   |

> **Warning**
>
> **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](/api-reference/endpoints/workflow/batch-create-workflow-runs) endpoint.

### Example: Create Request

**`Before (2025-04-21)`**

```json title="Before (2025-04-21)"
{
  "workflowId": "workflow_abc123",
  "version": "3",
  "files": [
    {
      "fileUrl": "https://example.com/invoice.pdf",
      "fileName": "invoice.pdf"
    }
  ],
  "metadata": { "customerId": "cust_123" }
}
```

**`After (2026-02-09)`**

```json title="After (2026-02-09)"
{
  "workflow": {
    "id": "workflow_abc123",
    "version": "3"
  },
  "file": {
    "url": "https://example.com/invoice.pdf",
    "name": "invoice.pdf"
  },
  "metadata": { "customerId": "cust_123" }
}
```

### Batch Run Request

**`Before (2025-04-21)`**

```json title="Before (2025-04-21)"
{
  "workflowId": "workflow_abc123",
  "version": "2",
  "inputs": [
    {
      "file": { "fileUrl": "https://example.com/file1.pdf", "fileName": "file1.pdf" },
      "metadata": { "source": "upload" }
    },
    {
      "rawText": "Raw invoice data here...",
      "metadata": { "source": "email" }
    }
  ]
}
```

**`After (2026-02-09)`**

```json title="After (2026-02-09)"
{
  "workflow": {
    "id": "workflow_abc123",
    "version": "2"
  },
  "inputs": [
    {
      "file": { "url": "https://example.com/file1.pdf", "name": "file1.pdf" },
      "metadata": { "source": "upload" }
    },
    {
      "file": { "text": "Raw invoice data here..." },
      "metadata": { "source": "email" }
    }
  ]
}
```

---

## Response Changes

> **Note**
>
> **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](/api-reference/migrations/2026-02-09/overview#simplified-response-shapes) for details.

### Key Differences

| Old                                   | New                                    | Notes                                                    |
| ------------------------------------- | -------------------------------------- | -------------------------------------------------------- |
| `success: true`                       | *(removed)*                            | Use HTTP status codes                                    |
| `{ workflowRuns: [...] }` (create)    | Direct `WorkflowRun` object            | Single file = single response                            |
| `{ workflowRun: {...} }` (get/update) | Direct `WorkflowRun` object            | Unwrapped                                                |
| `{ workflowRuns: [...] }` (list)      | `{ object: "list", data: [...] }`      | Standardized list format                                 |
| `run.url`                             | `run.dashboardUrl`                     | Renamed                                                  |
| `run.name`                            | *(removed)*                            | No longer on the run object                              |
| `run.workflow` (flat object)          | `run.workflow` + `run.workflowVersion` | Split into two objects                                   |
| `run.workflow.version`                | `run.workflowVersion.version`          | Moved 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.reviewedBy`                      | `run.reviewedByUser`                   | Renamed                                                  |
| Optional fields (may be absent)       | Required but nullable (always present) | Predictable response shape                               |

### Example: Create Response

**`Before (2025-04-21)`**

```json title="Before (2025-04-21)"
{
  "success": true,
  "workflowRuns": [
    {
      "object": "workflow_run",
      "id": "workflow_run_abc123",
      "name": "invoice.pdf",
      "url": "https://dashboard.extend.ai/workflows/workflow_abc?workflowRunId=workflow_run_abc123",
      "status": "PENDING",
      "metadata": {},
      "batchId": "batch_xyz",
      "files": [{ "id": "file_123", "name": "invoice.pdf", "type": "PDF" }],
      "outputs": [],
      "stepRuns": [],
      "workflow": {
        "object": "workflow",
        "id": "workflow_abc",
        "version": "3",
        "name": "Invoice Processing"
      }
    }
  ]
}
```

**`After (2026-02-09)`**

```json title="After (2026-02-09)"
{
  "object": "workflow_run",
  "id": "workflow_run_abc123",
  "dashboardUrl": "https://dashboard.extend.ai/workflows/workflow_run_abc123",
  "status": "PENDING",
  "metadata": {},
  "batchId": "batch_xyz",
  "files": [{ "id": "file_123", "name": "invoice.pdf" }],
  "stepRuns": [],
  "workflow": {
    "object": "workflow",
    "id": "workflow_abc",
    "name": "Invoice Processing"
  },
  "workflowVersion": {
    "object": "workflow_version",
    "id": "workflow_version_xyz",
    "version": "3",
    "name": "Invoice Processing"
  },
  "reviewed": false,
  "failureReason": null,
  "failureMessage": null,
  "reviewedByUser": null,
  "rejectionNote": null,
  "reviewedAt": null,
  "initialRunAt": "2025-05-12T21:34:54.477000+00:00",
  "startTime": null,
  "endTime": null,
  "usage": null
}
```

### 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:

**`Before (2025-04-21) — outputs array`**

```json title="Before (2025-04-21) — outputs array"
{
  "success": true,
  "workflowRun": {
    "id": "workflow_run_abc123",
    "status": "PROCESSED",
    "outputs": [
      {
        "object": "document_processor_run",
        "id": "dpr_extract1",
        "type": "EXTRACT",
        "status": "PROCESSED",
        "output": {
          "value": { "vendorName": "Acme Corp", "total": 500.00 }
        }
      },
      {
        "object": "document_processor_run",
        "id": "dpr_classify1",
        "type": "CLASSIFY",
        "status": "PROCESSED",
        "output": {
          "type": "INVOICE",
          "confidence": 0.98
        }
      }
    ],
    "stepRuns": []
  }
}
```

**`After (2026-02-09) — stepRuns with typed results`**

```json title="After (2026-02-09) — stepRuns with typed results"
{
  "id": "workflow_run_abc123",
  "status": "PROCESSED",
  "stepRuns": [
    {
      "object": "workflow_step_run",
      "id": "workflow_step_run_abc",
      "workflowRunId": "workflow_run_abc123",
      "stepType": "PARSE",
      "status": "PROCESSED",
      "step": {
        "object": "workflow_step",
        "id": "step_parse1",
        "name": "Parse Document",
        "type": "PARSE"
      },
      "result": { "...": "ParseResult" },
      "files": [{ "id": "file_123", "name": "invoice.pdf" }]
    },
    {
      "object": "workflow_step_run",
      "id": "workflow_step_run_def",
      "workflowRunId": "workflow_run_abc123",
      "stepType": "EXTRACT",
      "status": "PROCESSED",
      "step": {
        "object": "workflow_step",
        "id": "step_extract1",
        "name": "Extract Invoice Data",
        "type": "EXTRACT"
      },
      "result": {
        "output": {
          "value": { "vendorName": "Acme Corp", "total": 500.00 }
        }
      },
      "files": [{ "id": "file_123", "name": "invoice.pdf" }]
    },
    {
      "object": "workflow_step_run",
      "id": "workflow_step_run_ghi",
      "workflowRunId": "workflow_run_abc123",
      "stepType": "CLASSIFY",
      "status": "PROCESSED",
      "step": {
        "object": "workflow_step",
        "id": "step_classify1",
        "name": "Classify Document",
        "type": "CLASSIFY"
      },
      "result": {
        "output": {
          "type": "INVOICE",
          "confidence": 0.98
        }
      },
      "files": [{ "id": "file_123", "name": "invoice.pdf" }]
    }
  ]
}
```

### Example: List Response

**`Before (2025-04-21)`**

```json title="Before (2025-04-21)"
{
  "success": true,
  "workflowRuns": [
    {
      "id": "workflow_run_abc123",
      "status": "PROCESSED",
      "workflowId": "workflow_abc",
      "workflowName": "Invoice Processing",
      "workflowVersionId": "workflow_version_xyz",
      "createdAt": "2024-03-21T15:29:55Z",
      "updatedAt": "2024-03-21T16:45:00Z"
    }
  ],
  "nextPageToken": "..."
}
```

**`After (2026-02-09)`**

```json title="After (2026-02-09)"
{
  "object": "list",
  "data": [
    {
      "object": "workflow_run",
      "id": "workflow_run_abc123",
      "status": "PROCESSED",
      "workflow": {
        "object": "workflow",
        "id": "workflow_abc",
        "name": "Invoice Processing"
      },
      "workflowVersion": {
        "object": "workflow_version",
        "id": "workflow_version_xyz",
        "version": "3",
        "name": "Invoice Processing"
      },
      "dashboardUrl": "https://dashboard.extend.ai/workflows/workflow_run_abc123",
      "createdAt": "2024-03-21T15:29:55Z",
      "updatedAt": "2024-03-21T16:45:00Z",
      "reviewedByUser": null,
      "reviewedAt": null,
      "initialRunAt": "2024-03-21T15:30:00Z",
      "startTime": "2024-03-21T15:30:05Z",
      "endTime": "2024-03-21T15:35:00Z",
      "batchId": null,
      "rejectionNote": null,
      "usage": null
    }
  ],
  "nextPageToken": "..."
}
```

### Example: Delete Response

**`Before (2025-04-21)`**

```json title="Before (2025-04-21)"
{
  "success": true,
  "workflowRunId": "workflow_run_abc123",
  "message": "Workflow run data has been successfully deleted."
}
```

**`After (2026-02-09)`**

```json title="After (2026-02-09)"
{
  "id": "workflow_run_abc123"
}
```

---

## 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 Method                          | New 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

| Property          | Old (2025-04-21)                 | New (2026-02-09)                  | Change                                                                                                                                        |
| ----------------- | -------------------------------- | --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `object`          | `"workflow_run"`                 | `"workflow_run"`                  | No change                                                                                                                                     |
| `id`              | Required `string`                | Required `string`                 | No change                                                                                                                                     |
| `name`            | Required `string`                | —                                 | Removed                                                                                                                                       |
| `url`             | Required `string`                | —                                 | Renamed to `dashboardUrl`                                                                                                                     |
| `dashboardUrl`    | —                                | Required `string`                 | New (replaces `url`)                                                                                                                          |
| `status`          | Required                         | Required                          | No change                                                                                                                                     |
| `metadata`        | Optional `JsonObject`            | Required `RunMetadata`            | Now required                                                                                                                                  |
| `batchId`         | Optional `string`                | Required but nullable `string`    | Now required                                                                                                                                  |
| `files`           | Required `File[]`                | Required `FileSummary[]`          | Simplified file objects                                                                                                                       |
| `workflow`        | `Workflow` (with `version`)      | `WorkflowSummary` (no `version`)  | Split into two fields                                                                                                                         |
| `workflowVersion` | —                                | Required `WorkflowVersionSummary` | New (version info moved here)                                                                                                                 |
| `outputs`         | Required `ProcessorRun[]`        | —                                 | **Removed.** Use `stepRuns`                                                                                                                   |
| `stepRuns`        | Required (validation types only) | Required (all step types)         | **Expanded.** Now includes PARSE, EXTRACT, CLASSIFY, SPLIT, MERGE_EXTRACT, CONDITIONAL_EXTRACT, RULE_VALIDATION, and EXTERNAL_DATA_VALIDATION |
| `failureReason`   | Optional `string`                | Required but nullable `string`    | Now required                                                                                                                                  |
| `failureMessage`  | Optional `string`                | Required but nullable `string`    | Now required                                                                                                                                  |
| `initialRunAt`    | Required `date-time`             | Required but nullable `date-time` | Now nullable                                                                                                                                  |
| `reviewedBy`      | Optional `string`                | —                                 | Renamed to `reviewedByUser`                                                                                                                   |
| `reviewedByUser`  | —                                | Required but nullable `string`    | New (replaces `reviewedBy`)                                                                                                                   |
| `reviewed`        | Required `boolean`               | Required `boolean`                | No change                                                                                                                                     |
| `rejectionNote`   | Optional `string`                | Required but nullable `string`    | Now required                                                                                                                                  |
| `reviewedAt`      | Optional `date-time`             | Required but nullable `date-time` | Now required                                                                                                                                  |
| `startTime`       | Optional `date-time`             | Required but nullable `date-time` | Now required                                                                                                                                  |
| `endTime`         | Optional `date-time`             | Required but nullable `date-time` | Now required                                                                                                                                  |
| `usage`           | Optional `WorkflowRunCredits`    | Required but nullable `RunUsage`  | Now required, type changed                                                                                                                    |

### WorkflowRunSummary Schema (List Response)

| Property            | Old (2025-04-21)     | New (2026-02-09)                        | Change                            |
| ------------------- | -------------------- | --------------------------------------- | --------------------------------- |
| `object`            | —                    | `"workflow_run"`                        | New                               |
| `id`                | Required `string`    | Required `string`                       | No change                         |
| `status`            | Required             | Required                                | No change                         |
| `workflowId`        | Required `string`    | —                                       | Removed, see `workflow.id`        |
| `workflowName`      | Required `string`    | —                                       | Removed, see `workflow.name`      |
| `workflowVersionId` | Required `string`    | —                                       | Removed, see `workflowVersion.id` |
| `workflow`          | —                    | Required `WorkflowSummary`              | New                               |
| `workflowVersion`   | —                    | Required `WorkflowVersionSummary`       | New                               |
| `dashboardUrl`      | —                    | Required `string`                       | New                               |
| `createdAt`         | Required `date-time` | Required `date-time`                    | No change                         |
| `updatedAt`         | Required `date-time` | Required `date-time`                    | No change                         |
| `reviewedByUser`    | Optional `string`    | Required but nullable `string`          | Now required                      |
| `reviewedAt`        | Optional `date-time` | Required but nullable `date-time`       | Now required                      |
| `initialRunAt`      | Optional `date-time` | Required `date-time`                    | Now required                      |
| `startTime`         | Optional `date-time` | Required `date-time`                    | Now required                      |
| `endTime`           | Optional `date-time` | Required `date-time`                    | Now required                      |
| `batchId`           | —                    | Required but nullable `string`          | New                               |
| `rejectionNote`     | —                    | Required but nullable `string`          | New                               |
| `usage`             | —                    | Required but nullable `RunUsageSummary` | New                               |

### StepRun Schema

| Old (2025-04-21)                                                    | New (2026-02-09)                                                                                                                            |
| ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| Simple object type                                                  | Discriminated union (`oneOf`)                                                                                                               |
| `step.type`: `EXTERNAL_DATA_VALIDATION`, `RULE_VALIDATION` only     | `step.type`: `PARSE`, `EXTRACT`, `CLASSIFY`, `SPLIT`, `MERGE_EXTRACT`, `CONDITIONAL_EXTRACT`, `RULE_VALIDATION`, `EXTERNAL_DATA_VALIDATION` |
| `output` field                                                      | `result` field (typed per step type)                                                                                                        |
| No `workflowRunId`                                                  | `workflowRunId` included                                                                                                                    |
| No `files`                                                          | `files` array included                                                                                                                      |
| Status: `PENDING`, `PROCESSING`, `PROCESSED`, `FAILED`, `CANCELLED` | Status: adds `WAITING`                                                                                                                      |

---

## Need Help?

If you encounter any issues while migrating, please contact our support team at [support@extend.app](mailto:support@extend.app).

---

## Migration Guides

| Guide                            | Migrating From           | Migrating To                            |
| -------------------------------- | ------------------------ | --------------------------------------- |
| [Overview](./overview)           | —                        | What's new and how to upgrade           |
| [Extract Runs](./extract)        | `/processor_runs`        | `/extract_runs` + `/extract`            |
| [Classify Runs](./classify)      | `/processor_runs`        | `/classify_runs` + `/classify`          |
| [Split Runs](./split)            | `/processor_runs`        | `/split_runs` + `/split`                |
| [Parse Runs](./parse)            | `/parse`, `/parse/async` | `/parse_runs` + `/parse`                |
| [Edit Runs](./edit)              | `/edit`, `/edit/async`   | `/edit_runs` + `/edit`                  |
| [Extractors](./extractors)       | `/processors`            | `/extractors`                           |
| [Classifiers](./classifiers)     | `/processors`            | `/classifiers`                          |
| [Splitters](./splitters)         | `/processors`            | `/splitters`                            |
| [Files](./files)                 | `/files`                 | `/files` (breaking changes)             |
| [Evaluation Sets](./evaluation)  | evaluation endpoints     | Updated evaluation endpoints            |
| [Workflow Runs](./workflow-runs) | `/workflow_runs`         | `/workflow_runs` (breaking changes)     |
| [Webhooks](./webhooks)           | `processor_run.*` events | `extract_run.*`, `classify_run.*`, etc. |