Quickstart
Create an API key, then send a file. New accounts start with 200 free credits.
curl https://api.ocrrouter.com/v1/ocr \
-H "Authorization: Bearer $OCRROUTER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "auto",
"file_url": "https://example.com/invoice.pdf",
"format": "markdown"
}'Request
POST https://api.ocrrouter.com/v1/ocr with a JSON body and an Authorization: Bearer header.
| model | string | A model ID such as mistral/mistral-ocr, or auto. |
| file_url | string | Public URL of a PDF or image. Use one of file_url, file_base64 or file_id. |
| file_base64 | string | The file as base64, up to 20 MB. |
| file_id | string | ID returned by POST /v1/files, for larger files. |
| format | string | markdown (default) or json. |
| pages | string | Page range, for example 1-5,8. Defaults to all pages. |
| fallbacks | string[] | Model IDs to try, in order, if the first model fails. |
| route | string | With model auto: quality (default), cheapest or fastest. |
| filename | string | Optional name shown in your activity log. |
Other endpoints:
GET /v1/modelslists every model, its price and whether it is available. No key needed.POST /v1/filestakes a multipart upload with afilefield and returns afile_idthat works for 24 hours.GET /v1/requests/:idreturns an earlier result. Add?format=jsonto get it in the other format.GET /v1/creditsreturns your balance and this key's usage.POST /v1/keys/temporaryreturns a temporary key with 50 credits. No sign-up, one per day.
Output formats
markdown
The whole document as Markdown. Tables are GitHub-flavoured tables, formulas are wrapped in $...$, and pages are separated by <!-- page:N -->.
json
The same structure from every model: pages, each with typed blocks. Block types are heading, paragraph, list, table, formula, image, header and footer. bbox, confidence and page size are null when the model does not provide them, which is the case for the models live today.
{
"id": "req_8f2c1a41d0b3c7e9a2",
"model": "mistral/mistral-ocr",
"format": "json",
"attempts": [
{
"model": "mistral/mistral-ocr",
"ok": true,
"ms": 1180
}
],
"pages": [
{
"index": 1,
"width": null,
"height": null,
"blocks": [
{
"type": "heading",
"level": 1,
"text": "Invoice INV-2041",
"bbox": null,
"confidence": null
},
{
"type": "paragraph",
"text": "Acme Supply Co.\n14 Harbour Street, Sydney NSW 2000",
"bbox": null,
"confidence": null
},
{
"type": "table",
"rows": [
[
"Item",
"Qty",
"Unit price",
"Amount"
],
[
"A4 paper, 5 reams",
"4",
"$24.00",
"$96.00"
]
],
"markdown": "| Item | Qty | Unit price | Amount |\n|---|---|---|---|\n| A4 paper, 5 reams | 4 | $24.00 | $96.00 |",
"bbox": null,
"confidence": null
}
]
}
],
"usage": {
"pages": 1,
"credits": 6,
"latency_ms": 1180,
"cached": false
}
}Routing and fallbacks
Set model to auto and we choose a model for each document. Use route to say what matters: cheapest, fastest or quality.
Add fallbacks to keep working through outages. If the first model errors or is rate-limited, the next one runs. The response tells you which model answered, and you pay only for that one.
{
"model": "mistral/mistral-ocr",
"fallbacks": ["google/gemini-flash", "tesseract/tesseract"],
"file_url": "https://example.com/report.pdf"
}Credits
Each model has a price in credits per page. $1 buys 1,000 credits and they do not expire. Every response includes usage.credits.
- Failed and empty results are free.
- Sending the same file to the same model again is served from cache for free.
- Each API key can have its own credit limit.
Errors
Agents, MCP and CLI
Coding agents can use OCRRouter without a sign-up step. The CLI and the MCP server ask for a temporary key with 50 credits on first use and save it in ~/.ocrrouter/config.json. Set OCRROUTER_API_KEY to use your own key.
# CLI
npx ocrrouter invoice.pdf --format markdown
# MCP server for Claude Code
claude mcp add ocrrouter -- npx ocrrouter mcpA machine-readable summary of this page is at /llms.txt.