Migration Guides2026-02-09

Parse Runs Migration

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

The /parse sync endpoint is available and intended for onboarding and testing. For production use, we recommend POST /parse_runs with webhooks or polling instead.


This guide covers all breaking changes to the parse endpoints.

Summary of Changes

Old EndpointNew EndpointChange TypeDescription
POST /parsePOST /parseUpdatedNew request/response format (same as /parse_runs); for testing and onboarding
POST /parse/asyncPOST /parse_runsReplacedUse /parse_runs instead
GET /parser_runs/{id}GET /parse_runs/{id}ReplacedResponse format updated
DELETE /parser_runs/{id}DELETE /parse_runs/{id}ReplacedResponse format simplified

SDK Changes

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

Before (2025-04-21)
1const run = await client.parse({ file: { fileUrl: "https://..." } });
2const asyncRun = await client.parseAsync({ file: { fileUrl: "https://..." } });
3const result = await client.parserRun.get("parser_run_abc123");
After (2026-02-09)
1const result = await client.parseRuns.createAndPoll({ file: { url: "https://..." } });

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.

PropertyOld (ParserRun)New (ParseRun)Change
objectRequired "parser_run"Required "parse_run"Value changed
idRequired stringRequired stringNo change
fileIdRequired stringRemoved, see file
fileRequired FileSummaryNew (replaces fileId)
chunksRequired arrayMoved to output.chunks
outputRequired object | nullNew (null when not PROCESSED or when responseType=url)
outputUrlRequired string | nullNew (null unless PROCESSED with responseType=url)
statusRequired "PROCESSED" or "FAILED"Required "PROCESSING", "PROCESSED", or "FAILED"Added PROCESSING
failureReasonOptional stringRequired string | nullNow required but nullable (null unless FAILED)
metricsRequired objectRequired object | nullNow nullable (null when not PROCESSED)
configRequired ParseConfigRequired ParseConfigNo 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.

1// Before (2025-04-21) - ParserRun (optional fields omitted when not applicable)
2{
3 "object": "parser_run",
4 "id": "parser_run_xK9mLPqRtN3vS8wF5hB2cQ",
5 "fileId": "file_Zk9mNP12Qw4yTv8BdR3H",
6 "status": "PROCESSED",
7 "chunks": [
8 {
9 "object": "chunk",
10 "type": "page",
11 "content": "# Document Title\n\nThis is the content...",
12 "metadata": {
13 "pageRange": { "start": 1, "end": 1 }
14 },
15 "blocks": [...]
16 }
17 ],
18 "metrics": {
19 "processingTimeMs": 1234,
20 "pageCount": 5
21 },
22 "config": {
23 "target": "markdown",
24 "chunkingStrategy": { "type": "page" }
25 },
26 "usage": { "credits": 10 }
27}
28
29// After (2026-02-09) - ParseRun (all fields present, nullable fields use null)
30{
31 "object": "parse_run",
32 "id": "pr_xK9mLPqRtN3vS8wF5hB2cQ",
33 "file": {
34 "object": "file",
35 "id": "file_Zk9mNP12Qw4yTv8BdR3H",
36 "name": "document.pdf",
37 "type": "PDF",
38 "metadata": {},
39 "createdAt": "2025-01-01T00:00:00Z",
40 "updatedAt": "2025-01-01T00:00:00Z"
41 },
42 "status": "PROCESSED",
43 "output": {
44 "chunks": [
45 {
46 "object": "chunk",
47 "type": "page",
48 "content": "# Document Title\n\nThis is the content...",
49 "metadata": {
50 "pageRange": { "start": 1, "end": 1 }
51 },
52 "blocks": [...]
53 }
54 ]
55 },
56 "outputUrl": null,
57 "failureReason": null,
58 "metrics": {
59 "processingTimeMs": 1234,
60 "pageCount": 5
61 },
62 "config": {
63 "target": "markdown",
64 "chunkingStrategy": { "type": "page" }
65 },
66 "usage": { "credits": 10 }
67}

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.

PropertyOld (ParserRunStatus)New (ParseRun)Change
objectRequired "parser_run_status"Required "parse_run"Value changed
idRequired stringRequired stringNo change
statusRequired "PROCESSING", "PROCESSED", "FAILED"Required "PROCESSING", "PROCESSED", "FAILED"Now on main schema
failureReasonOptional stringRequired string | nullNow required but nullable

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

1// Before (2025-04-21) - ParserRunStatus for in-progress (from GET endpoint)
2{
3 "success": true,
4 "parserRun": {
5 "object": "parser_run_status",
6 "id": "parser_run_xK9mLPqRtN3vS8wF5hB2cQ",
7 "status": "PROCESSING"
8 }
9}
10
11// After (2026-02-09) - ParseRun with PROCESSING status (from GET endpoint)
12// All fields are always present; nullable fields are null when not applicable
13{
14 "object": "parse_run",
15 "id": "pr_xK9mLPqRtN3vS8wF5hB2cQ",
16 "file": { ... },
17 "status": "PROCESSING",
18 "output": null,
19 "outputUrl": null,
20 "metrics": null,
21 "usage": null,
22 "failureReason": null,
23 "config": { ... }
24}

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

Endpoint Path

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

