PDFCraft
Extraction guide

Extract a explanation of benefits PDF to JSON

Everything below is the response the live API returned for a explanation of benefits, 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

Medical billing, RCM and patient-advocacy tools reconciling what was billed against what was paid.

The job, in the words people search for: “read an EOB into a medical billing system”.

What makes this shape awkward

Six numeric columns that must not be confused with one another — billed, allowed, paid, deductible, coinsurance, patient responsibility. They are all currency, all right-aligned, and several are zero on any given line. Getting one column wrong is a billing error, not a formatting one.

The measured result

Pages read1
Time9 ms (9 ms/page)
Labelled fields found unprompted5
Tables1 (5 rows)
Inputexplanation-of-benefits.pdf (30 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 explanation of benefits>",
    "schema": {
      "claim_number": "string",
      "member_id": "string",
      "service_date": "date"
    }
  }'

What came back

Fieldrawvalueconfidence
claim_numberCLM-2026-774102"CLM-2026-774102"60%
member_idMBR-4417-22"MBR-4417-22"60%
service_date2026-02-18"2026-02-18"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.

Claim Number, Member ID, Provider, Service Date, Patient Responsibility

Tables

Service · Code · Billed · Allowed · Paid · Deductible · You owe · 5 rows × 7 columns · page 1

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

ServiceCodeBilledAllowedPaidDeductibleYou owe
Office visit99213240.00148.00118.40—29.60
Blood panel80053180.0092.0073.60—18.40
X-ray, chest71046420.00210.00—210.00210.00

First 3 of 5 rows.

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

{
  "Service": "Office visit",
  "Code": "99213",
  "Billed": "240.00",
  "Allowed": "148.00",
  "Paid": "118.40",
  "Deductible": "",
  "You owe": "29.60"
}

What this does not do

Try it on your own explanation of benefits

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