PDFCraft
Extraction guide

Extract a commercial invoice PDF to JSON

Everything below is the response the live API returned for a commercial invoice, 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

Accounts-payable tooling and B2B marketplaces, where invoices arrive as PDFs from hundreds of suppliers in nearly as many layouts.

The job, in the words people search for: “turn supplier invoices into rows in my accounting system”.

What makes this shape awkward

The header block is key/value pairs and the line items are a table, and the two need opposite treatment. A parser that sees everything as a table returns "Invoice Number:" as a one-column table and buries the line items under it.

The measured result

Pages read1
Time211 ms (211 ms/page)
Labelled fields found unprompted6
Tables1 (9 rows)
Inputcommercial-invoice.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 commercial invoice>",
    "schema": {
      "invoice_number": "string",
      "invoice_date": "date",
      "due_date": "date",
      "total_due": "currency"
    }
  }'

What came back

Fieldrawvalueconfidence
invoice_numberINV-2026-04817"INV-2026-04817"60%
invoice_date2026-03-14"2026-03-14"70%
due_date2026-04-13"2026-04-13"70%
total_dueUSD 14,882.5014882.5 USD70%

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.

Invoice Number, Invoice Date, Due Date, Purchase Order, Currency, Total Due

Tables

Description · Qty · Unit price · Line total · 9 rows × 4 columns · page 1

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

DescriptionQtyUnit priceLine total
Steel bracket, 40mm6288.001,728.00
Aluminium housing9107.00963.00
Cable loom, 2m18801.0014,418.00

First 3 of 9 rows.

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

{
  "Description": "Steel bracket, 40mm",
  "Qty": "6",
  "Unit price": "288.00",
  "Line total": "1,728.00"
}

What this does not do

Try it on your own commercial invoice

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