← Blog

How to Build an AI Summarizer With Claude

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

Building an AI summarizer with Claude comes down to three decisions: how you chunk input text, how you structure the prompt, and how you handle output length and streaming. This guide walks through all three with working code, so you end up with a summarizer that handles anything from a short email to a 50-page PDF without falling apart.

The short answer: send your text to Claude with a prompt that specifies summary length, tone, and format, split long documents into chunks and summarize each before doing a final "summary of summaries" pass, and stream the response if you're showing it in a UI. Everything below expands on that.

What you actually need to build

A summarizer isn't just "call the API with a prompt." For anything beyond toy demos you need:

If you're prototyping, you can skip the infrastructure and just get an API key — see /docs/quickstart for a five-minute setup.

Step 1: Design the prompt first

Before writing code, nail the prompt. A vague instruction like "summarize this" produces inconsistent length and tone across requests. Be explicit:

You are a summarization engine. Summarize the following text in 3-5
sentences, written in plain neutral language. Do not add opinions or
information not present in the source. If the text contains no
substantive content, say so.

Text:
"""
{document_text}
"""

Pin down:

If you need structured output (e.g., {summary, key_points, action_items}), say so explicitly and show an example shape in the prompt — Claude follows a demonstrated schema far more reliably than a loose description.

Step 2: Handle documents longer than one context window

Most real documents — reports, transcripts, support threads — exceed what you want to send in a single request, both for cost and quality reasons. The standard pattern is map-reduce summarization:

  1. Split the document into chunks (by paragraph or heading, not arbitrary character counts — breaking mid-sentence hurts quality)
  2. Summarize each chunk independently
  3. Concatenate the chunk summaries
  4. Run a final pass that summarizes the summaries into one coherent output
async function summarizeChunk(chunkText) {
  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: 300,
      messages: [{
        role: "user",
        content: `Summarize this excerpt in 2-3 sentences, factual only:\n\n${chunkText}`
      }]
    })
  });
  const data = await res.json();
  return data.content[0].text;
}

async function summarizeDocument(chunks) {
  const partials = await Promise.all(chunks.map(summarizeChunk));
  const combined = partials.join("\n\n");

  const final = 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: `These are summaries of sequential sections of one document. Merge them into a single coherent summary, removing redundancy:\n\n${combined}`
      }]
    })
  });
  const finalData = await final.json();
  return finalData.content[0].text;
}

This pattern scales to documents of almost any length because chunk summarization runs in parallel, and only the final merge step is sequential. Full request and response fields are documented at /docs/messages.

Step 3: Stream output for long or interactive use cases

If users are watching the summary generate in real time — a browser extension, a dashboard widget — stream the response instead of waiting for the full completion:

curl -N https://api.subtoapi.app/v1/messages \
  -H "Authorization: Bearer $SUBTOAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-4",
    "max_tokens": 400,
    "stream": true,
    "messages": [{"role": "user", "content": "Summarize this article in bullet points: ..."}]
  }'

Streaming matters most for the final merge step, where output can run a few hundred tokens — users perceive it as faster even though total latency is similar. Details on event formats are in /docs/streaming.

Step 4: Add structure when summaries feed other systems

If the summary output is consumed by another program rather than a human — e.g., stored in a database or passed to a downstream workflow — ask Claude to return JSON directly and parse it, rather than regex-scraping free text. Keep the schema small: summary, key_points as an array, and optionally sentiment or category fields. For summarizers that also need to extract specific fields (dates, names, action items) alongside the narrative summary, tool use can enforce a strict schema — see /docs/tools if your pipeline needs that level of reliability.

Choosing a model and managing cost

Longer or more nuanced documents benefit from larger models; short transcripts and emails summarize well with smaller, cheaper ones. A practical rule: use a faster model for the per-chunk pass (volume is high, each summary is short) and a stronger model for the final merge (one call, needs coherence). This cuts cost significantly on long documents without hurting final quality, since the last pass is doing the real synthesis work.

Getting this running quickly

If you already have Claude access through a Pro or Team plan and want to expose it as a proper HTTPS API — with application keys, request logging, and usage metadata per key — SubToAPI turns that access into an API you can call from the code above without managing separate billing. Plans start at Solo for solo projects, Team for shared seats, and Scale for higher-volume usage; see /pricing for the breakdown, or start with a free trial at /signup.

Questions

Does Claude have a built-in summarization mode? No. There's no dedicated "summarize" endpoint — you get summarization behavior by prompting a general chat/completion model with clear length, format, and scope instructions, as shown above.

How do I summarize a document longer than Claude's context window? Use map-reduce: split the document into chunks, summarize each chunk independently, then run one more pass that merges the chunk summaries into a single final summary.

Should I stream the summarizer's output? Stream it if a human is watching the result appear live (UI widgets, chat-style tools). For batch jobs or pipelines where the summary is stored or passed to another system, a single non-streamed response is simpler to parse.

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 →