PDFtoMD
AI WorkflowsMistralOCRAPI

Mistral OCR Tutorial: Convert PDF to Markdown with the Hosted API

Mistral OCR turns PDFs into clean Markdown through a hosted API, with high accuracy on tables, figures, and multi column layouts. A hands on tutorial with setup, working requests, and when a hosted OCR beats a local library.

8 min readBy Rafael Abellan

Most PDF to Markdown libraries run on your own machine. You install a Python package, load the file, and get Markdown back. That works well for clean, text based documents. But the moment you hit a scanned contract, a two column research paper, or a report full of tables and figures, local tools start to struggle. They miss reading order, mangle tables, and drop the text that only exists inside an image.

Mistral OCR takes a different approach. It is a hosted OCR model that you call over an API. You upload a document, and the service returns clean Markdown with headings, tables, and figures preserved, along with structured metadata about each page. Because the heavy lifting happens on Mistral servers, you do not install any models, manage GPUs, or fight with system dependencies. You send a request and get Markdown back.

This tutorial walks through the whole workflow: getting an API key, uploading a PDF, making your first OCR request, parsing the response into Markdown files, and handling images. It also covers the honest tradeoffs, so you know when a hosted OCR is worth it and when a local library is the better call.

What Mistral OCR Actually Does

Mistral OCR is a document understanding model exposed through the Mistral platform API. Unlike a plain text extractor, it is built to preserve the structure of a document, not just the words. When you send it a PDF, it processes each page and returns Markdown that keeps the layout intact.

The features that matter most for PDF to Markdown work:

  • Layout aware output: Headings, paragraphs, and lists come back in the correct reading order, even for multi column pages where naive extractors interleave the columns.
  • Table extraction: Tables are rendered as Markdown tables rather than collapsed into a wall of numbers, which is where most simple tools fail.
  • Image and figure handling: The model detects figures and can return them as separate image assets with references in the Markdown, so charts and diagrams are not silently dropped.
  • Scanned document support: Because it is a true OCR model, it reads text baked into images. Scanned PDFs and photographed pages become searchable Markdown.
  • Math and equations: Mathematical notation is preserved in a form you can render, which is useful for scientific and technical documents.

The output is JSON that contains, among other fields, the Markdown for each page. Your job on the client side is mostly to concatenate those pages and save the result.

Step 1: Get an API Key

Sign up on the Mistral platform and create an API key from the console. Treat the key like a password. Never hardcode it in your source or commit it to a repository. The standard pattern is to store it in an environment variable and read it at runtime.

export MISTRAL_API_KEY="your_key_here"

Mistral OCR is a paid, usage based service billed roughly per page processed. There is no free perpetual tier for the API itself, so check the current pricing on the platform before you run a large batch. For occasional documents the cost is small, but for tens of thousands of pages it adds up, which is a factor we will return to when comparing hosted OCR with local libraries.

Step 2: Install the SDK

Mistral publishes an official Python client. Install it in a virtual environment to keep your dependencies clean.

python -m venv venv source venv/bin/activate pip install mistralai

There is also an official JavaScript client if you work in Node. The request shape is the same in both, so the concepts below carry over regardless of language.

Step 3: Your First OCR Request in Python

The cleanest flow has two parts. First you upload the PDF to the Mistral Files API, which returns a file ID. Then you point the OCR endpoint at that file and ask for Markdown back. Here is a complete, working script.

import os
from mistralai import Mistral

client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])

# 1. Upload the PDF to the Files API
with open("report.pdf", "rb") as f:
    uploaded = client.files.upload(
        file={"file_name": "report.pdf", "content": f},
        purpose="ocr",
    )

# 2. Get a short lived signed URL for the uploaded file
signed = client.files.get_signed_url(file_id=uploaded.id)

# 3. Run OCR on the document
response = client.ocr.process(
    model="mistral-ocr-latest",
    document={"type": "document_url", "document_url": signed.url},
    include_image_base64=False,
)

# 4. Join every page of Markdown into one document
markdown = "\n\n".join(page.markdown for page in response.pages)

with open("report.md", "w", encoding="utf-8") as out:
    out.write(markdown)

print(f"Converted {len(response.pages)} pages to report.md")

That is the entire core workflow. You upload once, process once, and write the joined Markdown to disk. The response.pages list holds one entry per page, and each entry carries a markdown field plus metadata such as detected images and dimensions.

No API keys, no setup. Drop a PDF into PDFtoMD and get clean Markdown back in seconds.

Step 4: Convert a PDF Straight From a URL

If your PDF is already hosted somewhere public, you can skip the upload step entirely and pass the URL directly. This is handy for documents on the open web or in a bucket with a signed link.

response = client.ocr.process(
    model="mistral-ocr-latest",
    document={
        "type": "document_url",
        "document_url": "https://example.com/whitepaper.pdf",
    },
)

markdown = "\n\n".join(page.markdown for page in response.pages)

The same endpoint also accepts images. Change the type to image_url and pass a link to a PNG or JPG of a scanned page, and Mistral OCR will return Markdown for that single image. This is useful for photographed receipts, screenshots, or one off pages that are not in a PDF container.

Step 5: Call the API Directly With curl

