OCR pipelines: pick one name@version per call
A pipeline is a fixed, versioned way to read a page. Pass pipeline=name@version on every call and it stays that way until you change it. The pinned version is the one that reads.
curl -s -X POST "https://api.ocr-software.com/v1/jobs?pipeline=scan-ctc@2&formats=json" \
-H "Authorization: Bearer $OCR_KEY" --data-binary @page.pdf
The first call from key to result is in the API guide; what each format holds is on the output formats page.
OCR pipelines compared: version, best use and output
| Pipeline | Best for | Returns |
|---|---|---|
scan-ctc@2 | Clean and scanned pages where you need the place of every word and a confidence for each. | JSON, text, Markdown, hOCR, searchable PDF; a box for every word |
scan-ctc-tables@2 | Pages with tables: every cell comes back with its row and column, and every page area with its kind, such as table or text. | JSON, text, Markdown, hOCR, searchable PDF; a box for every line, page areas, table cells |
scan-vlm-ctc@2 | Hard pages, such as poor scans and fax, where a wrong word must not pass unnoticed. | JSON, text, Markdown, hOCR, searchable PDF; a box for every word, page areas, table cells, the origin of every word |
The speed of each pipeline, with the run behind it, is in the speed table below. It counts pages per second; multiply by 3,600 for pages per hour.
OCR output format by pipeline
| Pipeline | JSON | Text | Markdown | hOCR | Searchable PDF |
|---|---|---|---|---|---|
scan-ctc@2 | yes | yes | yes | yes, word level | yes, word level |
scan-ctc-tables@2 | yes | yes | yes, with tables | yes, line level | yes, line level |
scan-vlm-ctc@2 | yes, with origin | yes | yes, with tables | yes, word level | yes, word level |
Source: the capabilities of each pipeline version. Word level means a box for every word, line level one box per line; nothing is invented to fill a gap. A format a pipeline cannot deliver is answered with 422 capability_missing.
Measured OCR accuracy per pipeline
Each table is one claim, one row per pipeline. The figures come from our own runs; the columns after them say on how many pages, on which card, with which software revision and on which date. A cell that reads not measured has no run behind it yet, and we do not fill it with a guess.
Speed
| Pipeline | s per page, 1 at a time | s per page, 8 at a time | pages per s, 8 at a time | answered, 8 at a time | sent, 8 at a time | Pages | Card | Revision | Date |
|---|---|---|---|---|---|---|---|---|---|
scan-ctc@2 | 2.71 | 0.95 | 1.048 | 24 | 24 | 30 | not stated | f3ff4a24 | 2026-11-06 |
scan-ctc-tables@2 | 2.09 | 1.04 | 0.96 | 24 | 24 | 30 | not stated | f3ff4a24 | 2026-11-06 |
scan-vlm-ctc@2 | 9.59 | 7.58 | 0.132 | 24 | 24 | 30 | not stated | f3ff4a24 | 2026-11-06 |
Numbers on hard pages
| Pipeline | numbers | found | other form | missing | wrong without warning | Pages | Card | Revision | Date |
|---|---|---|---|---|---|---|---|---|---|
scan-ctc@2 | not measured | not measured | not measured | not measured | not measured | not measured | not measured | not measured | not measured |
scan-ctc-tables@2 | not measured | not measured | not measured | not measured | not measured | not measured | not measured | not measured | not measured |
scan-vlm-ctc@2 | 425 | 418 | 5 | 2 | 0 (on 9 pages) | 4 | not stated | 10fc2ac8 | 2026-11-07 |
Reproducible OCR: the CTC pipelines (scan-ctc) give the same bytes however a page is batched, 300 of 300 pages identical at batch size 1, 8 and 16 (test on 300 public pages, on the reference engine of the CTC pipelines). The language-model pipelines return the same characters after every restart when a page is read on its own: 98 of 98 test pages. For identical bytes at any load, use scan-ctc.
OCR pipeline details: best use and output per name@version
scan-ctc@2
Best for: Clean and scanned pages where you need the place of every word and a confidence for each. It returns the same bytes for a page however it is batched (shown on the reference engine), so a second run can be compared byte by byte, and it is the cheapest of the pipelines on offer. It has no table cells and no page areas; for those, use a pipeline that lists them.
Other pages: hard pages, where a wrong word must be flagged: scan-vlm-ctc@2; pages that arrive turned, which are checked and turned upright first: scan-ctc-tables@2.
Returns: JSON, text, Markdown, hOCR, searchable PDF; a box for every word.
| Dimension | Value |
|---|---|
| Output formats | json, text, md, hocr, pdf |
| Box and confidence | per word |
| Confidence for every word | yes |
| Origin of every word | no |
| Page areas (layout classes) | no |
| Table cells | no |
| Page turned upright | no |
| Text layer of the file | ignored, every page is read as an image |
| Same output at any batching | same bytes; shown on the reference engine |
| Can invent text | no |
| Smallest GPU | compute capability 7.5, 8 GiB, driver 570 |
| Price factor | 1 |
scan-ctc-tables@2
Best for: Pages with tables: every cell comes back with its row and column, and every page area with its kind, such as table or text. A page that lies turned is checked first and turned upright when that reads better. The boxes are per line, not per word, and there is no confidence for every word; if you need those, use a pipeline that gives them.
Other pages: pages without tables, read cheaper with a box and a confidence for every word: scan-ctc@2.
Returns: JSON, text, Markdown, hOCR, searchable PDF; a box for every line, page areas, table cells.
| Dimension | Value |
|---|---|
| Output formats | json, text, md, hocr, pdf |
| Box and confidence | per line |
| Confidence for every word | no |
| Origin of every word | no |
| Page areas (layout classes) | yes |
| Table cells | yes |
| Page turned upright | yes |
| Text layer of the file | ignored, every page is read as an image |
| Same output at any batching | not known |
| Can invent text | no |
| Smallest GPU | compute capability 7.5, 12.5 GiB, driver 580 |
| Price factor | 1.5 |
scan-vlm-ctc@2
Best for: Hard pages, such as poor scans and fax, where a wrong word must not pass unnoticed. A language model reads the text; the CTC reader gives each word its box and confidence, and every word says where it came from and whether the two readings agree. It is the slowest and dearest of the pipelines on offer. Because a language model writes the text, it can invent words and does not promise the same bytes at any load; the per-word marks are there for that.
Other pages: clean pages in bulk, read faster and cheaper and with the same bytes every time: scan-ctc@2.
Returns: JSON, text, Markdown, hOCR, searchable PDF; a box for every word, page areas, table cells, the origin of every word.
| Dimension | Value |
|---|---|
| Output formats | json, text, md, hocr, pdf |
| Box and confidence | per word |
| Confidence for every word | yes |
| Origin of every word | yes |
| Page areas (layout classes) | yes |
| Table cells | yes |
| Page turned upright | yes |
| Text layer of the file | ignored, every page is read as an image |
| Same output at any batching | not guaranteed |
| Can invent text | yes |
| Smallest GPU | compute capability 8.0, 17.5 GiB, driver 580 |
| Price factor | 4 |
Run data: words flagged, revision, hardware, input
Every example page in the gallery shows the run data of its answer: how that page was read, so that you can compare two answers or read the page again the same way. Reading it:
- Words flagged: only the pipelines with an origin for every word read a page twice and compare the two readings. A word where they differ carries a marker (
differs,punct_differs,low_conf,no_ctc,not_in_model) and counts as flagged; a word where they agree isok. The other pipelines read a page once and return lines or words without markers, so the value is 0 or missing. - Software revision: the version of the software that produced the answer, so the same page can be read again the same way.
- Hardware: the machine the page ran on, and whether its GPU was used.
- Input: the page, its size in pixels, its resolution, the size it was reduced to for reading and the angle it was turned by.
The counts are the lines, the words, and the words below 0.90 confidence; a word below that value is the one to look at first.
Mixed batches and custom OCR pipelines
A mixed batch: send two jobs, one per pipeline. A special need: see your own pipeline.