Pdf Invoice Table Extraction
Pricing
from $30.00 / 1,000 result returneds
Pdf Invoice Table Extraction
Automation workflows need to convert varied native-text or scanned invoices into consistent accounting-ready line items while detecting uncertain fields and arithmetic mismatches before downstream import.
Pricing
from $30.00 / 1,000 result returneds
Rating
0.0
(0)
Developer
Jordan Nabbe
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
20 hours ago
Last modified
Categories
Share
PDF Invoice Table Extraction turns invoices into clean, accounting-ready JSON and CSV for automation builders, accounts-payable teams and agencies who connect invoice intake to ERP, accounting or workflow systems. It reads real native-text PDF files (base64 or HTTPS URL) plus text, HTML, CSV and JSON invoices, normalizes header fields and line items, recomputes the totals and tells you exactly which invoices need a human look before import.
What it does
- Parses PDF bytes with a real PDF parser, page by page, and keeps the source page of every line item.
- Also accepts inline text, HTML tables, CSV line-item tables, JSON invoice records, and base64-encoded versions of these.
- Extracts vendor, tax id, invoice number, invoice and due date, currency, PO number, subtotal, discount, tax, shipping, grand total and line items (description, SKU, quantity, unit price, discount, tax, line total).
- Normalizes dates to ISO
YYYY-MM-DDand amounts to plain numbers. European and US notation are both understood. - Never guesses ambiguous values.
1.234vs1,234and03/04/2025are rejected withAMBIGUOUS_NUMBERorAMBIGUOUS_DATEunless the document settles them (for example13/04/2025or1.234,56) or you setlocaleHint. - Reconciles line totals, subtotal and grand total within a configurable tolerance. Stated values are never overwritten; stated and calculated values are both returned with the difference.
- Reports evidence lines with page numbers and explicit exceptions (
TOTAL_MISMATCH,SUBTOTAL_MISMATCH,LINE_TOTAL_MISMATCH,MISSING_FIELD,INVALID_VALUE, ...). No confidence scores are invented; only measured checks are reported. - Supports vendor column aliases and a
targetSchemathat renames canonical fields in an extramappedInvoicecopy. - Writes one dataset row per extracted invoice, an
OUTPUTrecord with the summary, all rows, per-source failures and an outcome block, and anOUTPUT.csvline-item file. - One bad source never fails the batch; it is reported in
OUTPUTwith an error code. If nothing usable was produced, the run fails after writingOUTPUT.
How to use it
Paste sources into the input and run. Example:
{"sources": [{"mode": "inline","name": "acme-invoice-1001.txt","format": "text","content": "ACME Supplies\nInvoice: INV-1001\nInvoice Date: 2025-01-15\nCurrency: USD\n\nDescription,SKU,Qty,Unit Price,Line Total\nBlue widgets,BW-10,2,10.00,20.00\n\nSubtotal: 20.00\nTax: 2.00\nTotal: 22.00"},{ "mode": "url", "name": "vendor-b.pdf", "url": "https://files.example.com/invoices/b.pdf", "format": "pdf" }],"currencyHint": "USD","localeHint": "en-US","reconciliationTolerance": 0.02}
For a PDF you already hold, use {"mode":"inline","name":"a.pdf","format":"base64_document","mediaType":"application/pdf","content":"<base64>"}.
Tables in text and PDFs are detected from a header row whose columns match known names (Description, SKU, Qty, Unit Price, Line Total and aliases), separated by commas, tabs, pipes or two or more spaces. Header fields are read from Label: value lines.
Output
| Field | Meaning |
|---|---|
| inputName, source | Your source name and a query-free source reference |
| status | succeeded when invoice number, grand total and line items were extracted; partial when an invoice was produced but one of those is missing |
| reviewStatus | clean, or needs_review when any warning was raised (for example a total mismatch) |
| vendorName, invoiceNumber, currency, grandTotal, lineItemCount | Flat columns for spreadsheets |
| invoice | Canonical invoice with lineItems |
| reconciliation | Calculated vs stated subtotal and grand total, difference, withinTolerance |
| sourceReferences | Evidence line and page per field |
| exceptions | code, field, severity, message |
Abridged row:
{ "inputName": "acme-invoice-1001.txt", "recordType": "invoice", "status": "succeeded", "reviewStatus": "clean", "invoiceNumber": "INV-1001", "grandTotal": 38.5,"reconciliation": { "calculatedGrandTotal": 38.5, "statedGrandTotal": 38.5, "difference": 0, "withinTolerance": true },"reviewRequired": false }
The OUTPUT record adds outcome with status (SUCCEEDED, PARTIAL, FAILED or LIMIT_REACHED), itemsReceived, itemsSucceeded, itemsFailed, billableCount, limitReached and undelivered. Sources that could not be read (for example INVALID_BASE64, URL_BLOCKED, OCR_REQUIRED) appear only in OUTPUT.rows with status: failed, never in the dataset.
Pricing
Pay per event. The main charge is per invoice; everything else listed below is free.
| Event | Price (USD) | Charged when |
|---|---|---|
Actor start (apify-actor-start) | $0.005 | The run starts. |
Invoice processed (apify-default-dataset-item) | $0.03 | An extracted invoice row (status succeeded or partial) is written to the default dataset. Sources that could not be read are never written to the dataset. |
Not charged:
- failed source rows (OUTPUT only)
- OUTPUT summary
- OUTPUT.csv line-item file
Examples (default 512 MB memory, one start event):
- 10 invoices processed: $0.005 start + 1 × $0.005 + 10 × $0.03 = $0.31
- 8 invoices, 2 sources failed: $0.005 start + 1 × $0.005 + 8 × $0.03 = $0.25
Spending limit: when you set a maximum cost per run, the Actor stops before it would exceed it, keeps every invoice it already delivered and reports limitReached in the OUTPUT record. It never delivers results beyond the limit.
The Store's Pricing tab shows the prices in force. If this section and the Pricing tab ever differ, the Pricing tab applies.
Use cases
- Normalize invoice headers and line items before ERP or accounting import.
- Catch subtotal, tax, shipping and grand-total mismatches automatically.
- Queue invoices with
needs_reviewfor human review. - Map different vendors' column names onto one schema.
- Convert PDF, HTML, CSV or JSON invoices to JSON and CSV.
Limits
- At most 50 sources per run, 1000 rows and 1000 line items per invoice; 10 MiB per inline source, 25 MiB per download; up to 500 PDF pages (
maxPagesPerDocumentdefaults to 100). - PDFs must contain a text layer. Scanned or image-only PDFs are reported with
OCR_REQUIRED; there is no OCR. Encrypted or damaged PDFs givePDF_TEXT_UNSUPPORTED. - Extraction is rule-based. Unusual layouts, or tables separated by single spaces, may be missed; those invoices surface as exceptions rather than silent wrong values.
minimumConfidenceis accepted for compatibility but has no effect, because no confidence scores are produced.- URL mode: HTTPS only, public hosts only (private, loopback and link-local addresses and embedded credentials are rejected, redirects are re-validated, at most 3), 30-second timeout.
- Spreadsheet (.xlsx) input is not supported; export the sheet to CSV first.
- If your spending limit is reached, remaining invoices are not delivered and
OUTPUT.outcomereports them asundeliveredwithlimitReached: true. - Invoice content is never written to the log. Datasets and key-value stores follow your Apify retention settings.
FAQ
Does it work offline? Yes, for all inline sources, including base64 PDFs.
Does it read scanned invoices? No. It reports OCR_REQUIRED for that source.
Are totals silently corrected? Never. Stated values are kept, the difference is reported and the row is marked needs_review.
What if the number format is ambiguous? The value is left empty and an ambiguity exception is added, unless localeHint settles it.
What happens with invalid input? The run fails before processing with INPUT_VALIDATION_ERROR.
Is my invoice data shared or used for training? No. Extraction is rule-based and runs inside your Actor run. In URL mode only the exact HTTPS URL you supply (and its validated redirects) is downloaded.