Claude API Text Summarization (Python)

Working Python code to summarize text, documents, and URLs with the Claude API in 2026. Covers bullet-point summaries, extractive key points, long-document chunking, and structured JSON output.

💥 50p impulse-buy: Power Prompts PDF (first 10 buyers) 30 battle-tested Claude Code prompts · 8-page PDF · paste into CLAUDE.md and never re-type a prompt again · 50p impulse-buy, no commitment

Claude produces high-quality summaries out of the box — no fine-tuning required. The key is a precise system prompt that specifies length, format, and perspective. Below are working patterns for the most common summarization use cases.

Minimal summarization

import anthropic

client = anthropic.Anthropic()

def summarize(text: str, max_sentences: int = 3) -> str:
    response = client.messages.create(
        model="claude-haiku-4-5-20251001",  # cheapest model, great for summaries
        max_tokens=512,
        system=f"Summarize the following text in {max_sentences} sentences. Be concise and capture the main point.",
        messages=[{"role": "user", "content": text}]
    )
    return response.content[0].text

article = """
Anthropic released Claude 3.5 Sonnet in June 2024, followed by Claude 3.5 Haiku in November.
The Claude 4 family launched in early 2026 with Sonnet 4.6 and Opus 4.7 offering 200K context windows.
Anthropic's models consistently score near the top of LMSYS Chatbot Arena leaderboard benchmarks.
"""

print(summarize(article))

Bullet-point key points

def bullet_summary(text: str, n_points: int = 5) -> list[str]:
    response = client.messages.create(
        model="claude-haiku-4-5-20251001",
        max_tokens=512,
        system=f"Extract exactly {n_points} key points from the text. Return them as a JSON array of strings. No other text.",
        messages=[{"role": "user", "content": text}]
    )
    import json
    return json.loads(response.content[0].text)

points = bullet_summary(article)
for p in points:
    print(f"• {p}")

Structured JSON summary

import json

def structured_summary(text: str) -> dict:
    system = """Return a JSON object with these exact keys:
- summary: 2-3 sentence overview
- key_points: list of 5 concise strings
- sentiment: one of "positive", "neutral", "negative"
- topics: list of up to 5 topic tags
No markdown, no explanation — only the raw JSON object."""

    response = client.messages.create(
        model="claude-sonnet-4-6",
        max_tokens=1024,
        system=system,
        messages=[{"role": "user", "content": text}]
    )
    return json.loads(response.content[0].text)

result = structured_summary(article)
print(result["summary"])
print(result["key_points"])
print(result["sentiment"])

Long-document map-reduce summarization

def chunk_text(text: str, words_per_chunk: int = 3000) -> list[str]:
    words = text.split()
    return [
        " ".join(words[i:i + words_per_chunk])
        for i in range(0, len(words), words_per_chunk)
    ]

def summarize_long_document(text: str) -> str:
    chunks = chunk_text(text)
    if len(chunks) == 1:
        return summarize(text)

    # Map: summarize each chunk
    chunk_summaries = [summarize(chunk, max_sentences=5) for chunk in chunks]

    # Reduce: synthesize chunk summaries into a final summary
    combined = "

".join(f"[Section {i+1}]
{s}" for i, s in enumerate(chunk_summaries))
    response = client.messages.create(
        model="claude-sonnet-4-6",
        max_tokens=1024,
        system="You have been given summaries of individual sections of a long document. Write a cohesive 3-5 sentence summary of the entire document.",
        messages=[{"role": "user", "content": combined}]
    )
    return response.content[0].text

Webpage summarization (with BeautifulSoup)

# pip install requests beautifulsoup4 anthropic
import requests
from bs4 import BeautifulSoup

def summarize_url(url: str) -> str:
    html = requests.get(url, timeout=10).text
    soup = BeautifulSoup(html, "html.parser")
    # Extract main text, skip nav/footer
    for tag in soup(["script", "style", "nav", "footer", "header"]):
        tag.decompose()
    text = " ".join(soup.get_text(separator=" ").split())[:15000]  # 15K char safety cap
    return summarize(text)

print(summarize_url("https://en.wikipedia.org/wiki/Anthropic"))

Batch summarization (50% cost, async)

def batch_summarize(texts: list[str]) -> list[str]:
    """Summarize many documents at 50% cost via the Batch API."""
    requests_list = [
        {
            "custom_id": f"summary_{i}",
            "params": {
                "model": "claude-haiku-4-5-20251001",
                "max_tokens": 256,
                "system": "Summarize in 2 sentences.",
                "messages": [{"role": "user", "content": t}]
            }
        }
        for i, t in enumerate(texts)
    ]
    batch = client.beta.messages.batches.create(requests=requests_list)
    print(f"Batch ID: {batch.id} — poll until processing_status == 'ended'")
    return batch.id  # poll batch.id later, or use the Batch API webhook

Model comparison for summarization

ModelCost per 1K tokens (in/out)ContextBest for
claude-haiku-4-5-20251001$0.00025 / $0.00125200KHigh-volume bulk summarization
claude-sonnet-4-6$0.003 / $0.015200KNuanced documents, structured output
claude-opus-4-7$0.015 / $0.075200KComplex research papers, board reports

Use the Claude API Cost Calculator to estimate the cost of your summarization pipeline before scaling. For document Q&A (not just summarization), see the RAG with Claude guide. For PDF-specific summarization, see Claude PDF Analysis.

Frequently asked questions

What is the best Claude model for summarization?
For most summarization tasks, `claude-haiku-4-5-20251001` gives the best cost/quality trade-off — it is 5-10× cheaper than Sonnet and produces excellent summaries for documents under 50K tokens. Use `claude-sonnet-4-6` for nuanced long documents where quality is critical.
How long of a document can Claude summarize?
Claude Sonnet 4.6 and Opus 4.7 support 200K token context windows — roughly 150,000 words or a full novel. For longer documents, use a map-reduce chunking approach: summarize each chunk independently, then ask Claude to synthesize the chunk summaries.
How do I get a structured summary (bullet points, JSON)?
Specify the output format in your system prompt: 'Return a JSON object with keys: summary (2-3 sentences), key_points (list of 5 strings), sentiment (positive|neutral|negative).' Claude follows structured output instructions reliably, especially with `claude-sonnet-4-6`.
Can Claude summarize a URL or webpage?
Claude cannot fetch URLs directly — you must extract the text first. Use `requests` + `BeautifulSoup` to scrape the page text, then pass it to Claude. For PDFs, use `pypdf` or the Claude Files API.
How do I summarize many documents in bulk?
Use the Batch API (`client.beta.messages.batches.create`) for bulk summarization. It processes up to 10,000 requests asynchronously at 50% cost reduction compared to real-time API calls. Ideal for nightly document pipelines.

Free tools

Cost Calculator → API Cookbook → Diff Summarizer → Skills Browser →

More examples

Claude API Python QuickstartClaude API Node.js / TypeScript QuickstartClaude API Streaming in PythonClaude API Streaming in Node.js / TypeScriptClaude API Tool Use in PythonClaude API Tool Use in Node.js / TypeScript