Build a Customer Service Bot with Claude API
If you want to build a customer service bot with the Claude API, you need four things working together: a system prompt that encodes your support policies, a way to feed Claude your product knowledge, tool use so the bot can actually look up orders or create tickets, and a conversation loop that keeps context across turns. None of this requires a dedicated chatbot framework — Claude's Messages API handles all of it directly.
This guide walks through a working architecture you can ship, from the first API call to handling escalations and streaming responses in a UI. By the end you'll have a bot that answers FAQs, pulls real account data, and knows when to hand off to a human.
What a customer service bot actually needs
Most "AI chatbot" tutorials stop at a single prompt-and-response loop. A production support bot needs more:
- Grounded answers — the bot shouldn't hallucinate refund policies or shipping times
- Tool access — it needs to call your order lookup, ticketing, or CRM APIs
- Conversation memory — multi-turn context within a session
- Escalation logic — a clear path to a human agent when confidence is low
- Usage visibility — cost and volume tracking once it's live
Claude handles the first three natively through system prompts, tool use, and the Messages API's conversation format. The last one is where most teams end up building (or buying) extra infrastructure.
Step 1: Design the system prompt
The system prompt is where your support policies live. Keep it specific and bounded — vague instructions like "be helpful" produce inconsistent behavior.
You are a customer support assistant for Acme Cloud Storage.
Rules:
- Only answer questions about billing, storage limits, and account access.
- Never promise refunds yourself — use the create_refund_request tool.
- If the user is angry, frustrated, or asks for a human twice, call escalate_to_human.
- Keep answers under 4 sentences unless the user asks for detail.
- If you don't know something, say so and escalate rather than guessing.
This is more effective than a generic "you are a helpful assistant" prompt because it gives Claude explicit boundaries and tool-calling triggers rather than leaving escalation to chance.
Step 2: Set up tool use for real actions
A bot that can only chat isn't a customer service bot — it's a FAQ page with extra latency. Tool use lets Claude call your backend functions when it needs real data.
{
"model": "claude-sonnet-4-5",
"max_tokens": 1024,
"system": "You are a customer support assistant...",
"tools": [
{
"name": "get_order_status",
"description": "Look up the current status of an order by ID",
"input_schema": {
"type": "object",
"properties": {
"order_id": { "type": "string" }
},
"required": ["order_id"]
}
},
{
"name": "escalate_to_human",
"description": "Transfer the conversation to a human support agent",
"input_schema": {
"type": "object",
"properties": {
"reason": { "type": "string" }
},
"required": ["reason"]
}
}
],
"messages": [
{ "role": "user", "content": "Where's my order #48213?" }
]
}
When Claude decides it needs order data, it returns a tool_use block instead of a final answer. Your application runs the actual lookup, then sends the result back as a tool_result message. Claude uses that result to compose the final reply. This loop is what separates a real support bot from a scripted FAQ tree — see /docs/tools for the full request/response shapes.
Step 3: Maintain conversation state
The Messages API is stateless per request — you resend the full message history each time. For a support bot, structure it like this:
const messages = [
{ role: "user", content: "I was charged twice this month" },
{ role: "assistant", content: "Let me check your billing history. Can you confirm your account email?" },
{ role: "user", content: "it's jane@example.com" }
];
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",
max_tokens: 1024,
system: "You are a customer support assistant...",
messages
})
});
Store this array per session (Redis, a database row, or in-memory for a demo) and append new turns as the conversation continues. Trim or summarize history once you approach context limits — most support conversations don't need more than the last 20-30 turns.
Step 4: Stream responses for a natural feel
Support chat feels sluggish if users wait for a full response. Streaming token-by-token output makes the bot feel responsive even on longer answers. Set "stream": true in the request and consume server-sent events on the client. Full event format and reconnection handling are covered in /docs/streaming.
Step 5: Handle escalation gracefully
Escalation isn't a failure state — it's a feature. Design it so the bot:
- Recognizes escalation triggers (explicit request, repeated frustration, tool errors)
- Calls the
escalate_to_humantool with a reason - Your backend creates a ticket and returns a tool result confirming the handoff
- Claude tells the user a human will follow up, with a timeframe if you have one
This keeps the bot honest about its limits instead of stalling or guessing when it's out of depth.
Where SubToAPI fits
If you already have a Claude subscription and want to expose it as an API for this bot without separately provisioning Anthropic API billing, SubToAPI turns your existing Claude access into an HTTPS API with its own sub_live_ keys. You get the same Messages endpoint, streaming, and tool use shown above, plus per-key usage metadata so you can see exactly how many requests and tokens your support bot is consuming. Team and Scale plans add seat-based access if multiple people on your team are building or monitoring the bot. Check /pricing for plan details or start with the /docs/quickstart to get a key running in minutes.
Keep iterating after launch
Launching the bot isn't the end — log transcripts (with user consent), review where escalations happen most, and tighten the system prompt based on real conversations. Customer service bots improve mostly through prompt refinement and better tool coverage, not model changes.
Questions
Do I need a chatbot framework to build this, or just the API? Just the API. The Messages endpoint, tool use, and streaming cover everything a support bot needs — frameworks add abstraction you often have to work around for custom escalation logic.
How do I stop the bot from making up answers about policies? Constrain it with a specific system prompt, feed real data through tools instead of hoping the model "knows" it, and instruct it explicitly to say "I don't know" and escalate rather than guess.
Can the bot handle multiple languages? Yes — Claude handles multilingual input without extra configuration. Just make sure your system prompt and tool descriptions don't assume English-only responses if you expect non-English users.