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

# Parse Runs Migration

> Migrate from /parse to /parse_runs

## What You Get

* **Single production endpoint** — Use `/parse_runs` (async) for all production workloads
* **`createAndPoll()` helper** — Easy polling with `client.parseRuns.createAndPoll()`
* **Cleaner response structure** — Chunks moved to `output.chunks`, predictable nullable fields
* **Better file info** — `file` object instead of just `fileId`
* **Metadata support** — Pass custom metadata to track and identify parse runs
* **Simplified response shapes** — Single object responses returned directly, list responses use standardized `{ object: "list", data: [...] }` format

> **Note**
>
> The `/parse` sync endpoint is available and intended for onboarding and testing. For production use, we recommend `POST /parse_runs` with [webhooks](/webhooks/configuration) or [polling](/general/async-processing) instead.

---

This guide covers all breaking changes to the parse endpoints.

## Summary of Changes

| Old Endpoint               | New Endpoint              | Change Type | Description                                                                     |
| -------------------------- | ------------------------- | ----------- | ------------------------------------------------------------------------------- |
| `POST /parse`              | `POST /parse`             | Updated     | New request/response format (same as `/parse_runs`); for testing and onboarding |
| `POST /parse/async`        | `POST /parse_runs`        | Replaced    | Use `/parse_runs` instead                                                       |
| `GET /parser_runs/{id}`    | `GET /parse_runs/{id}`    | Replaced    | Response format updated                                                         |
| `DELETE /parser_runs/{id}` | `DELETE /parse_runs/{id}` | Replaced    | Response format simplified                                                      |

---

## SDK Changes

The SDK group and method names have been updated for consistency:

#### TypeScript

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

```typescript title="Before (2025-04-21)"
const run = await client.parse({ file: { fileUrl: "https://..." } });
const asyncRun = await client.parseAsync({ file: { fileUrl: "https://..." } });
const result = await client.parserRun.get("parser_run_abc123");
```

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

```typescript title="After (2026-02-09)"
const result = await client.parseRuns.createAndPoll({ file: { url: "https://..." } });
```

#### Python

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

```python title="Before (2025-04-21)"
run = client.parse(file={"file_url": "https://..."})
async_run = client.parse_async(file={"file_url": "https://..."})
result = client.parser_run.get("parser_run_abc123")
```

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

```python title="After (2026-02-09)"
result = client.parse_runs.create_and_poll(file={"url": "https://..."})
```

#### Java

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

```java title="After (2026-02-09)"
var result = client.parseRuns().createAndPoll(ParseRunsCreateRequest.builder()
    .file(ParseRunsCreateRequestFile.of(FileFromUrl.builder().url("https://...").build()))
    .build());
```

---

## ParseRun Schema (formerly ParserRun)

The `ParserRun` schema has been replaced with a unified `ParseRun` schema that handles both sync and async cases. Status-dependent fields are now **required but nullable** for a predictable response structure.

| Property        | Old (ParserRun)                      | New (ParseRun)                                        | Change                                                     |
| --------------- | ------------------------------------ | ----------------------------------------------------- | ---------------------------------------------------------- |
| `object`        | Required `"parser_run"`              | Required `"parse_run"`                                | Value changed                                              |
| `id`            | Required `string`                    | Required `string`                                     | No change                                                  |
| `fileId`        | Required `string`                    | —                                                     | Removed, see `file`                                        |
| `file`          | —                                    | Required `FileSummary`                                | New (replaces `fileId`)                                    |
| `chunks`        | Required `array`                     | —                                                     | Moved to `output.chunks`                                   |
| `output`        | —                                    | Required `object \| null`                             | New (null when not `PROCESSED` or when `responseType=url`) |
| `outputUrl`     | —                                    | Required `string \| null`                             | New (null unless `PROCESSED` with `responseType=url`)      |
| `status`        | Required `"PROCESSED"` or `"FAILED"` | Required `"PROCESSING"`, `"PROCESSED"`, or `"FAILED"` | Added `PROCESSING`                                         |
| `failureReason` | Optional `string`                    | Required `string \| null`                             | Now required but nullable (null unless `FAILED`)           |
| `metrics`       | Required `object`                    | Required `object \| null`                             | Now nullable (null when not `PROCESSED`)                   |
| `config`        | Required `ParseConfig`               | Required `ParseConfig`                                | No change                                                  |

