Invoice Extractor with Per-Field Agreement Check
Under maintenancePricing
$120.00 / 1,000 invoice page extracteds
Invoice Extractor with Per-Field Agreement Check
Under maintenanceTurns invoice PDFs and scans into JSON. Every field is marked as agreed by two independent readers or flagged for a person, and you pay only for pages it actually extracted and cross-checked.
Pricing
$120.00 / 1,000 invoice page extracteds
Rating
0.0
(0)
Developer
D. Michael Piscitelli
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
3 days ago
Last modified
Categories
Share
Turns invoice PDFs and scans into JSON. Every field is marked as agreed by two independent readers or flagged for a person, and you pay only for pages it actually extracted and cross-checked.
What it does
I built this for one job: getting invoice data into your system without someone re-checking every number. You give it an invoice as a PDF or an image. Two separate readers go through it. One looks at the page image. The other works from the PDF's text, or from OCR text when the file is a scan. A field is marked agree only when both land on the same value. Anything else is flagged, and the Actor does not guess.
Fields: vendor name, vendor address, vendor tax ID, customer name, invoice number, invoice date, due date, PO number, currency, subtotal, tax, shipping, total, and line items with description, quantity, unit price and amount. Each field carries the page and the text snippet it came from, so a reviewer can check it against the source.
Status of each field
agree: both readers found the same value. Safe to accept automatically.disagree: they found different values. Send it to review.single_source: only one reader produced a value. Send it to review.absent: neither reader found the field on the page.needs_locale: the value is ambiguous, like the date 04/03/2026 with no locale given. PasslocaleHintor send it to review.unparsed: a value was read but could not be turned into a clean date or number. Send it to review.
Each result begins with two counts, verified_fields and needs_review. A workflow can take the first group as is and route only the second to a person.
Input example
{"documents": ["https://example.com/invoices/INV-17744.pdf"],"localeHint": "en-US","maxPages": 10}
documents: public http(s) links, up to 100 per run. Each file must be under 20 MB. PDF, PNG, JPEG, WebP and TIFF work.recordKeysandrecordStore: for private files, keep the invoices as records in a key-value store in your Apify account and list their keys. Choose the store with the picker. Picking it is what gives the Actor read access, and it can read only the stores you pick. LeaverecordStoreempty to use the run's own store.localeHint: a locale tag such asen-US,en-GBorde-DE. It settles ambiguous dates and amounts like 1.234,56. Without it, an ambiguous value comes back asneeds_locale.maxPages: 1 to 10, default 10. Pages past the limit are not read and not billed.
A bad link or a missing store gives an error on that document only. The rest of the run carries on.
Output example (one dataset item per document, trimmed)
{"source": "https://example.com/invoices/INV-17744.pdf","outcome": "ok","pages_total": 1,"pages_processed": 1,"pages_charged": 1,"verified_fields": 21,"needs_review": 0,"absent_fields": 0,"needs_review_fields": [],"notices": [],"extraction": {"data": {"vendor_name": "Harborview Supply Co.","invoice_number": "INV-17744","invoice_date": "2026-08-13","due_date": "2026-08-27","currency": "USD","subtotal": 6378.99,"tax": 526.27,"total": 6905.26,"line_items": ["..."]},"fields": {"/total": { "status": "agree", "basis": "exact", "value": 6905.26, "evidence": { "page": 1, "snippet": "..." } }},"summary": { "agree": 21, "disagree": 0, "single_source": 0, "required_all_agree": true, "attention": [] }},"latency_s": 21.4}
outcome is one of ok, ok_degraded, not_an_invoice, skipped or error. With ok_degraded, one reader was down, so the result is delivered but every value is single-source. A skipped document hit a limit (see notices). For error, error.type gives the reason.
Pricing
$0.12 per page, pay per event (event name page). You are charged only for pages that were extracted and cross-checked, meaning an ok result. You are not charged when a reader is down, when the document is not an invoice, when a document fails, or when it is skipped. If you set a maximum total charge for the run, a document that would go past it is skipped and marked as such.
Limits
- Free Apify plan: at most 3 pages per run. A page that fails to read still counts toward those 3. Paid plans: up to 10 pages per document.
- Up to 100 documents per run.
- Invoices only. Forms and receipts are not supported. They did not pass my accuracy testing, so I left them out. Phone photos of receipts may come back wrong or flagged.
- One-page invoices had a 95th-percentile time of 22.5 seconds in my test. The longest invoice in the set, dense with line items, took about 3.5 minutes.
How I measured accuracy
I tested on 27 invoices from a held-out set, kept apart from the ones I tuned on. That is 38 pages, a mix of born-digital PDFs and scans. Every value that both readers agreed on was correct: 878 out of 878. On born-digital invoices the readers agreed on 89.6% of fields, and on scans 60.7%. The rest came back with another status so a person can look. This is my test set, not a promise for every layout. Keep the review step for anything that is not agree.
Contact
Questions or a layout that misbehaves: hello@herakles.dev. I read it myself.