NativePort
← OCR API

Turn a scanned document into readable text

Read a scanned PDF or image with OCR and get Markdown for each selected page. Use the output for search, field extraction, or an AI workflow.

Try a request

curl
curl https://api.nativeport.ai/mistral/v1/ocr \
  -H "Authorization: Bearer $NATIVEPORT_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{
    "model": "mistral-ocr-4-0",
    "document": {
      "type": "document_url",
      "document_url": "https://example.com/scan.pdf"
    },
    "pages": [0, 1, 2]
  }'
example response
{
  "model": "mistral-ocr-4-0",
  "usage_info": {"pages_processed": 3},
  "pages": [
    {
      "index": 0,
      "markdown": "# INVOICE\n\n| Item | Qty | Price |\n| --- | --- | --- |\n| Widget | 2 | 19.00 |",
      "dimensions": {"dpi": 200, "height": 2200, "width": 1700}
    }
  ]
}

Select the pages you want to read

The request needs a document URL and a page selection. The example selects pages 0, 1, and 2, which are the first three pages. You can send the pinned model ID shown in the request or omit model to use NativePort’s supported OCR model.

Make the document available over HTTPS before sending the request. The file itself stays at that URL; the JSON body contains its reference and processing options. Each request can select up to 100 pages, so the Python example splits a longer document into batches.

The response returns Markdown for each processed page. The example joins those pages into one file, with separators so you can see where each page starts.

You can store that text for search or pass it to a model to extract specific fields. Mistral also supports structured annotations in the OCR request; the OCR overview explains that option and how it affects billing.

Save the selected pages as a Markdown file

Pass the document URL and page count. The script processes the selected pages in batches and saves their Markdown.

python
import json, os, sys, urllib.request

def ocr(url, pages):
    req = urllib.request.Request(
        "https://api.nativeport.ai/mistral/v1/ocr",
        data=json.dumps({
            "model": "mistral-ocr-4-0",
            "document": {"type": "document_url", "document_url": url},
            "pages": pages,
        }).encode(),
        headers={
            "Authorization": f"Bearer {os.environ['NATIVEPORT_API_KEY']}",
            "Content-Type": "application/json",
        },
    )
    with urllib.request.urlopen(req) as r:
        return json.load(r)

url = sys.argv[1]
total = int(sys.argv[2]) if len(sys.argv) > 2 else 10

parts = []
# `pages` is capped at 100 per call, so walk long documents in batches.
for start in range(0, total, 100):
    batch = list(range(start, min(start + 100, total)))
    res = ocr(url, batch)
    parts += [p["markdown"] for p in res["pages"]]
    print(f"  pages {batch[0]}–{batch[-1]}: "
          f"{res['usage_info']['pages_processed']} processed")

open("document.md", "w").write("\n\n---\n\n".join(parts))
print(f"wrote {len(parts)} pages to document.md")
example output
$ python ocr.py https://example.com/scan.pdf 12
  pages 0–11: 12 processed
wrote 12 pages to document.md

Use it with NativePort

Run OCR and process the resulting text with the same NativePort account. Your balance covers the document pages and any model requests you make afterwards.

Before you start

How do I send my file?

Upload it to a location accessible over HTTPS, then pass the URL in document.document_url. This route accepts a document reference and has a 16 KB request-body limit; it does not accept inline file bytes.

Which pages should I request?

Pages are numbered from zero. Select the pages you need using an array or a supported range string, with up to 100 pages per request. The example batches longer documents into groups of 100.

How is OCR billed?

OCR is billed per processed page. The response reports the count in usage_info.pages_processed. Requests with structured annotations use the Document AI rate. Check the Mistral provider page for current prices.

Will the output preserve tables and headings?

The output includes Markdown structure, including headings and tables. Review a sample of your documents to check table structure and reading order before using the results in your workflow.