← Blog

Build a Customer Support Chatbot with Claude

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

Building a customer support chatbot with Claude means combining three things: a system prompt that constrains Claude to your product and tone, tool calling so it can look up order status or account data instead of guessing, and a way to escalate to a human when it's out of its depth. Claude handles the language part well out of the box — the engineering work is in grounding it in your data and controlling what it's allowed to say.

This guide walks through the architecture, the API calls you need, and the decisions that actually matter: what goes in the system prompt, when to use tools versus retrieval, how to manage conversation history, and how to keep the whole thing reliable in production.

Architecture overview

A production support chatbot usually has four layers:

  1. Frontend widget — chat UI embedded on your site or app
  2. Backend endpoint — receives messages, calls Claude, returns responses
  3. Tools/functions — order lookup, ticket creation, refund status, knowledge base search
  4. Escalation path — hands off to a human agent or ticketing system when Claude can't resolve the issue

Claude never talks to your database directly. Your backend owns the tool implementations; Claude decides when to call them based on the conversation.

Step 1: Write a constrained system prompt

The system prompt is where most of the "personality" and guardrails live. Be specific about scope, tone, and what Claude should refuse to do.

You are the support assistant for Acme Cloud Storage.

Rules:
- Only answer questions about Acme Cloud Storage products, billing, and account issues.
- If asked about anything unrelated, politely redirect to support topics.
- Never invent order numbers, refund amounts, or account details — always use tools to look them up.
- If you cannot resolve the issue after two attempts, offer to escalate to a human agent.
- Keep responses under 150 words unless the user asks for detail.

Vague system prompts ("be helpful and friendly") lead to Claude improvising answers about things it has no data for. Explicit rules about tool usage and escalation reduce hallucinated account details significantly.

Step 2: Give Claude tools instead of static context

Stuffing every FAQ and order record into the prompt doesn't scale. Instead, define tools Claude can call — order status, subscription details, refund eligibility — and let it request what it needs.

{
  "name": "get_order_status",
  "description": "Look up the status of a customer order by order ID",
  "input_schema": {
    "type": "object",
    "properties": {
      "order_id": { "type": "string" }
    },
    "required": ["order_id"]
  }
}

When Claude decides it needs this data, it returns a tool_use block instead of a text answer. Your backend executes the actual lookup, returns the result, and Claude incorporates it into the next reply. This is the same tool-calling pattern used across the Claude API — see /docs/tools for the full spec.

A minimal request/response loop against SubToAPI, which proxies your existing Claude access through a standard API key:

const response = 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",
    system: SYSTEM_PROMPT,
    messages: conversationHistory,
    tools: [orderStatusTool, refundLookupTool],
    max_tokens: 500
  })
});

const data = await response.json();

if (data.stop_reason === "tool_use") {
  const toolCall = data.content.find(c => c.type === "tool_use");
  const result = await runTool(toolCall.name, toolCall.input);
  // send result back as a tool_result message and call again
}

The request shape matches the standard Claude Messages API, so if you've built against Anthropic directly before, nothing here changes conceptually — see /docs/messages for the full reference.

Step 3: Stream responses for a better UX

Support chat feels sluggish if users stare at a blank bubble while Claude generates a full response. Streaming tokens as they're produced makes the bot feel responsive even on longer answers.

const stream = 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",
    system: SYSTEM_PROMPT,
    messages: conversationHistory,
    stream: true,
    max_tokens: 500
  })
});

Pipe the server-sent events straight to your frontend widget. Details on the event format are in /docs/streaming.

Step 4: Manage conversation history and context windows

Send the full conversation history with each request — Claude has no memory between calls. For long support sessions, trim old turns or summarize them once you approach a token budget, and always keep the system prompt and the last few exchanges intact so context isn't lost mid-conversation.

A simple sliding window works for most cases: keep the last 10–15 messages, summarize anything older into a single system-appended note.

Step 5: Build the escalation path

No chatbot resolves everything. Define clear triggers for handoff:

When triggered, create a ticket in your existing helpdesk system and hand the full conversation transcript to the agent — don't make the customer repeat themselves.

Step 6: Manage keys and usage across environments

Once the chatbot is live, you need separate credentials for staging, production, and any internal testing, plus visibility into how much usage each is generating. SubToAPI issues per-application sub_live_... keys from your existing Claude access, so you can run a staging bot and a production bot on separate keys with independent usage metadata, without provisioning separate Anthropic accounts. Team plans (/pricing) add seats if more than one person needs dashboard access to logs and usage. Start with a free trial at /signup, or check /docs/quickstart for a working example in under ten minutes.

Common mistakes to avoid

questions

Do I need to fine-tune Claude for a support chatbot? No. A well-written system prompt combined with tools for live data lookup covers the vast majority of support use cases without any fine-tuning.

How do I stop Claude from making up order details? Explicitly instruct it in the system prompt to never guess account-specific data and only report information returned by tool calls — this eliminates most hallucinated details.

Can the chatbot hand off to a human mid-conversation? Yes — define escalation triggers in your backend logic (explicit request, repeated failure, tool errors) and pass the full transcript to your ticketing system when triggered.

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 →