curl -X POST https://api.parserouter.com/v1/mineru/parse \
-H "Authorization: Bearer sk-pr-..." \
-F "file=@invoice.pdf" \
-F "model=mineru2.5-pro-2605"
import requests
resp = requests.post(
"https://api.parserouter.com/v1/mineru/parse",
headers={"Authorization": "Bearer sk-pr-..."},
files={"file": open("invoice.pdf", "rb")},
data={
"model": "mineru2.5-pro-2605",
},
timeout=600,
)
resp.raise_for_status()
data = resp.json()
markdown = data["markdown"]
for block in data["content_list"]:
print(block["type"], block.get("text", ""))
{
"markdown": "# Invoice #2041\n\n<table><tr><td>Item</td><td>Qty</td><td>Price</td></tr><tr><td>API credits</td><td>10,000</td><td>$99.00</td></tr></table>",
"page_count": 1,
"content_list": [
{
"type": "text",
"page_idx": 0,
"bbox": [80, 60, 420, 110],
"text": "Invoice #2041",
"text_level": null,
"text_format": null,
"img_path": null,
"content": null,
"sub_type": null,
"list_items": null,
"table_body": null,
"code_body": null
},
{
"type": "table",
"page_idx": 0,
"bbox": [80, 200, 920, 480],
"text": null,
"text_level": null,
"text_format": null,
"img_path": null,
"content": null,
"sub_type": null,
"list_items": null,
"table_body": "<table><tr><td>Item</td><td>Qty</td><td>Price</td></tr><tr><td>API credits</td><td>10,000</td><td>$99.00</td></tr></table>",
"code_body": null
}
]
}
API Reference
Parse a document
Convert a PDF or image into Markdown plus structured, reading-order content blocks.
POST
/
v1
/
mineru
/
parse
curl -X POST https://api.parserouter.com/v1/mineru/parse \
-H "Authorization: Bearer sk-pr-..." \
-F "file=@invoice.pdf" \
-F "model=mineru2.5-pro-2605"
import requests
resp = requests.post(
"https://api.parserouter.com/v1/mineru/parse",
headers={"Authorization": "Bearer sk-pr-..."},
files={"file": open("invoice.pdf", "rb")},
data={
"model": "mineru2.5-pro-2605",
},
timeout=600,
)
resp.raise_for_status()
data = resp.json()
markdown = data["markdown"]
for block in data["content_list"]:
print(block["type"], block.get("text", ""))
{
"markdown": "# Invoice #2041\n\n<table><tr><td>Item</td><td>Qty</td><td>Price</td></tr><tr><td>API credits</td><td>10,000</td><td>$99.00</td></tr></table>",
"page_count": 1,
"content_list": [
{
"type": "text",
"page_idx": 0,
"bbox": [80, 60, 420, 110],
"text": "Invoice #2041",
"text_level": null,
"text_format": null,
"img_path": null,
"content": null,
"sub_type": null,
"list_items": null,
"table_body": null,
"code_body": null
},
{
"type": "table",
"page_idx": 0,
"bbox": [80, 200, 920, 480],
"text": null,
"text_level": null,
"text_format": null,
"img_path": null,
"content": null,
"sub_type": null,
"list_items": null,
"table_body": "<table><tr><td>Item</td><td>Qty</td><td>Price</td></tr><tr><td>API credits</td><td>10,000</td><td>$99.00</td></tr></table>",
"code_body": null
}
]
}
Upload a document and receive it as a single Markdown string plus a flat list of content blocks in reading order. Accepts a single PDF or image (
.pdf, .png, .jpg, .jpeg). PDFs are parsed page by page; an image is treated as a single page.
Authentication
string
required
Your API key as a bearer token:
Bearer sk-pr-....Request
Send the document asmultipart/form-data.
file
required
The document to parse. Must be a PDF or image (
.pdf, .png, .jpg, .jpeg), up to 50 pages.string
default:"mineru2.5-pro-2605"
The parsing model to use.
mineru2.5-pro-2605 is currently the only option and is used by default if omitted.Models are versioned and never change behavior once released. For production, we recommend pinning this explicitly so a future default model never alters your results without you opting in.Coming soon
These options are planned but not yet available – the endpoint doesn’t accept them today, and the features they control are currently off. The response fields they populate (text_level, img_path, content) are still returned on every block, but are always null for now.
boolean
Coming soon. Detect heading levels. When available, title blocks will carry a
text_level (1–4) and headings will render with matching # depth in markdown. Today, titles are returned flat.boolean
Coming soon. Crop images, tables, and charts to hosted storage and return their URLs as
img_path on the relevant blocks (and as image links in markdown). Today, those blocks carry no URL.boolean
Coming soon. Generate a short text description of each image and chart block, returned as
content. Today, no description is generated.Response
string
The whole document rendered as a single Markdown string – headings, with tables and equations inline. (Per-level heading depth and hosted image links are coming soon – see
title_levels and extract_images.)integer
The number of pages parsed.
1 for an image.object[]
A flat list of content blocks in reading order across the whole document (this mirrors MinerU’s
content_list). Every block carries the full set of fields below; which ones are populated depends on type (the rest are null). Additional fields (e.g. captions and footnotes) may also appear and are passed through as-is.Show block
Show block
string
The block kind. Common values:
text (body text – and titles; per-title text_level is coming soon), list, equation, image, chart, table, code, header, footer, page_number, aside_text, page_footnote, ref_text.integer
The 0-based index of the page the block belongs to.
integer[] | null
The block’s bounding box as
[x_min, y_min, x_max, y_max], scaled to 0–1000 of the page width and height, with the origin at the top-left. null when not available.string | null
The block’s text. Present for text-like blocks (
text, titles, header, footer, etc.) and, for equation, the LaTeX source. null otherwise.integer | null
Heading level
1–4 on title blocks, driving the #-depth of the heading in markdown. Always present in every block; null for non-titles – and null everywhere for now, as per-heading levels are coming soon.string | null
The format of
text when applicable, e.g. latex for an equation. null otherwise.string | null
Public URL of the cropped asset for
image, chart, and table blocks. Always present; null when no asset is hosted – and null everywhere for now, as hosted image extraction is coming soon.string | null
A generated description of an
image or chart block. Always present; null unless a description was produced – and null everywhere for now, as image analysis is coming soon.string | null
The table rendered as HTML. Present for
table blocks; null otherwise.string[] | null
The items of a
list block, in order. null otherwise.string | null
The source of a
code block. null otherwise.string | null
A finer-grained subtype for blocks that have one (e.g.
list, image/chart, code). null otherwise.curl -X POST https://api.parserouter.com/v1/mineru/parse \
-H "Authorization: Bearer sk-pr-..." \
-F "file=@invoice.pdf" \
-F "model=mineru2.5-pro-2605"
import requests
resp = requests.post(
"https://api.parserouter.com/v1/mineru/parse",
headers={"Authorization": "Bearer sk-pr-..."},
files={"file": open("invoice.pdf", "rb")},
data={
"model": "mineru2.5-pro-2605",
},
timeout=600,
)
resp.raise_for_status()
data = resp.json()
markdown = data["markdown"]
for block in data["content_list"]:
print(block["type"], block.get("text", ""))
{
"markdown": "# Invoice #2041\n\n<table><tr><td>Item</td><td>Qty</td><td>Price</td></tr><tr><td>API credits</td><td>10,000</td><td>$99.00</td></tr></table>",
"page_count": 1,
"content_list": [
{
"type": "text",
"page_idx": 0,
"bbox": [80, 60, 420, 110],
"text": "Invoice #2041",
"text_level": null,
"text_format": null,
"img_path": null,
"content": null,
"sub_type": null,
"list_items": null,
"table_body": null,
"code_body": null
},
{
"type": "table",
"page_idx": 0,
"bbox": [80, 200, 920, 480],
"text": null,
"text_level": null,
"text_format": null,
"img_path": null,
"content": null,
"sub_type": null,
"list_items": null,
"table_body": "<table><tr><td>Item</td><td>Qty</td><td>Price</td></tr><tr><td>API credits</td><td>10,000</td><td>$99.00</td></tr></table>",
"code_body": null
}
]
}
Errors
ParseRouter uses standard HTTP status codes. Error responses have the shape{ "detail": "..." }.
| Status | Meaning | What to do |
|---|---|---|
400 | The file is not a valid PDF or image. | Check the file is one of the supported formats and not corrupted. |
401 | Missing or invalid API key. | Send a valid Authorization: Bearer sk-pr-... header. |
402 | Insufficient credits. | Top up your balance on the Billing page. |
413 | The document exceeds 50 pages. | Split the document into smaller files. |
429 | Rate limit exceeded. | Back off and retry after the Retry-After header (seconds). |
503 | The parsing backend is temporarily overloaded. | Retry after the Retry-After header. No charge is made. |
You’re only charged for successful parses (
200). Failed requests – including 400, 413, and 503 – never consume credits.