PDFCraft
Extraction guide

Extract a inspection report PDF to JSON

Everything below is the response the live API returned for a inspection report, generated when this page was built. Not a description of what it would return — the output itself, including what it scored low on.

Who this is for

Compliance, facilities and asset-management tools keeping an auditable record of periodic inspections.

The job, in the words people search for: “digitise inspection reports into a compliance record”.

What makes this shape awkward

A pass/fail column of single characters beside a long observations column. Short cells and very long cells in the same table pull the column bands in opposite directions, and an observation that wraps onto a second line is the commonest cause of a table ending early.

The measured result

Pages read1
Time7 ms (7 ms/page)
Labelled fields found unprompted5
Tables1 (8 rows)
Inputinspection-report.pdf (29 KB — synthetic, generated from a spec in the repo; real documents of this type cannot be published)

Fields, with a schema

Ask for the fields you want by the label printed on the page. Each answer carries the text exactly as printed (raw), the value coerced to the type you asked for, a confidence, and a bounding box you can draw on the page to check it.

curl -X POST https://api.pdfcraft.dev/v1/extract \
  -H "Authorization: Bearer $PDFCRAFT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "file": "<base64 of your inspection report>",
    "schema": {
      "report_number": "string",
      "inspection_date": "date",
      "next_due": "date"
    }
  }'

What came back

Fieldrawvalueconfidence
report_numberINS-2026-2214"INS-2026-2214"60%
inspection_date2026-03-12"2026-03-12"70%
next_due2026-09-12"2026-09-12"70%

Every label it found without being asked

Send no schema and you get all of these, keyed by the label as printed. Useful for discovering what a new supplier’s layout actually contains before you write a schema against it.

Report Number, Site, Inspection Date, Inspector, Next Due

Tables

Ref · Item · Result · Observation · 8 rows × 4 columns · page 1

Table confidence 90%. Header confidence 100% — the first row was promoted out of the data.

RefItemResultObservation
1Fire alarm panelPassNo faults logged
2Emergency lightingPassAll units tested
3ExtinguishersFailUnit 3B overdue service

First 3 of 8 rows.

With options.rows_as_objects, the same row keyed by its header:

{
  "Ref": "1",
  "Item": "Fire alarm panel",
  "Result": "Pass",
  "Observation": "No faults logged"
}

What this does not do

Try it on your own inspection report

The playground takes a file and shows the same JSON, with every bounding box drawn over the page. No key and no signup for the first few; a free key gives you 100 pages a month.

Related