mdfi.ai Docs

How it works

How mdfi scores every page, escalates the ones that need it, and shows what it is unsure about.

Three tiers

Every page is read once by Tier 1. A page that scores badly can be read again by a stronger tier, which costs more.

Tier What reads the page Weight
1 For PDF, Office, HTML and image files, a layout-aware document parser (Docling): the text layer of born-digital pages, with OCR for pages and regions that are images. Text and email files are parsed directly. 1
2 Enhanced OCR: for a PDF page, the whole page is OCR'd again at twice the resolution 2
3 A vision model, sent that one page on its own 5

The weight is what a page costs in weighted pages; Pricing explains the charge.

Only PDF and image pages escalate. Word, PowerPoint, Excel, HTML, email and text pages are read once, at Tier 1. A low score on one of those pages is flagged, not re-read, and costs nothing extra. Every plan can use all three tiers.

Page scores

Every page gets a score from 0 to 100. A page that scores 85 or more is accepted as it is. A PDF or image page under 85 is a candidate for a re-read.

What lowers a score:

  • A scanned page (fewer than 50 characters of text layer and an image over half the page; every page of an image file counts as one) whose OCR returned fewer than 30 words scores 20, unless its small text layer came through whole, such as a cover title over a full-page photo.
  • A page with a text layer of over 200 characters whose conversion kept less than a tenth of it scores 30.
  • OCR that lost the spaces between words (tohavepaidyourpartofthetax) caps the page at 60. This is checked on OCR output only, never on a born-digital text layer.
  • A table that fails a check a better reader could fix (see Tables) caps the page at 70, under the accept score.
  • Broken table markup, garbled or repeated output, and OCR noise on scanned pages take points off.

A blank page (no text and no image) is not penalised: it scores 100.

Flags and warnings

A page's flags say what mdfi noticed about it. The API lists them by name in each page's flags; the connector shows each one with its label:

Flag Label What it means
table_uncertain uncertain tables A table on the page failed a check that a better reader could fix.
table_issues table problems The page's table markup is broken: rows of different widths, or mostly empty cells.
table_missed a captioned table was read as text (no table id, so it cannot be exported) The page has a caption such as "Table 10-1." but its table came back as plain text. The text is readable; there is no table to export.
ocr read by OCR The page is a scan. A scan that scores 85 or more is not a concern and is listed once instead, as read from scans: pages 1–40.
no_text_recovered no text recovered from scan OCR returned fewer than 30 words from a scanned page.
ocr_noise OCR noise The OCR output of a scanned page has the marks of misreading, such as many stray single characters.
glued_words words run together (spacing lost) OCR lost the spaces between words.
text_missing text layer present but little or nothing extracted The page has a text layer, but its conversion came back empty or nearly empty. With a text layer of over 200 characters the page scores 30 and is re-read; with a smaller one (often only a running header or footer) it is flagged but not re-read.
degenerate garbled output The output degenerated into long runs of blank space or a repeated character.
low_quality low quality The page still scores under 85, after any re-reads.
not_enhanced_cap could not be enhanced (escalation cap reached) A re-read would have gone over the per-document escalation cap or the pages left this month, so the page was kept as it was.
vision_unavailable vision reader unavailable The vision model was not available, or returned nothing, for this page.
not_converted page could not be converted Tier 1 could not convert this page, even on its own, and no re-read replaced it. Tier 1 charges nothing for such a page.

A ⚠ means: check this before relying on it. The connector puts one in three places: under ⚠ uncertain — verify before relying on these: in the read_document header, which lists the uncertain tables, the flagged pages and any warnings; after every outline entry whose pages hold a flagged page or an uncertain table; and on the line under a page's --- page N --- marker in read_pages. Clean scans and informational table notes never get a ⚠; those notes are shown on plain table notes: and note: lines instead. For example, read_pages with pages="5" on the report from the Quickstart returns:

--- page 5 ---
⚠ table p5-t1: "Total" row 14 does not add up in column "2025"
note: table p5-t1: continues on page 6
## Regional results
[table p5-t1 — 14 rows × 4 cols, uncertain: "Total" row 14 does not add up in column "2025"]
Region  2024    2025    2026
…

The API's manifest also carries three neutral flags that the connector does not show: empty (a blank page), and enhanced_tier2 and enhanced_tier3 (the page's text came from that tier).

Escalation

