How to Build a Text Summarization API With an LLM

A summarization API is one endpoint: take text in, send it to the LLM with a clear summarize prompt, return the summary out. The quality lives in the prompt and the input handling. Here's how to build it.

AI Engineerpythonflaskllm

The shape

POST /summarize takes {"text": "..."}, calls the LLM with a summarization instruction, and returns {"summary": "..."}. The LLM does the work - your job is a clean endpoint and a good prompt.

The endpoint

import requests
from flask import Flask, request, jsonify

app = Flask(__name__)
LLM_URL = "http://llm-service:8080/v1/chat/completions"

@app.post("/summarize")
def summarize():
    text = (request.get_json() or {}).get("text", "").strip()
    if not text:
        return jsonify({"error": "text is required"}), 400

    payload = {
        "model": "the-model",
        "messages": [
            {"role": "system", "content": "You summarize text concisely and accurately. "
                                          "Return only the summary, no preamble."},
            {"role": "user", "content": f"Summarize the following:\n\n{text}"},
        ],
    }
    r = requests.post(LLM_URL, json=payload, timeout=60)
    r.raise_for_status()
    summary = r.json()["choices"][0]["message"]["content"]
    return jsonify({"summary": summary})

What makes it good

Long inputs and consistent quality

Two things separate a toy summarizer from a usable one. Long inputs: any document longer than the model's context window must be chunked - split on paragraph boundaries, summarize each chunk, then summarize the summaries (a map-reduce pass). Track token counts so an oversized request fails fast with a clear error instead of a truncated, misleading summary.

Consistent output: put the rules in the system prompt, not the user text - length ("3 sentences" or "5 bullets"), audience, and tone. Use a low temperature so the same input gives a stable summary, and return structured output so callers don't parse free text. Guard against prompt injection from the document itself by clearly delimiting the content and instructing the model to treat it as data, not instructions. Add a timeout and a graceful error so one slow or oversized request can't hang the endpoint.

Want to try it hands-on? HeyDevJob gives you this exact setup in a live cloud workspace in your browser - edit it, run it, and see it work. Free, nothing to install.

Try it in a workspace →

What you'll practice

FAQ

How do I build a text summarization API with an LLM?

Expose a POST endpoint that takes the text, sends it to the LLM with a system prompt instructing it to summarize concisely and return only the summary, and returns the model's reply. Validate the input and set a timeout.

How do I control the length of an LLM summary?

Put the constraint in the prompt - e.g. 'summarize in 2-3 sentences' or 'in under 50 words' - and expose it as a request parameter so callers can ask for short or detailed summaries.

How do I summarize text longer than the model's context window?

Chunk the text, summarize each chunk, then summarize the combined chunk-summaries (a map-reduce approach), so you never exceed the context limit in a single call.

Keep learning

Restore a Broken LLM API IntegrationAI/ML projectHarden an LLM Pipeline Against API FailuresAI/ML projectParse JSON From an LLM (Strip Markdown Fences)AI/ML projectAI/ML roadmapStep by step to hiredAI/ML interview questionsSTAR answersAll AI/ML projectsProjects hub

Learn it by doing. Open this in a live cloud workspace, make the change yourself, and keep a record of the work you can share.

Open the workspace →