Skip to main
Omar Nagy.
Menu
← writing·Receipts·~5 min read·filed 2026-11-12

How to convert a PDF to JSON without a model guessing the values

A rule-based way to turn a PDF into JSON where every value carries the page, paragraph and sentence it came from, shown on a 5-page agreement.

5
pages in, four typed fields out, each with its source sentence
  • pdf
  • json
  • document-extraction
  • arabic

The short answer

Converting a PDF to JSON is two jobs. First you get the text out of the file in reading order. Then you map that text to the fields you care about and give each one a type. The part that decides whether you can trust the result is the second job: every value should come with the page, the paragraph and the exact sentence it was read from.

What I did on a 5-page agreement

I built a document-to-JSON tool, and the clearest way to show how it behaves is one real run on its bundled sample, a 5-page services agreement. I asked for four fields with a small JSON Schema: effective date, annual fee, notice period in days, and governing law.

The record that came back:

  • effective date: 2025-03-14, read from the sentence "made and entered into on 14 March 2025", found on page 1, paragraph P2
  • annual fee: 240000, as a number, not as text
  • notice period: 60 days
  • governing law: the full clause, 10.1, naming the laws of the United Arab Emirates as applied in Dubai

The document was split into 67 paragraphs and 50 clauses, each with a handle like P17 or C10. Nothing in the path was a language model and no API key was involved. The extraction is rule based, which means the same file gives the same answer every time.

Step by step

  1. Get the text layer. For a PDF with real text, read the text layer. For a scanned image you need OCR first, which is a different job with different error rates.
  2. Split it into paragraphs and clauses. Give each a stable handle. That handle is what lets a person jump to the evidence.
  3. Describe the fields as a schema. A JSON Schema with typed properties: string, number, integer, boolean, and dates as year-month-day.
  4. Add the document's own words. Telling the extractor to look for "notice of non-renewal" or "governed by" is the biggest single lever on accuracy. Quote the phrase the document actually uses.
  5. Keep the evidence. Return the verbatim sentence, the page and the paragraph next to every value.
  6. Return "not found" honestly. If a field is not there, the value is null and found is false. A guess that looks like an answer is the most expensive output.

Why the evidence matters more than the value

When a number goes into a contract review or an invoice system, someone will ask where it came from. If the answer is "the model said so", you have to reread the document. If the answer is "page 1, paragraph 2, this sentence", checking takes five seconds. That is also why the output works for AI agents that must cite their source and not only produce a blob of text.

The Arabic case

Arabic PDFs fail in ways English ones do not. Many store text in visual order, so a naive extractor returns reversed lines. Presentation-form glyphs come out as strange characters. Numbers can be written in Arabic-Indic digits, and dates can be Hijri. A tool that reads these files has to put lines back in reading order, map glyphs back to letters, and normalise digits before it parses any number. I treat each of these as a separate check, not as a general "Arabic support" switch.

What to do before you pick a tool

Take five of your own documents and write down the four fields you actually need from them. Convert each by hand and note where you found the value. That list is your test set. Any tool you try should reproduce it, with a source sentence next to every value.

If you want a second opinion on where your own documents stall a workflow, the audit page is the place to start.

// next move

Want this level of rigor on your own stack?

Find the leak: 1 week, $950, fixed scope. A plain-English plan plus one real fix built and working, yours to keep regardless.

// related essays