How to Extract Data from PDF Invoices Without Templates (2026)
How to Extract Data from PDF Invoices Without Templates (2026)
PDF invoices are the single most common document type in business finance — and one of the most frustrating to work with programmatically. PDFs weren't designed for data extraction. They were designed for printing.
The result: a vendor sends you a perfectly formatted invoice that looks great on screen, and extracting the vendor name, invoice number, and total requires either a human, a template, or — increasingly — AI.
This guide covers every practical approach to PDF invoice data extraction in 2026: from no-code AI tools for non-technical finance teams to Python libraries for developers who want full control.
Why PDF Extraction Is Hard
Understanding the challenge helps you choose the right tool.
PDF is a presentation format, not a data format. A PDF invoice doesn't store "vendor name = Nordic Supplies AB" as structured data. It stores a series of instructions: "draw this text in this font at these coordinates." The visual result looks like an invoice. The underlying data is a collection of drawing commands.
There are two fundamentally different types of PDF:
Searchable PDFs (digital PDFs) Generated by software — accounting systems, invoicing tools, ERPs. The text is embedded as actual characters, selectable and copyable. A Python library like PyPDF2 can extract the raw text directly from the file without OCR.
Image-based PDFs (scanned documents) Generated by scanning a physical document. The text appears visually but is actually a photograph. No text layer exists — you have to use OCR to convert the image back to text before you can extract data from it.
Modern extraction tools handle both. The approach differs under the hood.
Method 1: AI-Powered No-Code Extraction (Recommended for Finance Teams)
Best for: Accounting teams, finance managers, small businesses who need accurate data without developer involvement.
AI document extraction tools read PDF invoices and return structured data — vendor name, invoice number, date, line items, totals — without any template or configuration.
How It Works with ExtractBee
- Upload or forward your PDF invoice (drag-and-drop or email forwarding)
- Extraction runs automatically — ExtractBee's AI reads the document, identifies fields, and extracts structured data. We run Google's Gemini 2.5 Flash as the primary model with Claude Sonnet 4.6 as an automatic fallback, so a transient outage on one provider never blocks an extraction
- Review — low-confidence fields are flagged for human review
- Export — download as JSON, CSV, XML, or XLSX, or push directly to Xero, QuickBooks, or Google Sheets
What gets extracted from a typical invoice:
{
"vendor_name": "Nordic Supplies AB",
"vendor_address": "Vasagatan 12, Stockholm, Sweden",
"vendor_vat": "SE556789012301",
"invoice_number": "INV-2024-0892",
"invoice_date": "2024-11-15",
"due_date": "2024-12-15",
"purchase_order": "PO-2024-5521",
"currency": "SEK",
"line_items": [
{
"description": "Software Development Services",
"quantity": 40,
"unit": "hrs",
"unit_price": 1200.00,
"line_total": 48000.00
}
],
"subtotal": 80800.00,
"vat_rate": 25,
"vat_amount": 20200.00,
"total": 101000.00,
"iban": "SE45 5000 0000 0583 9825 7466",
"bic": "SWEDSESS",
"payment_terms": "Net 30"
}
Advantages:
- No setup per vendor
- Handles invoices from vendors you've never processed before
- No developer required
- Works on scanned PDFs too (with OCR pre-processing)
Limitations:
- Requires internet connection (cloud-based)
- Per-page pricing
- Suited for standard business invoices — highly specialised documents may need configuration
Try free — 20 pages/month, no card required →
Method 2: Python Libraries (Developer Approach)
Best for: Developers who need full control over extraction logic and want to build it into their own application.
Step 1: Extract Raw Text from the PDF
For searchable PDFs, use a text extraction library:
# PyPDF2 — simple text extraction
import PyPDF2
def extract_text_from_pdf(pdf_path):
with open(pdf_path, 'rb') as file:
reader = PyPDF2.PdfReader(file)
text = ""
for page in reader.pages:
text += page.extract_text() + "\n"
return text
raw_text = extract_text_from_pdf("invoice.pdf")
For better table extraction, use pdfplumber:
# pdfplumber — better for tables and layout
import pdfplumber
def extract_with_layout(pdf_path):
with pdfplumber.open(pdf_path) as pdf:
full_text = ""
tables = []
for page in pdf.pages:
full_text += page.extract_text() + "\n"
page_tables = page.extract_tables()
if page_tables:
tables.extend(page_tables)
return full_text, tables
text, tables = extract_with_layout("invoice.pdf")
For image-based (scanned) PDFs, you need OCR first:
# pdf2image + pytesseract for scanned PDFs
from pdf2image import convert_from_path
import pytesseract
def extract_text_from_scanned_pdf(pdf_path):
images = convert_from_path(pdf_path, dpi=300)
text = ""
for image in images:
text += pytesseract.image_to_string(image, lang='eng') + "\n"
return text
Step 2: Parse the Extracted Text
Once you have raw text, you need to find the relevant fields. The naive approach uses regex:
import re
def parse_invoice_fields(text):
patterns = {
'invoice_number': r'Invoice\s*(?:No|Number|#)[:\s]+([A-Z0-9\-]+)',
'invoice_date': r'(?:Invoice\s*Date|Date)[:\s]+(\d{1,2}[\s\-\/]\w+[\s\-\/]\d{4})',
'total': r'(?:Total|Amount Due)[:\s]+(?:[A-Z]{3}\s*)?([\d,]+\.?\d*)',
}
results = {}
for field, pattern in patterns.items():
match = re.search(pattern, text, re.IGNORECASE)
if match:
results[field] = match.group(1).strip()
return results
The problem with regex: it works on your test invoices and breaks on the next vendor's slightly different format. Maintaining regex patterns across hundreds of vendors is exactly the template maintenance problem that AI extraction solves.
Step 3: Use an LLM for Structured Extraction (Better)
A more robust approach uses the extracted text as input to an LLM:
import anthropic
import json
client = anthropic.Anthropic()
def extract_invoice_data_with_ai(raw_text: str) -> dict:
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1000,
system="""You are an invoice data extraction assistant.
Extract structured data from invoice text and return minified JSON only.
No explanation, no markdown, just raw JSON.""",
messages=[{
"role": "user",
"content": f"""Extract all fields from this invoice:
{raw_text}
Return JSON with these fields (use null for missing fields):
vendor_name, vendor_vat, invoice_number, invoice_date, due_date,
currency, subtotal, vat_amount, total, line_items, iban, payment_terms"""
}]
)
return json.loads(response.content[0].text)
# Full pipeline
raw_text = extract_text_from_pdf("invoice.pdf") # or scanned version
invoice_data = extract_invoice_data_with_ai(raw_text)
print(invoice_data)
This is essentially what ExtractBee does internally — but with additional layers: per-tenant encryption, position resolution (matching fields back to their location on the page), confidence scoring, Human Review routing, and integration delivery.
Method 3: ExtractBee REST API (Developer + No-Code Hybrid)
Best for: Developers who want accurate AI extraction without building the pipeline themselves, or teams integrating extraction into their own application.
ExtractBee exposes a public REST API (available on Starter plan and above):
// Step 1: Get a presigned upload URL
const uploadResponse = await fetch('https://extractbee.com/api/documents/upload-url', {
method: 'POST',
headers: {
'Authorization': 'Bearer sk_your_api_key',
'Content-Type': 'application/json'
},
body: JSON.stringify({
fileName: 'invoice-2024-0892.pdf',
fileType: 'application/pdf',
fileSize: 245000
})
});
const { documentId, uploadUrl } = await uploadResponse.json();
// Step 2: Upload directly to R2 (never touches ExtractBee servers)
await fetch(uploadUrl, {
method: 'PUT',
body: pdfFileBuffer,
headers: { 'Content-Type': 'application/pdf' }
});
// Step 3: Confirm upload and trigger extraction
await fetch(`https://extractbee.com/api/documents/${documentId}/confirm-upload`, {
method: 'POST',
headers: { 'Authorization': 'Bearer sk_your_api_key' }
});
await fetch(`https://extractbee.com/api/documents/${documentId}/extract`, {
method: 'POST',
headers: { 'Authorization': 'Bearer sk_your_api_key' }
});
// Step 4: Poll for result (or use webhook for async notification)
const result = await fetch(`https://extractbee.com/api/documents/${documentId}/extraction`, {
headers: { 'Authorization': 'Bearer sk_your_api_key' }
});
const { fields } = await result.json();
console.log(fields); // Structured invoice data
API rate limits by plan:
- Starter: 60 requests/minute
- Business: 180 requests/minute
- Pro: 300 requests/minute
Full API reference: extractbee.com/api/reference
Method 4: AWS Textract AnalyzeExpense API
Best for: Teams already in the AWS ecosystem who need high-volume extraction at low per-page cost.
import boto3
import json
textract = boto3.client('textract', region_name='eu-west-1')
def extract_invoice_textract(pdf_path):
with open(pdf_path, 'rb') as f:
document_bytes = f.read()
response = textract.analyze_expense(
Document={'Bytes': document_bytes}
)
result = {}
for doc in response['ExpenseDocuments']:
for field in doc.get('SummaryFields', []):
field_type = field.get('Type', {}).get('Text', '')
field_value = field.get('ValueDetection', {}).get('Text', '')
if field_type and field_value:
result[field_type] = field_value
return result
Cost: roughly $0.01/page for AnalyzeExpense at low volume (check current AWS Textract pricing for your region and volume tier; note the AWS free tier does not cover AnalyzeExpense for invoices and receipts).
Choosing the Right Method
| Your situation | Best method |
|---|---|
| Finance/accounting team, no developer | ExtractBee UI (drag-and-drop), or email forwarding on Business plans and above |
| Need to integrate extraction into your app | ExtractBee API or AWS Textract |
| Building a custom pipeline, full control | Python (pdfplumber + an LLM API) |
| High volume, AWS infrastructure | AWS Textract |
| Occasional extraction, maximum flexibility | ExtractBee UI + API |
Common PDF Extraction Problems and Fixes
Problem: Extracted text is garbled or has wrong character encoding Cause: The PDF uses a non-standard or embedded font. Fix: use pdfplumber instead of PyPDF2 (handles encoding better), or use OCR as fallback.
Problem: Table data comes out as a single block of text
Cause: PDF tables don't store tabular structure — they're positioned text. Fix: use pdfplumber's extract_tables() method, or use an AI model that understands table semantics.
Problem: Multi-column layout is extracted in wrong reading order Cause: PDF text extraction reads by position, not by visual column. Fix: use pdfplumber with bounding boxes, or pass to an AI model which handles layout intelligently.
Problem: Scanned PDF returns empty text Cause: Image-based PDF with no text layer. Fix: add OCR pre-processing (pdf2image + Tesseract, or use a service that handles this automatically).
Problem: Invoice number contains OCR errors (0 vs O, 1 vs l) Cause: Poor scan quality or unusual font. Fix: improve scan DPI to 300 minimum, or use the Human Review workflow to catch and correct uncertain fields before they enter your system.
Comparing Extraction Quality: What to Test
Before committing to any PDF extraction approach, test with your actual documents. Here's a practical test protocol:
Test set (minimum 10 documents):
- 3 invoices from your most common vendors (familiar formats)
- 3 invoices from vendors you process rarely (unfamiliar formats)
- 2 scanned invoices (photograph or flatbed scan)
- 1 multi-page invoice with many line items
- 1 foreign-language invoice if applicable
What to check:
- Vendor name: exact match or close enough for your accounting system?
- Invoice number: correct format, no OCR character errors (0 vs O, 1 vs l)?
- Dates: correct format and correct dates — check both invoice date and due date?
- Line items: all rows extracted, correct quantities and amounts?
- Total: does extracted total match the visual total on the document?
- VAT: is tax amount correctly separated from subtotal?
For most teams, this test takes 30–60 minutes and gives a clear picture of whether an extraction tool handles your specific document mix reliably. If most of your documents are scans rather than digital PDFs, it's worth understanding why AI-based extraction outperforms traditional OCR on those files.
Comparison: PDF Extraction Approaches
| Approach | Setup Time | Technical Skill | Accuracy | Cost |
|---|---|---|---|---|
| ExtractBee (no-code) | 5 minutes | None | High | €35+/mo |
| ExtractBee API | 1–2 hours | Low | High | €35+/mo |
| Python + LLM API | 1–2 days | Developer | High | API costs |
| Python + regex | 2–5 days | Developer | Medium (breaks) | Low |
| AWS Textract | 1–3 days | Developer | High | ~$0.01/pg |
For finance teams without developer resources, the no-code path — the ExtractBee dashboard, or email ingestion on Business plans and above — delivers the best results for the least effort. If you want to take invoice handling off your team's plate entirely, see our guide to automating invoice processing end to end. For developers who want to build extraction into their own application, the ExtractBee API or a direct LLM API integration are both solid choices.
Test With Your Own PDFs
Try ExtractBee free — 20 pages/month, no card required →
Frequently Asked Questions
Can I extract data from password-protected PDFs? ExtractBee does not process password-protected PDFs — the file must be openable without a password. Remove PDF protection before uploading (most PDF tools include this feature).
What file formats does ExtractBee support beyond PDF? PDF, PNG, JPEG, TIFF, XLSX, and DOCX. For spreadsheet files (XLSX) and Word documents (DOCX), our AI model reads the content directly without OCR.
Can I extract data from PDF forms (fillable fields)? Yes. ExtractBee reads both filled-in form fields and free-text content. The AI understands form structure and extracts field values correctly.
What's the maximum PDF size? 50 MB per file. Most invoice PDFs are well under 5 MB.
Does the number of pages affect extraction cost? Yes — each page consumes one page from your monthly allowance. A 3-page invoice consumes 3 pages.
Can I batch-process multiple PDFs at once?
Yes, on the Pro plan and above. Batch upload accepts up to 50 files per request via the API (POST /api/documents/upload-urls).
Last updated: June 2026. ExtractBee is operated by MB Dokigo, Vilnius, Lithuania.