← Blog

Claude API PDF Parsing and Summarization Guide

2026-10-20 · 5 min read · SubToAPI Team

Claude can read PDFs natively through the Messages API — no separate OCR step, no third-party parsing library required. You send the file as a base64-encoded document block alongside your prompt, and Claude processes both the text and the visual layout (tables, headers, charts) in one pass. This makes it a solid default choice for extracting structured data from contracts, invoices, research papers, or long reports and turning them into clean summaries.

The short answer to "how do I parse and summarize a PDF with the Claude API" is: encode the file, attach it as a document content block in your message, and ask for the output format you want in the prompt (bullet summary, JSON, table extraction, etc.). Claude handles multi-page documents up to roughly 100 pages and 32MB per file, and it reads scanned or image-heavy PDFs just as well as text-native ones because the model processes pages as images internally.

How Claude's native PDF support works

Unlike older pipelines that required pdftotext, pdfplumber, or an OCR service before anything reached the model, Claude's document understanding happens inside the same request as your prompt. You get:

This matters for summarization specifically because a lot of document quality is lost when you strip layout before summarizing. A financial report where numbers live in a table loses meaning if you flatten it to plain text first.

Sending a PDF to the API

A minimal request looks like this:

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-opus-4-20250514",
    "max_tokens": 1024,
    "messages": [
      {
        "role": "user",
        "content": [
          {
            "type": "document",
            "source": {
              "type": "base64",
              "media_type": "application/pdf",
              "data": "BASE64_ENCODED_PDF_HERE"
            }
          },
          {
            "type": "text",
            "text": "Summarize this report in five bullet points, including any key figures from tables."
          }
        ]
      }
    ]
  }'

If your app already talks to Claude through SubToAPI, the request shape is identical — you're hitting your own sub_live_... key instead of a raw Anthropic key, so you don't have to change how your document-handling code works:

curl https://api.subtoapi.app/v1/messages \
  -H "Authorization: Bearer $SUBTOAPI_KEY" \
  -H "content-type: application/json" \
  -d '{
    "model": "claude-opus-4-20250514",
    "max_tokens": 1024,
    "messages": [
      {
        "role": "user",
        "content": [
          { "type": "document", "source": { "type": "base64", "media_type": "application/pdf", "data": "BASE64_ENCODED_PDF_HERE" } },
          { "type": "text", "text": "Summarize this report in five bullet points, including any key figures from tables." }
        ]
      }
    ]
  }'

Full request and response field reference is in /docs/messages, and a working end-to-end setup is in /docs/quickstart.

Getting better summaries, not just shorter text

Dumping a PDF into the model and asking for "a summary" works, but you get noticeably better output by being specific:

Streaming long summaries

For large reports, summaries can run long enough that you want tokens as they're generated rather than waiting for the full response. Claude supports server-sent event streaming for this, and it works the same way whether the input includes a PDF or not:

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-opus-4-20250514",
    max_tokens: 2048,
    stream: true,
    messages: [
      {
        role: "user",
        content: [
          { type: "document", source: { type: "base64", media_type: "application/pdf", data: pdfBase64 } },
          { type: "text", text: "Produce a structured summary with headings: Overview, Key Numbers, Risks, Next Steps." },
        ],
      },
    ],
  }),
});

Details on handling the event stream, including partial-token deltas and reconnect behavior, are covered in /docs/streaming.

Why teams route PDF workloads through SubToAPI

Document-heavy summarization tends to be a shared workload — a support team parsing contracts, a finance team summarizing reports, a product team extracting feedback from PDFs. SubToAPI turns your existing Claude access into application-scoped API keys so each use case gets its own sub_live_... key, usage is tracked per key in one dashboard, and team members share seats instead of juggling personal credentials. Plans start at €9/month solo, with Team (€19/seat) and Scale (€49/seat) tiers for shared usage, and every plan includes a free trial — see /pricing or go straight to /signup.

questions

Does Claude need a separate OCR step to read scanned PDFs? No. Claude processes PDF pages as images internally, so scanned documents and image-heavy files are read the same way as text-native PDFs, without a separate OCR pipeline.

What's the maximum PDF size Claude can handle in one request? Roughly 100 pages and 32MB per file. Larger documents should be split into chunks, summarized individually, and then combined with a second summarization pass.

Can I get a structured JSON summary instead of plain text? Yes. Ask for a specific JSON schema in your prompt, or use tool calling to have Claude return extracted fields directly — see /docs/tools for the request format.

Turn your Claude access into an HTTPS API

SubToAPI gives you application API keys, streaming, tool use and usage insights on top of your existing Claude access — set up in minutes.

Start free  Read the quickstart →