Claude API PDF Document Analysis Example
What you're trying to do
If you searched for this, you probably want to send a PDF — an invoice, a contract, a research paper, a scanned form — to Claude and get back a summary, extracted fields, or answers to questions about its content. The short answer: yes, the Claude API supports native PDF input through the Messages API, and it doesn't require you to pre-process the file with a separate OCR tool. You send the PDF as a base64-encoded document block alongside your text prompt, and Claude reads both the text and the visual layout (tables, charts, scanned pages) in one pass.
This article shows a working request/response example, how to structure prompts for reliable extraction, and the practical limits you'll hit (file size, page count, token cost) before you build this into production.
How PDF input works in the Claude API
PDF support is exposed as a document content block inside a message, similar to how image blocks work. You pass the file as base64 data with a media_type of application/pdf, and Claude processes each page — both the extracted text and the rendered image of the page — so it can read tables, handwriting, stamps, and layout that plain text extraction would miss.
A minimal request body looks like this:
{
"model": "claude-sonnet-4",
"max_tokens": 1024,
"messages": [
{
"role": "user",
"content": [
{
"type": "document",
"source": {
"type": "base64",
"media_type": "application/pdf",
"data": "<BASE64_PDF_DATA>"
}
},
{
"type": "text",
"text": "Summarize this contract in 5 bullet points and list any dates or deadlines mentioned."
}
]
}
]
}
The order matters: put the document block before the text instruction so Claude has the content in context before it reads what you're asking it to do.
Full curl example
BASE64_PDF=$(base64 -w 0 invoice.pdf)
curl https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"model": "claude-sonnet-4",
"max_tokens": 1024,
"messages": [
{
"role": "user",
"content": [
{
"type": "document",
"source": {
"type": "base64",
"media_type": "application/pdf",
"data": "'"$BASE64_PDF"'"
}
},
{
"type": "text",
"text": "Extract the invoice number, total amount, and due date as JSON."
}
]
}
]
}'
On macOS, drop the -w 0 flag from base64 since it isn't supported — pipe through tr -d '\n' instead.
JavaScript example
import fs from "fs";
const pdfBuffer = fs.readFileSync("./contract.pdf");
const base64Pdf = pdfBuffer.toString("base64");
const response = await fetch("https://api.anthropic.com/v1/messages", {
method: "POST",
headers: {
"x-api-key": process.env.ANTHROPIC_API_KEY,
"anthropic-version": "2023-06-01",
"content-type": "application/json"
},
body: JSON.stringify({
model: "claude-sonnet-4",
max_tokens: 1024,
messages: [
{
role: "user",
content: [
{
type: "document",
source: {
type: "base64",
media_type: "application/pdf",
data: base64Pdf
}
},
{
type: "text",
text: "What are the three main risks mentioned in this document?"
}
]
}
]
})
});
const data = await response.json();
console.log(data.content[0].text);
Getting structured output from documents
For document analysis pipelines — invoices, resumes, forms — you usually want structured data back, not prose. Two approaches work well:
- Ask for JSON directly in the prompt. Be explicit about the schema: field names, types, and what to do if a field is missing (e.g.,
nullinstead of guessing). - Use tool calling. Define a tool with a JSON schema for the fields you need, and Claude will return a structured tool call instead of free text. This is more reliable for downstream parsing than asking for JSON in a text block, since you avoid stripping markdown fences or fixing malformed JSON. See /docs/tools if you're routing this through SubToAPI's tool-use support.
For multi-page contracts or long reports, chunking rarely helps — pass the whole PDF in one request when possible so Claude retains context across sections (a clause on page 12 referencing a definition on page 2, for example).
Limits and practical considerations
- File size and pages: PDFs are limited in size (check current limits before building around them, they change), and very long documents consume a large number of input tokens because each page is processed as both text and image.
- Cost scales with pages, not just text length. A 40-page PDF with mostly whitespace still costs more than a 40-page dense text file of similar token count, because of the per-page image processing.
- Scanned documents work, but quality depends on scan resolution — blurry or skewed scans reduce extraction accuracy just like they would for a human reader.
- Multiple documents per request are supported by including several
documentblocks — useful for comparing two contracts or cross-referencing an invoice against a PO.
Simplifying this with SubToAPI
If you're already paying for Claude access and want to expose this document analysis capability as a stable HTTPS API for your own app or team, SubToAPI turns your Claude subscription into application API keys (sub_live_...) that speak the same Messages format shown above — including document content blocks, streaming, and tool use. You get per-key usage metadata so you can see exactly which integration is burning tokens on large PDFs, without managing raw provider credentials across your team. Start with /docs/quickstart, or check the full request format at /docs/messages. Plans start at €9/month with a free trial at /signup.
questions
Does the Claude API support PDF input natively, or do I need OCR first? Native support — you send the PDF as a base64-encoded document block in the Messages API and Claude reads both text and page layout. No separate OCR step is required for typical use cases.
Can I extract structured JSON from a PDF instead of a text summary? Yes. Either ask for JSON explicitly in your prompt with a defined schema, or use tool calling (see /docs/tools) for more reliable structured output that's easier to parse downstream.
Why does analyzing a PDF cost more tokens than a text file with the same word count? Claude processes each PDF page as an image in addition to extracted text, so cost scales with page count as well as content length — a sparse 40-page PDF can cost more than a dense text document of similar length.