### Response Example

The following shows the ParseRun object structure.

**Note:** All fields are always present in the response. Status-dependent fields use `null` when not applicable.

```typescript
// Before (2025-04-21) - ParserRun (optional fields omitted when not applicable)
{
  "object": "parser_run",
  "id": "parser_run_xK9mLPqRtN3vS8wF5hB2cQ",
  "fileId": "file_Zk9mNP12Qw4yTv8BdR3H",
  "status": "PROCESSED",
  "chunks": [
    {
      "object": "chunk",
      "type": "page",
      "content": "# Document Title\n\nThis is the content...",
      "metadata": {
        "pageRange": { "start": 1, "end": 1 }
      },
      "blocks": [...]
    }
  ],
  "metrics": {
    "processingTimeMs": 1234,
    "pageCount": 5
  },
  "config": {
    "target": "markdown",
    "chunkingStrategy": { "type": "page" }
  },
  "usage": { "credits": 10 }
}

// After (2026-02-09) - ParseRun (all fields present, nullable fields use null)
{
  "object": "parse_run",
  "id": "pr_xK9mLPqRtN3vS8wF5hB2cQ",
  "file": {
    "object": "file",
    "id": "file_Zk9mNP12Qw4yTv8BdR3H",
    "name": "document.pdf",
    "type": "PDF",
    "metadata": {},
    "createdAt": "2025-01-01T00:00:00Z",
    "updatedAt": "2025-01-01T00:00:00Z"
  },
  "status": "PROCESSED",
  "output": {
    "chunks": [
      {
        "object": "chunk",
        "type": "page",
        "content": "# Document Title\n\nThis is the content...",
        "metadata": {
          "pageRange": { "start": 1, "end": 1 }
        },
        "blocks": [...]
      }
    ]
  },
  "outputUrl": null,
  "failureReason": null,
  "metrics": {
    "processingTimeMs": 1234,
    "pageCount": 5
  },
  "config": {
    "target": "markdown",
    "chunkingStrategy": { "type": "page" }
  },
  "usage": { "credits": 10 }
}
```

---

## ParserRunStatus Schema - Removed

The `ParserRunStatus` schema from the old API (used for async responses) has been removed. The unified `ParseRun` schema now handles all states with the `PROCESSING` status.

| Property        | Old (ParserRunStatus)                              | New (ParseRun)                                     | Change                    |
| --------------- | -------------------------------------------------- | -------------------------------------------------- | ------------------------- |
| `object`        | Required `"parser_run_status"`                     | Required `"parse_run"`                             | Value changed             |
| `id`            | Required `string`                                  | Required `string`                                  | No change                 |
| `status`        | Required `"PROCESSING"`, `"PROCESSED"`, `"FAILED"` | Required `"PROCESSING"`, `"PROCESSED"`, `"FAILED"` | Now on main schema        |
| `failureReason` | Optional `string`                                  | Required `string \| null`                          | Now required but nullable |

When a parse run is still processing, the response will have `status: "PROCESSING"` and `output` will be `null`:

```typescript
// Before (2025-04-21) - ParserRunStatus for in-progress (from GET endpoint)
{
  "success": true,
  "parserRun": {
    "object": "parser_run_status",
    "id": "parser_run_xK9mLPqRtN3vS8wF5hB2cQ",
    "status": "PROCESSING"
  }
}

// After (2026-02-09) - ParseRun with PROCESSING status (from GET endpoint)
// All fields are always present; nullable fields are null when not applicable
{
  "object": "parse_run",
  "id": "pr_xK9mLPqRtN3vS8wF5hB2cQ",
  "file": { ... },
  "status": "PROCESSING",
  "output": null,
  "outputUrl": null,
  "metrics": null,
  "usage": null,
  "failureReason": null,
  "config": { ... }
}
```