You do not need the SDK at all. The endpoint is a plain HTTPS POST, which makes it easy to call from any language or from the shell. Note the escaped variable so the shell expands your key correctly.

curl https://api.mistral.ai/v1/ocr \
  -H "Authorization: Bearer ${MISTRAL_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "mistral-ocr-latest",
    "document": {
      "type": "document_url",
      "document_url": "https://example.com/whitepaper.pdf"
    }
  }'

The response is JSON with a pages array. Each element has a markdown string and an images array. Pipe the output through a JSON tool such as jq to pull out just the Markdown, or parse it in whatever language your service is written in.

Step 6: Handle Extracted Images

Documents with charts, logos, and diagrams need those assets saved alongside the Markdown, otherwise the figure references point at nothing. Ask the API to include image data as base64, then write each image to disk.

import base64, os

response = client.ocr.process(
    model="mistral-ocr-latest",
    document={"type": "document_url", "document_url": signed.url},
    include_image_base64=True,
)

os.makedirs("images", exist_ok=True)

for page in response.pages:
    for img in page.images:
        data = img.image_base64.split(",")[-1]
        path = os.path.join("images", img.id)
        with open(path, "wb") as fh:
            fh.write(base64.b64decode(data))

The Markdown for each page already contains image references that match these IDs, so once the files are on disk the links resolve. If you are publishing to a static site or a wiki, upload the images to your asset host and rewrite the references to match.

How Mistral OCR Compares to Local Libraries

The real question is not whether Mistral OCR works. It does, and the output quality on hard documents is strong. The question is whether a hosted service fits your constraints better than a library you run yourself.

FactorMistral OCR (hosted)Local library
SetupAPI key onlyInstall, models, sometimes GPU
Scanned PDFsStrong, true OCRVaries, often weak
Tables and columnsHigh accuracyHit or miss
Cost modelPay per pageFree after hardware
Data privacyData leaves your networkStays local
Offline useNoYes

A hosted OCR wins when accuracy on messy documents matters more than anything else, when you do not want to manage infrastructure, and when your volume is moderate. A local library wins when your documents are simple and text based, when you process huge volumes where per page billing would be expensive, or when the files are sensitive enough that they cannot leave your network. If privacy is the deciding factor, running conversion on your own servers with a tool like the ones in our OCR for scanned PDFs guide is the safer path.

For a broader head to head across open source and hosted options, see our comparison of the best PDF to Markdown converters, and if you are building conversion into your own product, our API integration guide covers the design patterns you will need.

A Simpler Path When You Just Need the Markdown

Setting up an API key, a virtual environment, and an image handling loop is worthwhile when you are building an automated pipeline. But if you only need to convert a handful of documents, all of that plumbing is overhead. That is what PDFtoMD is for. You upload a PDF in the browser and get clean Markdown back in seconds, with headings, lists, and tables preserved, and nothing to install. The free tier gives you 3 conversions a month with no credit card, which is enough to check whether the output fits your workflow before you commit to writing code. You can see the full range of workflows it supports on the use cases page.

Frequently Asked Questions

Is Mistral OCR free to use?

No. The Mistral OCR API is a paid, usage based service billed per page. There is no perpetual free tier for the API, so estimate your page volume and check current pricing before running a large batch. For occasional documents the cost per file is small.

Does Mistral OCR handle scanned and photographed documents?

Yes. It is a genuine OCR model, so it reads text that lives inside images, including scanned pages and photos. This is the main advantage over text only extractors, which return nothing useful when a page is really just a picture of text.

Can it preserve tables and multi column layouts?

Yes. Table extraction and reading order for multi column pages are two of the areas where Mistral OCR is strongest. Tables come back as Markdown tables, and columns are read in the correct order rather than interleaved. Always spot check complex tables, since no converter is perfect on dense financial data.

What are the privacy implications?

Because it is a hosted API, your documents are sent to Mistral servers for processing. For public or low sensitivity files this is fine. For confidential contracts or regulated data, review the provider terms and consider a self hosted or local option so the files never leave your network.

Which model name should I use?

Use mistral-ocr-latest to always get the current OCR model, or pin a dated version string if you need reproducible output across runs. Pinning protects you from unexpected changes when the model is updated.

The Takeaway

Mistral OCR is a strong choice when your PDFs are messy: scanned pages, dense tables, multi column research papers, and figures that plain extractors ignore. You trade a small per page cost and the fact that data leaves your network for high accuracy and zero infrastructure. The workflow is short: get a key, upload the file, call ocr.process, and join the page Markdown.

If you are building a pipeline, the API is worth wiring up. If you just need clean Markdown from a few documents without touching code, upload them to PDFtoMD and skip the setup entirely. Either way, the goal is the same: turn locked up PDFs into structured Markdown you can search, edit, and feed to your tools.

Rafael Abellan

About the author

Rafael Abellan

Founder, PDFtoMD

Rafael Abellan is the founder of Agência Triva and ships independent side projects in parallel. PDFtoMD came out of a personal frustration: he kept burning through Claude AI's token limit by uploading long PDFs, then losing hours waiting for the cap to reset. He built the tool to fix his own workflow, and now uses it every day.

Ready to convert your PDFs to Markdown?

Free account · 3 conversions/month · No credit card required