Skip to content
Docs Security Sign in
PdfParse

Invoice OCR software that returns line items

Send a PDF invoice or a phone scan and get the vendor, dates, totals, tax and every line item back as typed JSON, with the page and confidence for each value. One API call, one schema, the same output for every supplier layout.

Parse PDF
A desktop document scanner with its feeder loaded with a stack of printed invoices in a back office

Parse an invoice before you sign up

Drop one of your own invoices or pick the sample invoice. Page 1 is parsed in full, with the JSON, Markdown and CSV tabs side by side and the rendered page showing every detected block.

Drop a PDF or scan

PDF, PNG or JPG up to 10 MB. Page one is parsed in full, right here.

Or try a sample file
Output

Optional. Comma separated field names, for example invoice_number, total, due_date.

Page one is parsed in your browser and never uploaded. No card needed to try page one.

What one call returns

Page one rendered with every block outlined, next to the JSON your code receives.

  1. Reading text layer
  2. Detecting layout
  3. Extracting tables
  4. Building JSON
Rendered page Page 1 of your document

Headings, paragraphs, tables and totals detected

heading
Invoice
paragraph
Harbor Street Joinery
14 Dock Lane
Portsmouth, NH 03801
key_value
Invoice no.INV-2026-0418IssuedOct 14, 2026DueNov 13, 2026
table
DescriptionQtyUnitAmount
Oak countertop, 2.4 m2640.001,280.00
Cabinet doors, shaker1285.001,020.00
On site fitting1450.00450.00
total
Subtotal2,750.00Tax 8.5%233.75Total dueUSD 2,983.75
paragraph
Payment by bank transfer within 30 days.
Quote the invoice number with your transfer.
Goods remain ours until paid in full.
footer
Harbor Street JoineryPage 1 of 2
Locked page

Pages 2 and later are parsed after you create an account.

Output
{
  "document": {
    "pages": 2,
    "parsed_pages": 1,
    "language": "en"
  },
  "pages": [
    {
      "number": 1,
      "blocks": [
        { "type": "heading", "text": "Invoice", "bbox": [48, 52, 132, 84] },
        { "type": "paragraph", "text": "Harbor Street Joinery, 14 Dock Lane, Portsmouth" },
        { "type": "key_value", "pairs": {
            "Invoice no.": "INV-2026-0418",
            "Issued": "Oct 14, 2026",
            "Due": "Nov 13, 2026" } },
        { "type": "table", "columns": ["Description", "Qty", "Unit", "Amount"],
          "rows": [
            ["Oak countertop, 2.4 m", 2, 640.00, 1280.00],
            ["Cabinet doors, shaker", 12, 85.00, 1020.00],
            ["On site fitting", 1, 450.00, 450.00] ] },
        { "type": "total", "label": "Total due", "value": 2983.75, "currency": "USD", "confidence": 0.98 }
      ]
    }
  ],
  "fields": {
    "invoice_number": { "value": "INV-2026-0418", "confidence": 0.99, "page": 1 },
    "total": { "value": 2983.75, "confidence": 0.98, "page": 1 },
    "due_date": { "value": "2026-11-13", "confidence": 0.97, "page": 1 }
  }
}

Downloads from the demo include a watermark field and cover page one only.

Page one is parsed in your browser, so your file never reaches our servers.

Request
The same request from your code
Read the API reference
$ curl https://api.pdfparse.ai/v1/parse \
  -H "Authorization: Bearer $PDFPARSE_API_KEY" \
  -F file[email protected] \
  -F outputs=json,markdown,csv
200 OK, 1 page parsed

One invoice schema for every supplier

Accounts payable teams receive invoices in hundreds of layouts. Instead of writing a template per supplier, you describe the fields you want once. PdfParse reads the page layout, finds the table of line items, and fills your fields with typed values. Money stays money, dates come back as ISO dates, and line items arrive as an array your code can loop over.

You create the schema with one request to POST /v1/schemas and pass its id with every parse call. The schema below covers the header, the totals and the line item table.

What comes back

Every field carries a confidence score and the page it was read from, so you can route low confidence values to a person and post the rest straight to your ledger. The full response also includes the Markdown of the page and the line item table as CSV.