After Tier 1, mdfi re-reads the PDF and image pages that scored under 85, by these rules:

  1. Worst first. Pages are taken in order of score, lowest first.
  2. Tier 2, then Tier 3. Each page tries enhanced OCR, then the vision model, and stops as soon as it scores 85 or more.
  3. A table-only problem skips Tier 2. When a page's text layer was read cleanly and only its table is in doubt, re-running OCR would not rebuild the table, so the page goes straight to the vision model. If no vision model is available, it is not re-read (and not charged) and stays flagged.
  4. Within the cap and the allowance. Each step runs only if its extra cost still fits: at most 100 extra weighted pages per document, and never so much that the document would cost more than the pages left this month. Tier 2 adds 1 to a Tier 1 page, Tier 3 adds 3 after Tier 2, or 4 straight from Tier 1. A page whose next step does not fit is flagged not_enhanced_cap (shown by the connector as "could not be enhanced (escalation cap reached)"), and the other pages carry on.
  5. A re-read must be better. Its text replaces the page only if it scores higher. Unless the page was blank or a scan, it must also keep at least half the page's words, so a short fragment never replaces a full page.
  6. Charged for the highest tier that returned output, even when a lower tier's version is kept. A tier that fails or returns nothing is not charged.

A scan that Tier 1 reads well (85 or more) is not re-read, so it costs 1. The vision model is sent only the one page it re-reads; Data and privacy covers what leaves mdfi.

Outline first, then pages

The outline comes as early as the file allows:

  • PDF bookmarks and PowerPoint slide titles are read from the file before conversion starts, so the agent can pick a section at once. An image shows its frame count, with no outline.
  • The file's outline is kept to the end when it has at least 3 entries and none of them covers more than 80% of the pages. Otherwise, and for files with no bookmarks or slide titles, the outline is built from the document's headings once Tier 1 is done.
  • A PDF without bookmarks gets an outline from the headings of the pages converted so far.
  • Word, Excel, HTML, email and text files get their outline from their headings once their text is converted, just before the document is ready.

Pages become readable as they are ready:

  • PDF: Tier 1 reads a PDF a few pages at a time (the first batch is at most 4 pages), and each batch is readable as soon as it is done. A page waiting for a re-read becomes readable when its re-read finishes.
  • Images and PowerPoint: pages are readable once Tier 1 is done, except image pages waiting for a re-read, which follow one by one.
  • Word, Excel, HTML, email and text: readable only when the whole document is ready. Their page count is only estimated before conversion, and a document that fails its final check is not charged, so showing its pages early would be a free read.

While a document converts, read_document lists the ready pages and read_pages returns the ready ones, naming the rest as still converting. The agent asks again later; nothing is charged until the document is ready.

Time left

While a document converts, the connector may add an estimate, such as should be ready in about N minutes (estimate). It is worked out from the pace of the pages converted so far, counting the pages still to convert and the pages queued for a re-read. It is an estimate, not a promise, and it is left out when there is nothing to base it on: before the first page is converted, when only re-reads remain (the pace of Tier 1 says nothing about how long a re-read takes), and when the conversion has run past its own projection.

Tables

Each table in the page text starts with a label line, followed by its rows with tab-separated cells:

[table p13-t1 — 42 rows × 6 cols]

The id p13-t1 means page 13, first table. The tables on a page are numbered in reading order, counting one continued from the previous page, and a table that runs over several pages keeps the id of its first page.

mdfi checks every table. A table that fails a check is uncertain, and its label says why, naming up to two problems: [table p13-t1 — 42 rows × 6 cols, uncertain: <problem>; <problem> (+1 more)]. The problems it reports:

  • rows with a different number of cells from the header;
  • a header with no rows;
  • empty or duplicate header cells;
  • text in a column of numbers, or cells that look like misread numbers (2O for 20);
  • a cell holding several numbers, often two rows merged into one;
  • a header row that looks like data;
  • a "Total" row that does not add up;
  • page read with low confidence (score N): the table is on a page that still scores under 85;
  • may continue as p14-t1 on page 14 (headers differ): a table ends a page and the next page starts with a table under different headers.

The first seven checks also run on each page by itself. A problem they find caps the page's score at 70, and on a PDF or image page that sends the page through escalation. Three problems do not cap the score, because a stronger reader would not change them: a total that does not add up (the source itself may not), a table that is only a header at the end of a page (its rows may be on the next page), and a header that looks like data on a table that starts its page (a continuation whose header was not repeated). Those tables stay marked uncertain.

Some notes are informational and never make a table uncertain: read by vision — verify (every table the vision model read), two-level header combined, continues on page N, and, while the document converts, may continue on page N (still converting).

export_table writes one table to a CSV file and, when the table has notes, a notes file beside it. It works once the document is ready, because a page still being re-read can extend a table. The Connector page has the details.

One conversion per file

The connector identifies a file by its SHA-256. It sends the hash first; if your account already has that document, mdfi returns it and charges nothing. If the file is still converting, the same document comes back with its progress. Only a file mdfi has not seen for your account is uploaded and converted. Any change to the file gives a new hash, so an edited file is a new document. Documents are kept per account: another account's copy of the same file is converted separately for that account.

A converted document is kept for 7 days. After that, reading the file again converts and charges it again. A conversion that failed keeps no pages, so trying again converts the file again.