← Blog

Claude API Pagination for Large Responses

2026-09-27 · 5 min read · SubToAPI Team

If you've searched for "Claude API pagination for large responses" expecting something like a page parameter or a next_cursor field, here's the short answer: the Claude Messages API doesn't paginate responses. There's no cursor-based pagination for a single completion the way there is for list endpoints (like listing files or messages in a conversation history). What you're actually running into is one of two separate problems: either a response that gets cut off because it hits the output token limit, or a task that produces more data than a single request can reasonably handle in one shot.

Both problems have solid solutions, but they're not "pagination" in the REST sense — they're about managing token limits, streaming, and multi-turn continuation. This article covers the three patterns that actually work.

Why there's no pagination parameter

Claude generates a response token by token in a single continuous generation pass. There's no server-side concept of "page 2 of this answer" because the model doesn't pre-compute the full answer and then slice it — it produces it incrementally, bounded by the max_tokens value you set on the request. Once that limit is hit, the response stops, with a stop_reason of max_tokens telling you it was truncated.

So the practical question isn't "how do I paginate through the response" — it's "how do I get a complete, correctly ordered result when the answer is longer than one response can hold." That's a continuation problem, not a pagination problem.

Check stop_reason before assuming you have everything

The first fix is often just visibility. Every response includes a stop_reason field:

{
  "id": "msg_01...",
  "role": "assistant",
  "content": [{ "type": "text", "text": "..." }],
  "stop_reason": "max_tokens",
  "usage": { "input_tokens": 512, "output_tokens": 4096 }
}

If stop_reason is max_tokens, the response was cut off mid-generation — this is the signal that you need a continuation step, not that something broke. If it's end_turn, the model finished naturally and there's nothing missing. A lot of "why is my Claude response incomplete" issues are just this field being ignored.

Strategy 1: raise max_tokens and stream the output

For most large-but-finite outputs (a long report, a big JSON payload, a full file rewrite), the fix is simpler than pagination: increase max_tokens to the model's ceiling and stream the response instead of waiting for the full completion.

curl https://api.subtoapi.app/v1/messages \
  -H "Authorization: Bearer $SUBTOAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-4-5",
    "max_tokens": 8192,
    "stream": true,
    "messages": [{"role": "user", "content": "Write a detailed 4000-word technical guide on..."}]
  }'

Streaming doesn't increase the token limit, but it lets your application start rendering or writing output as soon as tokens arrive, rather than blocking on the entire generation. This matters a lot for UX with long responses — see the streaming docs for the event format and how to parse content_block_delta events as they arrive.

Strategy 2: continuation prompts

If your output genuinely exceeds the max output tokens even at the ceiling, you need a continuation loop. The pattern:

  1. Send the initial request with a high max_tokens.
  2. If stop_reason is max_tokens, take the partial output and send it back as assistant content in a follow-up message, asking Claude to continue exactly where it left off.
  3. Concatenate the pieces client-side and repeat until stop_reason is end_turn.
async function generateLong(prompt) {
  let fullText = "";
  let messages = [{ role: "user", content: prompt }];

  while (true) {
    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-5",
        max_tokens: 8192,
        messages
      })
    });
    const data = await res.json();
    const chunk = data.content[0].text;
    fullText += chunk;

    if (data.stop_reason !== "max_tokens") break;

    messages = [
      { role: "user", content: prompt },
      { role: "assistant", content: chunk },
      { role: "user", content: "Continue exactly where you left off. Do not repeat any text." }
    ];
  }

  return fullText;
}

This is effectively how you "paginate" a Claude response — each loop iteration is a page, and you're the one stitching them together. It works well for long-form text but requires care with structured formats (JSON, code) since a truncation mid-token or mid-bracket needs careful re-joining logic on your side.

Strategy 3: chunk the task, not the response

For genuinely large workloads — summarizing 200 documents, processing a big CSV, transforming a large codebase — don't ask for one giant response at all. Split the input into logical units (per-document, per-file, per-record) and make one request per unit, each with its own bounded output. This avoids truncation entirely and makes retries cheap, since a failed chunk doesn't cost you the whole job. It also parallelizes naturally, since each chunk is an independent API call you can fire concurrently.

This is the approach most production pipelines end up converging on, because it sidesteps the continuation-loop complexity and gives you natural checkpoints for retries and rate limiting.

Where SubToAPI fits

If you're running Claude requests like these through a team or product, SubToAPI gives you a standard HTTPS API (sub_live_... keys) over your existing Claude access, with the same /v1/messages request and response shape shown above, plus streaming, tool use, and usage metadata per key. That's useful when you're chunking large jobs across multiple app keys or team members and need to see token usage per request without building your own logging layer. Check the quickstart and messages docs for the full request reference, or see pricing for plan details.

Questions

Does the Claude API support pagination for a single response? No. There's no cursor or page parameter for message completions. Large outputs are managed through max_tokens, streaming, and continuation requests, not pagination.

How do I know if my Claude response was cut off? Check the stop_reason field in the response. A value of max_tokens means the output was truncated and needs a continuation request; end_turn means it finished naturally.

What's the best way to handle a task that produces more output than one request can return? Split the input into smaller units and make separate requests per unit rather than relying on a single giant completion — it's more reliable than continuation loops and easier to retry on failure.

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 →