OCR

Scans to text, with the layout kept

Send a scanned PDF or a picture of a page. You get back the text in reading order, with tables split into rows and cells and checkboxes marked as ticked or empty.

Example

Part of a form from a Slovenian public tender, scanned:

Scanned form: PODATKI O GRADNJI, the name of the works, a short description, and seven kinds of works with one box ticked (NOVOGRADNJA - NOVOZGRAJEN OBJEKT)

What the service returns for it, as table rows (cells separated by a tab):

PODATKI O GRADNJI
naziv gradnje                        ČISTILNA NAPRAVA MEJA
kratek opis gradnje                  Čistilna naprava Meja, je locirana na parceli št.: 27/36 …
VRSTE GRADNJE                        ☑ NOVOGRADNJA - NOVOZGRAJEN OBJEKT
označiti vse ustrezne vrste gradnje  ☐ NOVOGRADNJA - PRIZIDAVA
                                     ☐ REKONSTRUKCIJA
                                     ☐ SPREMEMBA NAMEMBNOSTI
                                     ☐ ODSTRANITEV CELOTNEGA OBJEKTA
                                     ☐ LEGALIZACIJA
                                     ☐ MANJŠA REKONSTRUKCIJA

Plans and technical drawings are recognised: such a page is marked drawing and its labels are left out of the document text.

The model is Unlimited-OCR-2 (Baidu, MIT licence), 8-bit, reading one page at a time at 300 dpi. It runs on our own server in Slovenia; documents are not stored after the answer.

API

The API needs a key. Keys for all MediaAtlas services come from one place, services.mediaatlas.si; until it opens, write to info@mediaatlas.si.

Read a PDF

curl -X POST https://ocr.mediaatlas.si/v1/ocr?pages=1-5 \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/pdf" \
  --data-binary @document.pdf

Plain text only

curl -X POST "https://ocr.mediaatlas.si/v1/ocr?format=text" \
  -H "Authorization: Bearer $KEY" -H "Content-Type: image/png" --data-binary @page.png

JSON body

POST /v1/ocr
Content-Type: application/json

{"file": "<base64 PDF or image>", "pages": "2-7"}
POST /v1/ocr
The body is a PDF (application/pdf), one page image (PNG, JPEG, WebP, HEIC from iPhones, TIFF, BMP) or the JSON above. Up to 60 MB and 50 pages per request; ask for longer documents in ranges.
Photos
Phone photos are turned upright by their orientation tag and straightened when the text is tilted, so a receipt photographed at an angle still keeps its prices and total. Each page says by how many degrees it was turned (straightened).
?pages=3 · ?pages=2-7
Pages to read, 1-based and inclusive. A range past the end is cut to the document.
?format=text
Only the document text (text/plain) instead of JSON.
?multi=1
Read the pages together in one pass (eight at a time) instead of page by page. On our tests the text was the same and it was slower, so it is off by default.
GET /health
Is the model up. No key needed.

Output

{
  "model": "unlimited-ocr-2",
  "page_count": 6,
  "pages": [
    {"page": 1, "text": "REPUBLIKA SLOVENIJA\nUPRAVNA ENOTA MARIBOR\n…",
     "blocks": [
       {"type": "title", "level": 1, "box": [120, 78, 430, 99], "text": "NASLOVNA STRAN NAČRTA"},
       {"type": "table", "box": [117, 164, 928, 819], "html": "<table>…",
        "rows": [["naziv gradnje", "ČISTILNA NAPRAVA MEJA"], ["VRSTE GRADNJE", "☑ NOVOGRADNJA"]]}
     ],
     "drawing": false, "truncated": false, "tokens": 1547, "seconds": 9.4}
  ],
  "text": "…all pages that are not drawings…",
  "ms": 21758
}
blocks
In reading order: title (with level), header, footer, text, table, image, image_caption, ref_text, page_number, other. box is the position on a 0–1000 grid of the page.
drawing
Images cover 30 % of the page or more: a plan or detail rather than a document page. Its text is not in the document text.
truncated
The page hit the output limit, usually an empty form with many blank rows. Blank rows are removed from the answer.

Errors

Always JSON: {"error": {"code": "…", "message": "…"}}. 401 unauthorized (no or wrong key), 400 bad_pages / too_many_pages / bad_json, 413 too_large, 415 unsupported, 422 unreadable_pdf, 502 engine_error.