← Blog

Claude API Prompt Chaining Tutorial

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

What prompt chaining is and why you need it

Prompt chaining means breaking a complex task into a sequence of smaller Claude API calls, where the output of one call becomes the input for the next. Instead of asking Claude to "research, summarize, and write a report" in one giant prompt, you split it into three focused steps: extract facts, summarize them, then draft the report. Each step gets a smaller, clearer context window, which usually produces more accurate and more controllable output.

This matters because single mega-prompts tend to fail silently. Claude will do its best to satisfy a multi-part instruction, but accuracy drops as the task grows, and you lose the ability to inspect or correct intermediate results. Chaining gives you checkpoints: you can validate, cache, or retry each stage independently, log what happened at each step, and swap one stage's model or prompt without touching the rest of the pipeline.

Below is a practical tutorial for building a prompt chain against the Claude API, including code, error handling, and patterns that scale beyond toy examples.

When to chain instead of using one prompt

Chaining is worth the extra complexity when:

If the task is simple and single-shot, don't chain — it just adds latency and cost for no benefit.

Basic chain: extract, then transform

The simplest chain is two calls where step 2 depends on step 1's output. Here's a minimal example using plain HTTPS calls (swap in the Anthropic API or SubToAPI — the request shape is the same style of messages payload):

async function callClaude(messages) {
  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,
    }),
  });
  const data = await res.json();
  return data.content[0].text;
}

async function chain(rawText) {
  // Step 1: extract structured facts
  const facts = await callClaude([
    {
      role: "user",
      content: `Extract all named entities and dates from this text as JSON:\n\n${rawText}`,
    },
  ]);

  // Step 2: use step 1's output as input
  const summary = await callClaude([
    {
      role: "user",
      content: `Using this extracted data, write a two-sentence summary:\n\n${facts}`,
    },
  ]);

  return summary;
}

Each step is a normal call to the messages endpoint — the chaining logic lives entirely in your application code, not in Claude itself. That's the key mental model: Claude has no memory between separate API calls unless you explicitly pass prior output back in.

Keeping state across a longer chain

For chains with three or more steps, pass a running object instead of raw strings so you can log and debug each stage:

async function runPipeline(input) {
  const state = { input };

  state.entities = await callClaude([
    { role: "user", content: `List key entities in: ${state.input}` },
  ]);

  state.draft = await callClaude([
    { role: "user", content: `Write a draft report using these entities: ${state.entities}` },
  ]);

  state.final = await callClaude([
    { role: "user", content: `Edit this draft for clarity and tone: ${state.draft}` },
  ]);

  return state;
}

Returning the full state object, not just the final result, makes debugging much easier — if step 2 produces garbage, you can see exactly what step 1 handed it.

Validating output between steps

Chains break when a step returns something the next step can't parse. Always validate structured output before passing it on:

function parseOrRetry(raw) {
  try {
    return JSON.parse(raw);
  } catch {
    throw new Error("Step output was not valid JSON — add stricter formatting instructions");
  }
}

If you're extracting structured data between steps, it's often more reliable to use tool use for that step instead of asking Claude to format JSON in plain text. A tool call forces a schema, which removes an entire class of parsing failures from your chain.

Streaming inside a chain

Streaming is useful on the final, user-facing step of a chain, where you want tokens to appear as they're generated, but it adds complexity on intermediate steps where you just need the full text to pass forward. A common pattern:

const finalRes = 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,
    stream: true,
    messages: [{ role: "user", content: finalPrompt }],
  }),
});

Handling failures mid-chain

A chain is only as reliable as its weakest step. Build in:

If you're running chains in production, having per-key usage metadata matters here: when a chain fails or gets expensive, you want to know which step and which API key caused it. SubToAPI's dashboard exposes usage per key for exactly this kind of debugging, which is harder to get from raw Anthropic billing alone. See pricing for plan details, or start with a free trial at signup.

A note on cost and latency

Every step in a chain is a full round trip — API latency, token cost, and failure surface all multiply by the number of steps. Before adding a step, ask whether it genuinely improves accuracy or is just splitting work that one well-structured prompt could handle. A three-step chain that's twice as accurate is worth the extra 2x latency; a five-step chain that's marginally better than a two-step one usually isn't.

Questions

Does Claude remember previous steps automatically? No. Each API call is stateless unless you include prior messages or output in the new request. Chaining is entirely managed in your application code.

Should every step use the same model? Not necessarily. Cheaper or faster models can handle simple extraction steps, while a stronger model handles the final synthesis or writing step — this keeps chain cost down without sacrificing final quality.

How many steps is too many for a prompt chain? There's no fixed limit, but beyond 4–5 steps latency and cost compound quickly. If you're past that, consider whether a single well-structured prompt with tool use could replace several steps.

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 →