← Blog

How to Build a Chatbot with Claude API

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

Building a chatbot with Claude API comes down to four things: sending messages in the right format, maintaining conversation history, streaming responses so the UI feels responsive, and handling errors gracefully. Anthropic's Claude models are strong at following instructions and holding context over long conversations, which makes them a good fit for support bots, internal assistants, and product-embedded chat features.

This guide walks through the actual implementation — from your first API call to a working multi-turn chatbot — and covers the production concerns that tutorials usually skip, like rate limits, system prompts, and cost control.

What You Need Before Starting

Claude's API is stateless: every request must include the full conversation history. There's no server-side session object you can just append to. Your application is responsible for storing and replaying messages.

Step 1: Send a Single Message

The core request is a POST to a messages endpoint with a model name, a list of messages, and a max token limit.

curl https://api.anthropic.com/v1/messages \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "content-type: application/json" \
  -d '{
    "model": "claude-sonnet-4-20250514",
    "max_tokens": 1024,
    "messages": [
      {"role": "user", "content": "What is a REST API in one sentence?"}
    ]
  }'

The response contains a content array with the model's reply text and a usage object with input/output token counts. That usage data matters once you're running a chatbot at scale — it's your primary cost signal.

Step 2: Add Conversation Memory

A chatbot needs to remember what was said earlier in the session. Since the API is stateless, you build an array of {role, content} objects and append to it after every turn: user, then assistant, then user again.

const history = [];

function addUserMessage(text) {
  history.push({ role: "user", content: text });
}

function addAssistantMessage(text) {
  history.push({ role: "assistant", content: text });
}

async function sendTurn(userText) {
  addUserMessage(userText);

  const res = await fetch("https://api.anthropic.com/v1/messages", {
    method: "POST",
    headers: {
      "x-api-key": process.env.ANTHROPIC_API_KEY,
      "anthropic-version": "2023-06-01",
      "content-type": "application/json",
    },
    body: JSON.stringify({
      model: "claude-sonnet-4-20250514",
      max_tokens: 1024,
      messages: history,
    }),
  });

  const data = await res.json();
  const reply = data.content[0].text;
  addAssistantMessage(reply);
  return reply;
}

For a real product, store history per user or per session ID in a database rather than a global array. Trim or summarize old messages once the conversation gets long — context windows are large, but every token you send costs money and latency.

Step 3: Use a System Prompt to Define Behavior

The system parameter sets the chatbot's persona, scope, and constraints. This is where you define tone, what the bot should refuse to answer, and formatting rules.

{
  "model": "claude-sonnet-4-20250514",
  "max_tokens": 1024,
  "system": "You are a support assistant for a SaaS billing dashboard. Answer only questions about billing, invoices, and subscriptions. If asked about anything else, say you can only help with billing.",
  "messages": [{"role": "user", "content": "How do I update my card?"}]
}

A tight system prompt is usually more effective than stuffing instructions into every user message, and it keeps token usage predictable.

Step 4: Stream Responses for a Natural Chat Feel

Chatbots feel sluggish if users wait for the full response to generate before seeing anything. Streaming sends the reply token by token so you can render it as it arrives, the same way ChatGPT and Claude.ai do it. Set "stream": true in the request and read the response as server-sent events, printing each text delta as it comes in.

Step 5: Add Tool Use for Real Actions

If your chatbot needs to do things — look up an order, check a calendar, query a database — use tool calling. You define a tool schema, Claude decides when to call it, and your code executes the actual function and returns the result in the next turn. This is what turns a chatbot from "answers questions" into "takes actions," and it's worth building early rather than bolting it on later.

Where SubToAPI Fits In

If you're already paying for Claude through a Claude subscription rather than a pay-as-you-go developer API key, you don't automatically get programmatic access for a chatbot. SubToAPI turns that subscription into a standard HTTPS API: you get an application key (sub_live_...), and every example above works against https://api.subtoapi.app/v1/messages with Authorization: Bearer $SUBTOAPI_KEY instead of the x-api-key header.

curl https://api.subtoapi.app/v1/messages \
  -H "Authorization: Bearer $SUBTOAPI_KEY" \
  -H "content-type: application/json" \
  -d '{
    "model": "claude-sonnet-4-20250514",
    "max_tokens": 1024,
    "messages": [{"role": "user", "content": "Hello"}]
  }'

Streaming, tool use, and usage metadata per key are all supported — see the quickstart, messages docs, streaming guide, and tool use docs. This is particularly useful if multiple people on your team need separate API keys with their own usage tracking, without each person needing their own developer API billing setup. Plans start at Solo €9/month, with Team and Scale tiers for shared seats — check pricing or start with a free trial at signup.

Production Checklist

Before shipping your chatbot:

Questions

Do I need to manage conversation history myself? Yes. Claude's API has no built-in session storage — your application must store the message array and send the full history with each request.

What's the difference between the system prompt and a user message? The system prompt sets persistent behavior and constraints for the whole conversation. User messages are the actual turn-by-turn input the chatbot responds to.

Can I build a chatbot without a dedicated Claude developer API key? Yes, if you already have Claude access through a subscription, a service like SubToAPI exposes it as a standard HTTPS API with its own key, so you can build the same chatbot without separate developer billing.

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 →