Text recognition (OCR)
maKI recognises text in images and PDF documents and returns it as Markdown, page by page. Behind it runs PaddleOCR-VL on Uni Mannheim’s GPU infrastructure; documents never leave the university network.
The endpoint follows the schema of the Mistral OCR API. It is not a chat endpoint: there is no prompt, no messages and no tokens. Document in, text out.
| Endpoint | POST https://maki.uni-mannheim.de/v1/ocr |
| Model | paddleocr-vl |
| Access group | ocr (select it when requesting a key) |
| Input | PNG, JPEG or PDF as a data URL in the request body |
| Output | Markdown per page |
Recognise an image
Section titled “Recognise an image”The image is passed Base64-encoded as a data URL in the document field:
MAKI_API_KEY="..."IMAGE=$(base64 -i scan.png | tr -d '\n')
curl https://maki.uni-mannheim.de/v1/ocr \ -H "Authorization: Bearer ${MAKI_API_KEY}" \ -H "Content-Type: application/json" \ -d "{ \"model\": \"paddleocr-vl\", \"document\": { \"type\": \"image_url\", \"image_url\": \"data:image/png;base64,${IMAGE}\" } }"Response:
{ "object": "ocr", "model": "paddleocr-vl", "pages": [ { "index": 0, "markdown": "Invoice no. 2026-0815\n\nUniversität Mannheim, Schloss\n\nAmount: 1,234.56 EUR", "images": [], "dimensions": { "dpi": null, "height": null, "width": null } } ], "usage_info": { "pages_processed": 1 }}Recognise a PDF
Section titled “Recognise a PDF”For PDFs the document type is document_url. Every page of the PDF becomes
one entry in pages, in order, with index starting at 0:
PDF=$(base64 -i minutes.pdf | tr -d '\n')
curl https://maki.uni-mannheim.de/v1/ocr \ -H "Authorization: Bearer ${MAKI_API_KEY}" \ -H "Content-Type: application/json" \ -d "{ \"model\": \"paddleocr-vl\", \"document\": { \"type\": \"document_url\", \"document_url\": \"data:application/pdf;base64,${PDF}\" } }"Python
Section titled “Python”The endpoint is not part of the OpenAI SDK; a plain HTTP call is enough:
import base64import requests
MAKI_API_KEY = "..."
with open("minutes.pdf", "rb") as f: data = base64.b64encode(f.read()).decode()
response = requests.post( "https://maki.uni-mannheim.de/v1/ocr", headers={"Authorization": f"Bearer {MAKI_API_KEY}"}, json={ "model": "paddleocr-vl", "document": { "type": "document_url", "document_url": f"data:application/pdf;base64,{data}", }, }, timeout=120,)response.raise_for_status()
for page in response.json()["pages"]: print(f"--- page {page['index'] + 1} ---") print(page["markdown"])For images: "type": "image_url", "image_url": "data:image/png;base64,...".
- Data URLs only. An
https://address asimage_urlordocument_urlis currently not fetched and rejected withHTTP 400. Download the document yourself and pass it Base64-encoded. - All pages. The
pagesfield for page selection is still ignored, as isinclude_image_base64;imagesstays empty. The response always contains every page of the document. - Latency. One page takes about one to two seconds. Documents are processed in blocks of twelve pages; split very long PDFs beforehand, since a request is cut off after 75 seconds.
- Size. Base64 inflates the file by a third. Scale images to a sensible resolution before sending (text clearly legible, roughly 150 to 300 dpi).
- No prompt. To process the recognised text further (summarise, extract fields), send the Markdown to a chat model in a second step, see Structured output.