1// Before (2025-04-21)
2{
3 "file": {
4 "fileName": "document.pdf",
5 "fileUrl": "https://example.com/document.pdf"
6 // or
7 "fileId": "file_abc123"
8 },
9 "config": {
10 "target": "markdown",
11 "chunkingStrategy": { "type": "page" },
12 "blockOptions": { ... },
13 "advancedOptions": { ... }
14 }
15}
16
17// After (2026-02-09)
18{
19 "file": {
20 "name": "document.pdf",
21 "url": "https://example.com/document.pdf"
22 // or
23 "id": "file_abc123"
24 },
25 "config": {
26 "target": "markdown",
27 "chunkingStrategy": { "type": "page" },
28 "blockOptions": { ... },
29 "advancedOptions": { ... }
30 },
31 "metadata": { // Optional - for tracking and identifying runs
32 "customerId": "cust_123",
33 "extend:usage_tags": ["production", "team-eng"]
34 }
35}

Request Body Property Changes

Old PropertyNew PropertyChange
file.fileNamefile.nameRenamed
file.fileUrlfile.urlRenamed
file.fileIdfile.idRenamed
configconfigNo change
metadataNew (optional object for tracking runs)

Query Parameter Changes

Old ParameterNew ParameterChange
responseTypeRemoved 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:
1// Before - URL
2{ "file": { "fileUrl": "https://...", "fileName": "doc.pdf" } }
3
4// After - URL
5{ "file": { "url": "https://...", "name": "doc.pdf" } }
6
7// Before - File ID
8{ "file": { "fileId": "file_abc123" } }
9
10// After - File ID
11{ "file": { "id": "file_abc123" } }
  1. 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 or webhooks:
1// Before (2025-04-21) - synchronous with old schema
2const run = await client.parse({
3 file: { fileUrl: "https://..." } // Old: fileUrl
4});
5console.log(run.chunks); // Old: chunks at root level
6
7// After (2026-02-09) - sync endpoint with NEW schema (for testing only)
8const run = await client.parse({
9 file: { url: "https://..." } // New: url (not fileUrl)
10});
11console.log(run.output.chunks); // New: chunks in output
12
13// After (2026-02-09) - RECOMMENDED: use createAndPoll for production
14const result = await client.parseRuns.createAndPoll({
15 file: { url: "https://..." }
16});
17console.log(result.output.chunks);

Response Changes

The response structure has been updated:

1// Before (2025-04-21) - POST /parse returned ParserRun directly (not wrapped)
2{
3 "object": "parser_run",
4 "id": "parser_run_abc123",
5 "fileId": "file_xyz789",
6 "status": "PROCESSED",
7 "chunks": [...],
8 "metrics": { ... },
9 "config": { ... },
10 "usage": { "credits": 10 }
11}
12
13// Before (2025-04-21) - POST /parse/async returned ParserRunStatus directly
14{
15 "object": "parser_run_status",
16 "id": "parser_run_abc123",
17 "status": "PROCESSING"
18}
19
20// After (2026-02-09) - POST /parse_runs returns ParseRun directly
21{
22 "object": "parse_run",
23 "id": "pr_abc123",
24 "file": {
25 "object": "file",
26 "id": "file_xyz789",
27 "name": "document.pdf",
28 "type": "PDF",
29 "metadata": {},
30 "createdAt": "2025-01-01T00:00:00Z",
31 "updatedAt": "2025-01-01T00:00:00Z"
32 },
33 "status": "PROCESSED",
34 "output": {
35 "chunks": [...]
36 },
37 "outputUrl": null,
38 "metrics": { ... },
39 "config": { ... },
40 "usage": { "credits": 10 }
41}

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

Endpoint Path

$# Before (2025-04-21)
$GET /parser_runs/parser_run_abc123
$
$# After (2026-02-09)
$GET /parse_runs/pr_abc123

Query Parameter Changes

Old ParameterNew ParameterChange
responseTyperesponseTypeNo 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

1// Before (2025-04-21)
2{
3 "success": true,
4 "parserRun": {
5 "object": "parser_run",
6 "id": "parser_run_abc123",
7 "fileId": "file_xyz789",
8 "status": "PROCESSED",
9 "chunks": [...],
10 "metrics": { ... },
11 "config": { ... },
12 "usage": { "credits": 10 }
13 }
14}
15
16// After (2026-02-09)
17{
18 "object": "parse_run",
19 "id": "pr_abc123",
20 "file": {
21 "object": "file",
22 "id": "file_xyz789",
23 "name": "document.pdf",
24 "type": "PDF",
25 "metadata": {},
26 "createdAt": "2025-01-01T00:00:00Z",
27 "updatedAt": "2025-01-01T00:00:00Z"
28 },
29 "status": "PROCESSED",
30 "output": {
31 "chunks": [...]
32 },
33 "outputUrl": null,
34 "metrics": { ... },
35 "config": { ... },
36 "usage": { "credits": 10 }
37}

Key differences:

  • No success field
  • Response returned directly (no wrapper key)
  • fileIdfile (full File object)
  • chunksoutput.chunks
  • New outputUrl field (for responseType=url)

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

Endpoint Path

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

1// Before (2025-04-21)
2{
3 "success": true,
4 "parserRunId": "parser_run_abc123",
5 "message": "Parser run data has been successfully deleted."
6}
7
8// After (2026-02-09)
9{
10 "id": "pr_abc123"
11}

Key differences:

  • No success field
  • parserRunIdid
  • message field removed

SDK Method Reference

Old SDK MethodNew SDK MethodNotes
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.


Migration Guides

GuideMigrating FromMigrating To
OverviewWhat’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.