How to Extract Data from Invoices with Claude PDF
To extract data from invoices with Claude PDF, send your invoice file to the Claude API using a document content block, then prompt Claude to return the extracted fields — vendor name, invoice number, line items, totals — as structured JSON. Claude processes each page as a hybrid of visual and textual content, which means it handles scanned invoices, multi-column layouts, and embedded tables that a plain-text strip approach would miss entirely.
What Makes Claude's PDF Support Different from Plain Text Extraction?
Most invoice processing pipelines start by extracting raw text from a PDF, then parsing that text. The problem: PDF text extraction scrambles column order in tables, loses spatial relationships between labels and values, and fails entirely on scanned documents with no text layer.
Claude's approach is different. As the Claude API PDF documentation explains, Claude treats each PDF page as a hybrid of visual and textual content — processing the page layout as an image while also reading the underlying text layer. This gives it spatial awareness that lets it correctly associate a line-item description with its corresponding price, even in a complex invoice table.
A practical consequence: an accounts-payable system can process batches of scanned invoices, extracting vendor name, invoice number, line items, and totals as structured JSON for direct database insertion — including from invoices where OCR alone would struggle with handwritten annotations or mixed-format pages.
How Do You Set Up Invoice Extraction with the Claude API?
You have three ways to send a PDF to Claude: base64-encoded inline in the request, as a publicly accessible URL, or by referencing a file ID from the Anthropic Files API. For a production accounts-payable pipeline processing many invoices, the Files API is the recommended approach because you upload each file once and reuse it across multiple queries without re-sending the full payload.
Here is the complete flow for a one-off extraction using base64 — the simplest starting point:
import anthropic, base64, json
with open('invoice.pdf', 'rb') as f:
pdf_data = base64.standard_b64encode(f.read()).decode('utf-8')
client = anthropic.Anthropic()
response = client.messages.create(
model='claude-sonnet-4-5-20250929',
max_tokens=1024,
messages=[{
'role': 'user',
'content': [
{
'type': 'document',
'source': {
'type': 'base64',
'media_type': 'application/pdf',
'data': pdf_data
}
},
{
'type': 'text',
'text': 'Extract the following fields and return ONLY valid JSON, no explanation: vendor_name, invoice_number, invoice_date, line_items (array of {description, quantity, unit_price, total}), subtotal, tax, grand_total.'
}
]
}]
)
try:
extracted = json.loads(response.content[0].text)
print(extracted)
except json.JSONDecodeError:
print('Parsing failed — retry with stricter prompt')
print(response.content[0].text)
The prompt instruction "Return ONLY valid JSON, no explanation" is important. Claude will generally comply, but wrapping the parse in a try/except block and validating the result against a schema (for example, with Pydantic) is the right production habit.
How Do You Process Many Invoices Efficiently with the Files API?
When your pipeline processes dozens or hundreds of invoices, re-uploading the full base64 payload for every request wastes bandwidth and adds latency. The Files API solves this: upload each invoice once, get back a file_id, and reference that ID in as many subsequent queries as you need.
import anthropic, json
client = anthropic.Anthropic()
# Upload the invoice once
with open('invoice_batch_001.pdf', 'rb') as f:
uploaded = client.beta.files.upload(
file=('invoice_batch_001.pdf', f, 'application/pdf'),
betas=['files-api-2025-04-14']
)
file_id = uploaded.id
# Extract structured data
resp = client.beta.messages.create(
model='claude-sonnet-4-5-20250929',
max_tokens=1024,
betas=['files-api-2025-04-14'],
messages=[{
'role': 'user',
'content': [
{
'type': 'document',
'source': {'type': 'file', 'file_id': file_id}
},
{
'type': 'text',
'text': 'Extract vendor_name, invoice_number, invoice_date, line_items, and grand_total. Return ONLY valid JSON.'
}
]
}]
)
data = json.loads(resp.content[0].text)
print(data)
# Clean up when done
client.beta.files.delete(file_id)
Note that all Files API requests require the beta header. Omitting it returns an error, so pass it in the betas parameter of the SDK or as a raw HTTP header on every relevant call.
When Should You Use PDF Support vs. Other Approaches?
| Scenario | Best Approach | Why |
|---|---|---|
| Scanned invoices, complex tables, mixed layouts | Claude PDF (document block) | Layout-aware visual + text processing handles what plain extraction misses |
| Already have clean extracted text | Plain text prompt | Uses fewer tokens and is faster when layout interpretation isn't needed |
| One-off or prototype extraction | Base64 inline upload | No extra setup, no beta headers, fastest to get started |
| Batch pipeline, same invoice queried multiple times | Files API | Upload once, reuse by file_id — eliminates redundant network transfers |
| Document archive too large for a single request | RAG pipeline | Use when documents exceed Claude's context window or you need semantic search across a large corpus |
| High-volume overnight batch processing | Batch API + PDF support | Cost-efficient for large volumes where real-time response isn't required |
What Are the Most Common Pitfalls When Extracting Invoice Data?
Claude doesn't always return valid JSON
Even with a clear prompt, Claude may occasionally include an explanation before or after the JSON object. Always wrap your json.loads() call in a try/except block. For critical extraction workflows, validate the parsed object against a schema and retry on failure. Including "Return ONLY valid JSON, no explanation" in your prompt significantly reduces this problem.
Password-protected invoices are rejected
Claude only supports standard PDFs. Encrypted or password-protected files will return an error. Remove password protection before uploading — this is a common surprise when pulling invoices from accounting systems that apply security by default.
Dense invoices with many line items consume more tokens than expected
Each PDF page consumes roughly 1,500–3,000 input tokens depending on content density. A multi-page invoice with dense tables sits at the higher end of that range. For large batches, use the token-counting API before sending to avoid unexpected context overruns, and split unusually dense files into logical sections if needed.
Large files sent as base64 hit payload limits
Base64 encoding adds approximately 33% overhead to the file size. For invoices larger than a few megabytes — or when processing many invoices in a loop — switch to the Files API to keep individual request payloads manageable and avoid re-sending the full file on every call.
Invalid filenames cause silent upload errors
Filenames must be between 1 and 255 characters and must not contain certain special characters. Sanitize filenames pulled from email attachments or accounting systems before passing them to the upload call.
Is Claude PDF Extraction Worth It for Accounts-Payable Workflows?
For any workflow that currently relies on brittle regex parsing of extracted text, or that struggles with scanned invoices from vendors who don't send digital PDFs, Claude's layout-aware PDF processing is a meaningful upgrade. The ability to read embedded charts and tables visually — not just the text layer — means it can correctly extract totals from invoices where the table structure would confuse a text-only approach.
The Files API pattern (upload once, query multiple times) makes it practical to run several validation passes on the same invoice: one prompt to extract line items, another to verify the math, another to flag missing required fields — all without re-uploading the document. This is the recommended production pattern for document-heavy applications.
For very large document archives or semantic search across thousands of invoices, a RAG pipeline remains the right tool. But for the common case — processing individual invoices or moderate batches and extracting structured fields — Claude's PDF support via the API is a direct, low-infrastructure path to accurate data extraction.
Frequently asked questions
Can Claude extract data from scanned invoices, not just digital PDFs?
Yes. Claude processes each PDF page as a hybrid of visual and textual content, so it can handle scanned pages that have no underlying text layer. This includes invoices with handwritten annotations or mixed-format pages that OCR alone struggles with.
What fields can Claude extract from an invoice?
Claude can extract any field visible on the invoice, including vendor name, invoice number, invoice date, individual line items (description, quantity, unit price, total), subtotal, tax, and grand total. You specify the fields you need in your prompt and ask for the output as structured JSON.
Do I need to pre-process or convert the PDF before sending it to Claude?
No pre-processing is required for standard PDFs. You send the PDF directly — as base64, a URL, or via the Files API — and Claude handles layout interpretation internally. Password-protected PDFs must have encryption removed before upload.
What is the Files API and why is it recommended for invoice processing?
The Files API lets you upload a PDF once and reference it by a file ID across multiple API calls, without re-sending the full file each time. This is more efficient for batch workflows where you might run several extraction or validation queries against the same invoice.
How do I make sure Claude returns valid JSON for database insertion?
Include 'Return ONLY valid JSON, no explanation' in your prompt, wrap your JSON parsing in a try/except block, and validate the parsed result against a schema (such as a Pydantic model). Retry on parse failure for critical extraction workflows.
What happens if my invoice PDF is very large or has many pages?
Each page consumes a meaningful number of input tokens, so dense multi-page invoices can approach context limits. Use the token-counting API to check before sending large documents, and consider splitting unusually dense files into sections. For large files, the Files API is also preferable to base64 to avoid payload size issues.
PDF support via API is one of 85 features in Claude Master — the independent, continuously updated manual with worked examples, the pitfalls, and the workflows that put Claude to work.
Get Claude Master — founding price →Independent product. Not affiliated with or endorsed by Anthropic. "Claude" is a trademark of Anthropic, used here only to describe the subject of this guide.