Using the Claude API for a Customer Onboarding Chatbot
If you're building a chatbot that walks new users through account setup, configuration, and their first "aha moment" with your product, the Claude API is a strong fit because it handles multi-turn conversation state well, supports structured tool calls for pulling account data, and can stream responses so onboarding feels instant rather than laggy. This article covers the architecture, the specific prompting and tool-use patterns that work for onboarding flows, and how to get from prototype to production without rebuilding your auth and billing layer from scratch.
The core design question for an onboarding chatbot isn't "which model" — it's how the bot knows what step the user is on, what data it's allowed to read or write, and how you keep costs predictable as usage grows. We'll work through each of those.
Why Claude fits onboarding use cases
Onboarding conversations are different from general support chat in three ways that matter for API design:
- They're stateful and sequential. The bot needs to know the user already connected their email but hasn't set up billing yet.
- They need to call your systems. Checking plan status, creating API keys, verifying domain ownership — these require tool use, not just text generation.
- They need to stay on-script. An onboarding bot that wanders into unrelated topics is a liability, not a feature.
Claude's tool use (function calling) and long context window make it practical to pass the user's current onboarding state into every turn, let the model decide which backend action to take next, and keep the conversation coherent across many steps without re-explaining context.
Architecture: state, tools, and the chat loop
A typical onboarding chatbot has four moving parts:
- Onboarding state store — a simple record per user (
step,completed_tasks,plan,integration_status). - Tool definitions — functions Claude can call, like
check_integration_status,create_api_key,send_verification_email. - The Claude API call — system prompt + conversation history + current state + tool results.
- Your UI — chat widget, streaming responses, and action confirmations (e.g., "I've created your API key").
Here's a minimal tool-use setup for an onboarding assistant:
{
"model": "claude-sonnet-4",
"system": "You are the onboarding assistant for Acme. Guide the user through setup: email verification, connecting a payment method, and creating their first API key. Never skip steps. Use tools to check real status before claiming something is done.",
"tools": [
{
"name": "check_onboarding_status",
"description": "Returns the user's current onboarding step and completed tasks",
"input_schema": { "type": "object", "properties": {} }
},
{
"name": "create_api_key",
"description": "Creates a new API key for the authenticated user",
"input_schema": { "type": "object", "properties": {} }
}
],
"messages": [
{ "role": "user", "content": "I signed up, what's next?" }
]
}
The model will typically respond with a tool call for check_onboarding_status before answering, because the system prompt tells it not to guess. You execute that function server-side, return the result, and Claude produces the actual reply — "You've verified your email. Next, let's connect a payment method." That loop (call model → run tool → return result → call model again) is the same pattern used in any Claude tool-use workflow; see the docs for the full request/response shape.
Keeping the bot on-script
Onboarding bots fail most often by over-explaining or by answering questions outside their scope ("can you also help me debug my webhook integration?"). Two things help:
- A narrow system prompt that explicitly states the bot's job and what it should defer ("For billing disputes, tell the user to email support@... Do not attempt to resolve them.").
- Step-gating in the prompt, not just in your UI. Pass the current step explicitly:
Current step: payment_setup. Do not discuss API key creation until payment is confirmed.Models follow explicit state better than implicit inference from chat history.
A short example of a step-gated turn:
const state = await getOnboardingState(userId);
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: `You are Acme's onboarding assistant. Current step: ${state.step}. Completed: ${state.completed.join(", ")}.`,
messages: [{ role: "user", content: userMessage }]
})
});
Passing state as plain text in the system prompt, rather than relying on the model to remember it from a long chat history, keeps behavior consistent even in conversations that resume days later.
Streaming for a responsive feel
Onboarding flows live or die on perceived speed. A user who clicks "connect payment" and waits four seconds for a static response feels stuck; the same response streamed token-by-token feels alive. Streaming is a standard part of the Claude API and SubToAPI passes it through as server-sent events, so your chat widget can render partial responses as they arrive — see /docs/streaming for the event format and reconnect handling.
Getting it into production
Once the prototype works, the practical questions are usually about access and cost, not the prompt itself:
- Per-environment keys. You want a key for staging and a separate one for production so a bad onboarding-flow deploy doesn't burn production quota.
- Usage visibility. Onboarding bots run on every signup, so token usage scales directly with growth — you want to see that trend before it becomes a surprise invoice.
- No new infrastructure. Most teams don't want to stand up a proxy, manage rate limiting, and build a billing dashboard just to ship a chatbot.
SubToAPI addresses that last point directly: it turns your existing Claude access into a standard HTTPS API with sub_live_... application keys, so your onboarding bot calls one endpoint, team members get their own seats and keys, and usage metadata is visible per key in a dashboard instead of buried in a provider console. Start with the /docs/quickstart guide, use /docs/messages for the request format, and /docs/tools if your onboarding flow needs function calling. Plans start at Solo €9, with Team and Scale tiers for multi-seat setups, and there's a free trial at /signup if you want to test it against your actual onboarding flow before committing.
Questions
Does the Claude API maintain conversation memory across onboarding sessions on its own? No. The API is stateless between requests — you send the full message history (or a summary) with each call. For onboarding bots, store state like current_step and completed_tasks in your own database and inject it into the system prompt each turn.
Should onboarding chatbots use tool use or just scripted logic with Claude generating text? Use tool use whenever the bot needs real data — account status, payment confirmation, API key creation. Scripted logic alone can't verify facts, and a model that claims "your email is verified" without checking will eventually be wrong and erode trust in the flow.
How do I control costs for a chatbot that runs on every new signup? Use a smaller/faster model for routine steps and reserve larger models for ambiguous user questions, cap max tokens per response, and track usage per key so you catch cost spikes early — a dashboard that shows usage by key, like SubToAPI's, makes this easier than digging through raw provider logs.