Claude API PDF Document Question Answering Guide
Claude can read PDFs natively and answer questions about their content — you send the document as part of the request, ask a question in the same message, and Claude returns an answer grounded in the text (and even the layout) of the file. This works for contracts, research papers, invoices, financial reports, and scanned documents with readable text, without needing a separate OCR or parsing pipeline in most cases.
This guide covers how PDF question answering works with Claude's API, how to structure requests for single and multi-document scenarios, how to handle large PDFs that exceed context limits, and practical tips for getting accurate, non-hallucinated answers.
How Claude Handles PDFs
Claude's models accept PDF files as a content block alongside text, similar to how images are handled. The model processes both the extracted text and the visual layout of each page, which means it can answer questions about tables, charts, headers, and page structure — not just plain text content.
A typical request looks like this:
curl https://api.subtoapi.app/v1/messages \
-H "Authorization: Bearer $SUBTOAPI_KEY" \
-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-encoded-pdf>"
}
},
{
"type": "text",
"text": "What is the total contract value and the payment terms in this document?"
}
]
}
]
}'
If you're using SubToAPI as your endpoint, this request behaves exactly like a standard Claude Messages call — see /docs/messages for the full request shape. SubToAPI passes the document content block through unchanged, so any PDF support that works directly against Anthropic's models works the same way through your sub_live_ key.
Encoding and Sending the File
In practice, you'll base64-encode the PDF client-side before sending it. A simple Node.js example:
import fs from "fs";
const pdfData = fs.readFileSync("./invoice.pdf").toString("base64");
const response = await fetch("https://api.subtoapi.app/v1/messages", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.SUBTOAPI_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "claude-sonnet-4",
max_tokens: 800,
messages: [
{
role: "user",
content: [
{
type: "document",
source: { type: "base64", media_type: "application/pdf", data: pdfData },
},
{ type: "text", text: "List every line item and its price." },
],
},
],
}),
});
const result = await response.json();
console.log(result.content[0].text);
Check /docs/quickstart if this is your first request — it walks through generating a key and making your first call end to end.
Handling Large or Multi-Page PDFs
PDFs consume tokens based on page count and content density — a 50-page report can use a significant portion of the context window once converted to text and image tokens per page. A few practical strategies:
- Split by section. If you only need answers about a specific chapter or appendix, extract just those pages before sending the request. Smaller inputs are cheaper and reduce the chance of the model losing focus in a long document.
- Summarize first, then query. For very large documents, run a first pass asking Claude to summarize each section, store those summaries, and use them to answer follow-up questions without resending the full PDF every time.
- Use multiple document blocks. You can include more than one PDF in a single message if you need to compare or cross-reference documents — useful for contract redlines or comparing quarterly reports.
"content": [
{ "type": "document", "source": { "type": "base64", "media_type": "application/pdf", "data": "<doc1>" } },
{ "type": "document", "source": { "type": "base64", "media_type": "application/pdf", "data": "<doc2>" } },
{ "type": "text", "text": "What changed between these two versions of the agreement?" }
]
Improving Answer Accuracy
A few things consistently improve the quality of PDF-based answers:
- Ask specific questions. "Summarize this document" produces vague output. "What is the termination clause and notice period?" produces a targeted, checkable answer.
- Request citations. Ask Claude to quote the exact sentence or page it used to answer, which makes it easy to verify and reduces the risk of silently wrong answers.
- Set a lower temperature for factual extraction tasks — you want consistent, literal answers, not creative paraphrasing.
- Validate numbers separately. For financial or legal documents, have Claude extract structured data (amounts, dates, parties) into JSON first, then reason over that structured output rather than free text.
Streaming Long Answers
If you're building a document Q&A interface where answers can be long (e.g., "summarize every clause"), streaming the response improves perceived speed significantly. See /docs/streaming for details on consuming server-sent events from the Messages endpoint — the same pattern applies whether the input is plain text or a PDF document block.
Where SubToAPI Fits
If you're already building on Claude and want this working through a standard API key setup rather than managing Anthropic console access directly, SubToAPI gives you an HTTPS endpoint with sub_live_ application keys, usage metadata per request, and team seats so multiple people on your team can build PDF-based tools without sharing one credential. Plans start at €9/month for solo use, with Team (€19/seat) and Scale (€49/seat) tiers for larger usage — see /pricing for details, or start a free trial at /signup.
Questions
Does Claude support scanned (image-only) PDFs? Yes, as long as the text is legible in the rendered pages — Claude reads the visual layout, not just embedded text layers. Very low-resolution scans or handwriting may reduce accuracy.
Is there a file size or page limit for PDFs? Practical limits come from the context window, not a hard page cap — very long documents consume more tokens and may need to be split or summarized in sections, as described above.
Can I ask follow-up questions about the same PDF without resending it? Within a single conversation, keep the document in the message history and Claude retains context across turns. For separate requests or sessions, you'll need to resend the document block or cache a summary instead.