---

## POST /parse_runs (formerly POST /parse and POST /parse/async)

### Endpoint Path

```bash
# Before (2025-04-21) - Two separate endpoints
POST /parse           # Synchronous
POST /parse/async     # Asynchronous

# After (2026-02-09) - Recommended production endpoint
POST /parse_runs      # Asynchronous, use with webhooks or polling

# Also available (for onboarding/testing only)
POST /parse           # Synchronous, returns completed result directly
```

### Request Body Changes

The request body structure has been updated with renamed properties:

```typescript
// Before (2025-04-21)
{
  "file": {
    "fileName": "document.pdf",
    "fileUrl": "https://example.com/document.pdf"
    // or
    "fileId": "file_abc123"
  },
  "config": {
    "target": "markdown",
    "chunkingStrategy": { "type": "page" },
    "blockOptions": { ... },
    "advancedOptions": { ... }
  }
}

// After (2026-02-09)
{
  "file": {
    "name": "document.pdf",
    "url": "https://example.com/document.pdf"
    // or
    "id": "file_abc123"
  },
  "config": {
    "target": "markdown",
    "chunkingStrategy": { "type": "page" },
    "blockOptions": { ... },
    "advancedOptions": { ... }
  },
  "metadata": {  // Optional - for tracking and identifying runs
    "customerId": "cust_123",
    "extend:usage_tags": ["production", "team-eng"]
  }
}
```

### Request Body Property Changes

| Old Property    | New Property | Change                                  |
| --------------- | ------------ | --------------------------------------- |
| `file.fileName` | `file.name`  | Renamed                                 |
| `file.fileUrl`  | `file.url`   | Renamed                                 |
| `file.fileId`   | `file.id`    | Renamed                                 |
| `config`        | `config`     | No change                               |
| —               | `metadata`   | New (optional object for tracking runs) |

### Query Parameter Changes

| Old Parameter  | New Parameter | Change                       |
| -------------- | ------------- | ---------------------------- |
| `responseType` | —             | Removed from create endpoint |

The `responseType` query parameter is no longer available on the create endpoint. Use it on the `GET /parse_runs/{id}` endpoint instead.

### Key Request Changes

1. **File Input**: File property names have been simplified:

```typescript
// Before - URL
{ "file": { "fileUrl": "https://...", "fileName": "doc.pdf" } }

// After - URL
{ "file": { "url": "https://...", "name": "doc.pdf" } }

// Before - File ID
{ "file": { "fileId": "file_abc123" } }

// After - File ID
{ "file": { "id": "file_abc123" } }
```

2. **Sync Endpoint Updated**: The sync endpoint (`POST /parse`) is still available and uses the **new request/response format** (same as `/parse_runs`). It's intended for testing and onboarding. For production, use `/parse_runs` with [polling](/general/async-processing) or [webhooks](/webhooks/configuration):

```typescript
// Before (2025-04-21) - synchronous with old schema
const run = await client.parse({
  file: { fileUrl: "https://..." }  // Old: fileUrl
});
console.log(run.chunks); // Old: chunks at root level

// After (2026-02-09) - sync endpoint with NEW schema (for testing only)
const run = await client.parse({
  file: { url: "https://..." }  // New: url (not fileUrl)
});
console.log(run.output.chunks);  // New: chunks in output

// After (2026-02-09) - RECOMMENDED: use createAndPoll for production
const result = await client.parseRuns.createAndPoll({
  file: { url: "https://..." }
});
console.log(result.output.chunks);
```

### Response Changes

The response structure has been updated:

