How to Build a Claude-Powered Onboarding Chatbot
Building a Claude-powered onboarding chatbot means connecting the Claude API to a conversational UI that walks new users through your product, answers their setup questions, and hands off to human support only when needed. The core pieces are: a system prompt that encodes your product knowledge and onboarding flow, a way to call Claude over HTTPS with streaming, and a frontend that renders the conversation as it's generated.
This guide covers the full build: designing the onboarding prompt, wiring up the API calls, streaming responses to the UI, giving the bot tools to check account state, and deciding between calling Claude directly or through a gateway like SubToAPI that adds API keys, usage tracking, and team access on top of your existing Claude subscription.
Why Claude for Onboarding
Onboarding chatbots fail when they're scripted decision trees that break the moment a user asks something unexpected. Claude handles the open-ended part well: it can read your docs, understand a user's half-formed question, and respond in context instead of forcing them into a menu. For onboarding specifically, you want a model that:
- Follows a defined flow (collect goal → recommend setup → confirm completion) without going off-script
- Can answer "what does this feature do" questions using your actual documentation
- Knows when to say "I don't know, here's how to reach support" instead of guessing
Claude does all three reliably when the system prompt is written carefully and the conversation history is managed well.
Step 1: Write the Onboarding System Prompt
The system prompt is where most of the engineering work actually happens. Structure it in sections:
You are the onboarding assistant for [Product].
Your job is to get a new user to their first successful
action in the product within this conversation.
Onboarding steps, in order:
1. Ask what the user wants to accomplish.
2. Recommend the relevant feature or setup path.
3. Walk them through it step by step, one step per message.
4. Confirm they completed the step before moving on.
5. When done, summarize what they set up and suggest next steps.
Rules:
- Keep responses under 4 sentences unless giving step-by-step instructions.
- If the user asks something outside onboarding, answer briefly
from the product docs below, then return to the current step.
- If you don't know the answer, say so and suggest contacting
support@yourproduct.com.
- Never ask for passwords, API keys, or payment details.
Product docs:
[paste condensed docs or key feature descriptions]
Keep the docs section tight. Dumping your entire help center into the system prompt wastes tokens and makes Claude slower to respond — summarize the sections relevant to onboarding and link out for the rest.
Step 2: Call the API With Conversation History
Each turn, you send the full conversation (not just the latest message) so Claude keeps context. A basic non-streaming call looks like this:
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",
system: onboardingSystemPrompt,
messages: conversationHistory, // [{role, content}, ...]
max_tokens: 500
})
});
const data = await response.json();
appendToChat(data.content[0].text);
Store conversationHistory server-side per user session, not in the browser — it keeps the system prompt and any sensitive context out of client-accessible storage, and it lets you resume onboarding if the user closes the tab and comes back later.
Step 3: Stream Responses for a Natural Feel
Onboarding conversations feel sluggish if the user stares at a blank bubble while Claude generates a full paragraph. Streaming fixes that:
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",
system: onboardingSystemPrompt,
messages: conversationHistory,
max_tokens: 500,
stream: true
})
});
const reader = res.body.getReader();
const decoder = new TextDecoder();
let text = "";
while (true) {
const { done, value } = await reader.read();
if (done) break;
text += decoder.decode(value);
renderPartial(text);
}
Details on event formats and reconnect handling are in the streaming docs. If you're building the frontend in React specifically, the same pattern applies — pipe chunks into component state as they arrive.
Step 4: Give the Bot Tools to Check Real Account State
A chatbot that says "go to Settings and enable X" when the user already enabled X looks broken. Tool use fixes this — give Claude a function to check the user's actual account state before giving instructions:
{
"name": "get_onboarding_status",
"description": "Returns which onboarding steps the current user has completed",
"input_schema": {
"type": "object",
"properties": {
"user_id": { "type": "string" }
},
"required": ["user_id"]
}
}
When Claude calls this tool, your backend queries your actual database and returns the result, which Claude then uses to tailor its next message — skipping steps already done, or pointing out something that's misconfigured. Setup for tool definitions and the request/response loop is covered in the tools documentation.
Step 5: Add Guardrails and Escalation
Onboarding bots need a clean exit to human support. Track a simple signal — three consecutive "I don't know" responses, or an explicit "talk to a human" request — and route to your support system with the full conversation transcript attached. This saves the support agent from asking the user to repeat everything.
Where SubToAPI Fits
If you already have Claude access through your account, SubToAPI turns it into an application-ready HTTPS API without a separate Anthropic developer contract. You get a sub_live_... API key, streaming and tool use out of the box, and usage metadata per key — useful if your onboarding bot is one of several internal tools drawing from the same Claude access. Team seats let your support and product teams share access without sharing a single key. Start with the quickstart, check the messages endpoint for the request format, and compare plans when you're ready to move past the free trial. Sign up at /signup.
Questions
Does the onboarding bot need to remember past sessions? Only if users can leave and resume onboarding later. Store conversation history server-side keyed to the user ID, and reload it at the start of each session rather than relying on browser storage.
How long should the system prompt be? Long enough to cover the onboarding flow and key product facts, short enough to stay fast. A few hundred words plus a condensed docs summary is typical — link out to full docs rather than pasting them all in.
Can the bot trigger actions in my app, like enabling a feature? Yes, through tool use. Define a function Claude can call (e.g., enable_feature), execute it against your backend when Claude requests it, and return the result so Claude can confirm it to the user.