Document Parse API
POST /api/v1/documents/parse — turn a PDF, Word file, spreadsheet or image into Markdown, text, layout blocks and chunks with your own Nace key.
Turn a file into Markdown, plain text, layout blocks and optional chunks for retrieval. OCR runs when the file needs it.
Document parsing is bring-your-own-key for now. It runs on your own Nace API key (nace_sk_…) and your own Nace credit, and AnyRouter charges nothing for it. Add the key under Provider keys in the dashboard first. Without one the call returns 400 with code byok_required.
Authenticate with an LLM API key (sk-ar-v1-…) from /dashboard/keys, sent as Authorization: Bearer ….
Request
The body is JSON and is sent to Nace unchanged, so every parse option in the Nace Parse reference works here.
| Field | Type | Required | Description |
|---|---|---|---|
source | object | yes | The file. {"type":"url","url":"https://…","file_name":"report.pdf"}, a workspace_file, or a finished parse_result. A url must start with https:// and file_name needs an extension. |
page_ranges | {start,end}[] | no | One-based, inclusive page ranges. Defaults to all pages. |
parse_mode | low | medium | high | no | Effort. Defaults to low. |
output.formats | string[] | no | Any of markdown, text, blocks. Defaults to markdown and blocks. |
chunking.strategy | none | page | section | no | Returns retrieval-sized chunks. Defaults to none. |
The request body can be up to 256 KiB. Send the file by https:// URL, or upload it to Nace and name it as a workspace_file.
Query parameter wait_seconds (integer, 0 to 60) holds the call open until the parse finishes. An optional Idempotency-Key header makes a retry return the same job instead of a second one.
curl "https://anyrouter.dev/api/v1/documents/parse?wait_seconds=60" \
-H "Authorization: Bearer $ANYROUTER_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: report-2026-10-01" \
-d '{
"source": {
"type": "url",
"url": "https://example.com/report.pdf",
"file_name": "report.pdf"
},
"page_ranges": [{ "start": 1, "end": 3 }],
"output": { "formats": ["markdown"] }
}'Response
200 when the parse finished within wait_seconds:
{
"result_type": "parse",
"file_name": "report.pdf",
"lane": "pdf",
"document": { "page_count": 3, "markdown": "# Annual Report\n\n...", "text": null, "chunks": [] },
"ocr_applied": false,
"units": 3,
"disclosures": []
}202 when it is still running (or no wait_seconds was sent). The body is the job, for example {"job_id":"…","status":"queued"}. Read it from Nace with the same key, or send the same request again with the same Idempotency-Key and a wait_seconds to pick it up.
The answer is relayed as Nace sends it. X-AnyRouter-Documents-Pages carries the page count when it is known.
A parse result larger than 8 MiB is refused with 502 and code upstream_response_too_large. Narrow page_ranges, or drop blocks, chunks and OCR data from output.
Errors
| Status | Code | Meaning |
|---|---|---|
| 400 | byok_required | No Nace key on your account. Add one, then retry. |
| 400 | missing_required_fields, invalid_request | Missing or invalid source, or wait_seconds outside 0 to 60. |
| 413 | request_too_large | Body over 256 KiB. |
| 422, 429, … | Nace's own | Nace's error, with its message, for a bad file type, a rate limit or an empty balance. |
| 502 | upstream_response_too_large | Result over 8 MiB. |
| 504 | upstream_timeout | No answer in time. Retry with the same Idempotency-Key. |
Pricing
Nace bills pages to your own Nace account at its rate (parse is one credit per page). AnyRouter adds no charge; the request shows in Request Logs with no cost.