```typescript
// Before (2025-04-21) - POST /parse returned ParserRun directly (not wrapped)
{
  "object": "parser_run",
  "id": "parser_run_abc123",
  "fileId": "file_xyz789",
  "status": "PROCESSED",
  "chunks": [...],
  "metrics": { ... },
  "config": { ... },
  "usage": { "credits": 10 }
}

// Before (2025-04-21) - POST /parse/async returned ParserRunStatus directly
{
  "object": "parser_run_status",
  "id": "parser_run_abc123",
  "status": "PROCESSING"
}

// After (2026-02-09) - POST /parse_runs returns ParseRun directly
{
  "object": "parse_run",
  "id": "pr_abc123",
  "file": {
    "object": "file",
    "id": "file_xyz789",
    "name": "document.pdf",
    "type": "PDF",
    "metadata": {},
    "createdAt": "2025-01-01T00:00:00Z",
    "updatedAt": "2025-01-01T00:00:00Z"
  },
  "status": "PROCESSED",
  "output": {
    "chunks": [...]
  },
  "outputUrl": null,
  "metrics": { ... },
  "config": { ... },
  "usage": { "credits": 10 }
}
```

---

## GET /parse_runs/\{id} (formerly GET /parser_runs/\{id})

### Endpoint Path

```bash
# Before (2025-04-21)
GET /parser_runs/parser_run_abc123

# After (2026-02-09)
GET /parse_runs/pr_abc123
```

### Query Parameter Changes

| Old Parameter  | New Parameter  | Change                                    |
| -------------- | -------------- | ----------------------------------------- |
| `responseType` | `responseType` | No change (still accepts `json` or `url`) |

The `responseType` query parameter controls how output is delivered:

* `json` (default) - Returns chunks in `output.chunks`
* `url` - Returns a presigned URL in `outputUrl` to download the output

### Response Changes

```typescript
// Before (2025-04-21)
{
  "success": true,
  "parserRun": {
    "object": "parser_run",
    "id": "parser_run_abc123",
    "fileId": "file_xyz789",
    "status": "PROCESSED",
    "chunks": [...],
    "metrics": { ... },
    "config": { ... },
    "usage": { "credits": 10 }
  }
}

// After (2026-02-09)
{
  "object": "parse_run",
  "id": "pr_abc123",
  "file": {
    "object": "file",
    "id": "file_xyz789",
    "name": "document.pdf",
    "type": "PDF",
    "metadata": {},
    "createdAt": "2025-01-01T00:00:00Z",
    "updatedAt": "2025-01-01T00:00:00Z"
  },
  "status": "PROCESSED",
  "output": {
    "chunks": [...]
  },
  "outputUrl": null,
  "metrics": { ... },
  "config": { ... },
  "usage": { "credits": 10 }
}
```

**Key differences:**

* No `success` field
* Response returned directly (no wrapper key)
* `fileId` → `file` (full File object)
* `chunks` → `output.chunks`
* New `outputUrl` field (for `responseType=url`)

---

## DELETE /parse_runs/\{id} (formerly DELETE /parser_runs/\{id})

### Endpoint Path

```bash
# Before (2025-04-21)
DELETE /parser_runs/parser_run_abc123

# After (2026-02-09)
DELETE /parse_runs/pr_abc123
```

### Response Changes

The response has been significantly simplified:

```typescript
// Before (2025-04-21)
{
  "success": true,
  "parserRunId": "parser_run_abc123",
  "message": "Parser run data has been successfully deleted."
}

// After (2026-02-09)
{
  "id": "pr_abc123"
}
```

**Key differences:**

* No `success` field
* `parserRunId` → `id`
* `message` field removed

---

## SDK Method Reference

| Old SDK Method              | New SDK Method                     | Notes                             |
| --------------------------- | ---------------------------------- | --------------------------------- |
| `client.parse()`            | `client.parse()`                   | Sync, for onboarding/testing only |
| `client.parseAsync()`       | `client.parseRuns.createAndPoll()` | Recommended for production        |
| `client.parserRun.get()`    | `client.parseRuns.retrieve()`      |                                   |
| `client.parserRun.delete()` | `client.parseRuns.delete()`        |                                   |

---

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