JSON
{
  "name": "invoice",
  "fields": [
    { "name": "invoice_number", "type": "string", "description": "Invoice number as printed by the supplier" },
    { "name": "vendor_name", "type": "string", "description": "Legal or trading name of the supplier" },
    { "name": "invoice_date", "type": "date", "description": "Date the invoice was issued" },
    { "name": "due_date", "type": "date", "description": "Payment due date, if printed" },
    { "name": "currency", "type": "string", "description": "ISO currency code" },
    { "name": "subtotal", "type": "money", "description": "Amount before tax" },
    { "name": "tax", "type": "money", "description": "Total tax amount" },
    { "name": "total", "type": "money", "description": "Amount payable" },
    { "name": "line_items", "type": "array", "description": "One entry per billed line with description, quantity, unit_price and amount" }
  ]
}
JSON
{
  "id": "prs_8f2c41",
  "status": "completed",
  "fields": {
    "invoice_number": { "value": "HL-20481", "confidence": 0.98, "page": 1 },
    "vendor_name": { "value": "Harbor Lane Supplies", "confidence": 0.97, "page": 1 },
    "invoice_date": { "value": "2026-09-30", "confidence": 0.99, "page": 1 },
    "due_date": { "value": "2026-10-30", "confidence": 0.96, "page": 1 },
    "currency": { "value": "USD", "confidence": 0.99, "page": 1 },
    "subtotal": { "value": 1240.00, "confidence": 0.97, "page": 2 },
    "tax": { "value": 99.20, "confidence": 0.95, "page": 2 },
    "total": { "value": 1339.20, "confidence": 0.98, "page": 2 },
    "line_items": {
      "value": [
        { "description": "A4 copy paper, 5 ream box", "quantity": 20, "unit_price": 38.00, "amount": 760.00 },
        { "description": "Toner cartridge, black", "quantity": 6, "unit_price": 80.00, "amount": 480.00 }
      ],
      "confidence": 0.94,
      "page": 1
    }
  },
  "usage": { "pages": 2 }
}

How an invoice moves through PdfParse

  1. 1

    Your inbox, upload form or storage bucket hands the file to POST /v1/parse with your schema id.

  2. 2

    Small invoices return in the same response. Longer ones return a job id, and a parse.completed webhook tells your system when the result is ready.

  3. 3

    Your code reads the fields, checks the confidence values against your own threshold, and posts approved invoices to your accounting system.

  4. 4

    Invoices below the threshold go to a review queue together with the page number, so the reviewer opens the right page straight away.

  5. 5

    Month end backlogs go through batch jobs of up to 500 files per job, with an Idempotency-Key header so a retry never parses the same batch twice.

Operations teams that do not write code use the same engine in the web app. They upload a folder of invoices, pick the schema and export one CSV with a row per invoice or per line item.

Invoices that break simple OCR

Plain OCR returns words and boxes. Invoices need more than that, and these are the cases PdfParse handles in the same call.

  • Line item tables that continue on the next page are joined into one array, with the header row recognised once.
  • Merged cells, wrapped descriptions and sub rows stay attached to the right line instead of turning into new lines.
  • Scanned and skewed pages go through OCR automatically when there is no text layer. Set ocr to "always" for faxes with a broken text layer.
  • Credit notes keep their negative amounts, and the money type keeps two decimal places without float rounding in the output.
  • Several tax rates on one invoice come back as separate lines when you add a tax_lines array to your schema.
  • Invoices in other languages and currencies use the same schema, because field descriptions guide the extraction, not fixed positions.

Which plan fits invoice processing

Custom extraction schemas start on Growth, which is where most invoice projects begin. A page is one page of a PDF or one image file, so a two page invoice uses two pages.

Plan Yearly billing Monthly billing Pages per month Schemas
Starter $24 per month $49 per month 2,000 Built in JSON, Markdown and CSV output
Growth $74 per month $149 per month 7,000 Up to 10 custom schemas, webhooks, batch jobs
Scale $249 per month $499 per month 24,000 Unlimited schemas, priority queue, audit log
Enterprise $749 per month $1,499 per month 72,000 SSO, roles, priority support, EU or US processing region

At the monthly limit parsing pauses with an Upgrade button. Nothing is charged automatically. See PDF extraction API pricing for every limit, or read the document parsing API reference for the full request and response format.

  • Starter 2,000 pages, 1 API key, 1 seat $49 per month $24 per month, $288 billed yearly
  • Growth 7,000 pages, 5 API keys, 3 seats $149 per month $74 per month, $888 billed yearly
  • Scale 24,000 pages, 20 API keys, 10 seats $499 per month $249 per month, $2,988 billed yearly
  • Enterprise 72,000 pages, unlimited API keys with per key limits, 25 seats $1,499 per month $749 per month, $8,988 billed yearly

FAQ

Do I need a template for each supplier

No. You define one schema with field names, types and descriptions. PdfParse reads each layout and fills the same fields, so a new supplier does not require any setup.

How do I know when a value needs a human check

Each field returns a confidence score and the source page. Pick a threshold that suits your approval process and send anything below it to review with the page already identified.

Does it read scanned and photographed invoices

Yes. OCR runs automatically on pages without a text layer, and you can force it with ocr set to "always". The output format is the same for digital and scanned invoices.

Can I export invoices to a spreadsheet

Yes. Every parse returns the line item table as CSV, and the web app exports one CSV for a whole batch of invoices.

What happens to the invoice files after parsing

Files are kept according to your plan, 7 days on Starter, configurable up to 30 days on Growth, and not stored at all in zero retention mode on Scale and Enterprise. Files are never used to train models.

Parse your next invoice in seconds

Create an account, add a key and send your first invoice with the Python or Node SDK in a few minutes.