← Blog

How to Summarize Long Documents with the Claude API

2026-11-06 · 5 min read · SubToAPI Team

Summarizing long documents with the Claude API comes down to two decisions: whether the document fits in a single context window, and if not, how you split it up and recombine the summaries without losing meaning. Claude's models support context windows large enough to fit most reports, transcripts, and contracts in one request, so the first step is always checking whether you actually need chunking at all.

This guide walks through both paths — single-pass summarization for documents that fit, and a map-reduce approach for documents that don't — along with the prompt patterns that produce consistent, useful summaries instead of vague paraphrasing.

Step 1: Check if you need chunking

Claude models handle context windows up to 200K tokens, which is roughly 150,000 words of English text. Before building any chunking logic, estimate your document's token count. A rough rule of thumb: 1 token ≈ 4 characters of English text.

If your document is under that limit (which covers most PDFs, legal contracts, support transcripts, and research papers), skip chunking entirely and send the whole thing in one request. This is simpler, cheaper per request, and avoids the information loss that comes from summarizing in pieces.

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": "Summarize the following document in 5 bullet points, focusing on decisions made and action items. Document:\n\n<full document text here>"
      }
    ]
  }'

For documents that genuinely exceed the context window — think multi-hundred-page filings, full books, or large batches of concatenated transcripts — you need a chunking strategy.

Step 2: Chunk large documents sensibly

Don't split on a fixed character count. Split on natural boundaries: paragraphs, sections, or page breaks. This keeps related sentences together and avoids cutting off mid-thought, which degrades summary quality more than almost anything else.

A practical chunking approach:

  1. Split the document into sections using existing structure (headings, page breaks, or double line breaks).
  2. Group sections into chunks that stay under roughly 60% of the model's context window, leaving room for the prompt and the output.
  3. Keep a small overlap (one or two paragraphs) between consecutive chunks so references that span a boundary aren't lost.
function chunkDocument(text, maxChars = 40000, overlapChars = 1000) {
  const paragraphs = text.split("\n\n");
  const chunks = [];
  let current = "";

  for (const para of paragraphs) {
    if ((current + para).length > maxChars) {
      chunks.push(current);
      current = current.slice(-overlapChars) + para;
    } else {
      current += "\n\n" + para;
    }
  }
  if (current) chunks.push(current);
  return chunks;
}

Step 3: Map — summarize each chunk

Summarize each chunk independently, with a prompt that asks for extraction rather than polished prose. At this stage you want facts, not final phrasing — you'll smooth that out in the reduce step.

async function summarizeChunk(chunk) {
  const res = 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: 500,
      messages: [
        {
          role: "user",
          content: `Extract the key facts, decisions, and figures from this document section. Use concise bullet points, no commentary.\n\n${chunk}`
        }
      ]
    })
  });
  const data = await res.json();
  return data.content[0].text;
}

Run this across all chunks, either sequentially or in parallel depending on your rate limits. Parallel requests are faster but check your plan's concurrency before firing dozens at once.

Step 4: Reduce — combine chunk summaries into one

Concatenate the chunk-level summaries and run a final pass that merges, deduplicates, and orders the result. This second pass is where you apply your actual formatting requirements (executive summary, bullet points, specific length).

async function reduceSummaries(chunkSummaries, instructions) {
  const combined = chunkSummaries.join("\n\n---\n\n");
  const res = 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: 1024,
      messages: [
        {
          role: "user",
          content: `Below are summaries of consecutive sections of one document. Merge them into a single coherent summary, removing duplicate points. ${instructions}\n\n${combined}`
        }
      ]
    })
  });
  const data = await res.json();
  return data.content[0].text;
}

This map-reduce pattern scales to documents of any length — the number of chunks grows, but the logic doesn't change.

Prompt patterns that improve summary quality

Streaming for long outputs

If you're generating detailed, multi-section summaries rather than short bullet lists, the response itself can take a while to generate. Streaming lets you render output as it's produced instead of waiting for the full response, which matters for any UI where users are watching the summary build. See /docs/streaming for details on handling streamed responses.

Where SubToAPI fits in

If you're already on a Claude subscription and want to build a document summarization pipeline without separately provisioning API access, SubToAPI turns that subscription into a standard HTTPS API with application keys, usage metadata per request, and team seats if multiple people on your team need access. You get the same /v1/messages endpoint shown above, with streaming and tool use available when your summarization pipeline needs to call out to extraction tools. Check /pricing for plan details or /docs/quickstart to get a key running in a few minutes.

questions

Does Claude API summarization work on PDFs directly? You need to extract text from the PDF first (most pipelines use a PDF parsing library), then send the extracted text in the message content. Claude processes text, not binary file formats, through the Messages API.

How long can a document be before I need to chunk it? If the document's token count is under roughly 150,000 words of English text, it fits in Claude's 200K token context window and can be summarized in a single request without chunking.

Will map-reduce summaries lose information compared to single-pass summaries? Some loss is inherent to any multi-step summarization, but good chunk boundaries, overlap between chunks, and an extraction-first prompt at the map stage minimize it significantly compared to naive fixed-length splitting.

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 →