Building Your First AI Chatbot: Model Choice, Code and Real Costs
A working chatbot takes about 30 lines of code. Understanding what it will cost to run takes a little longer, because every reply resends the whole conversation.
What you need
- An API key from one provider. If you don't have one, start here; Google's Gemini API has a free tier for experimenting.
- Node.js 18 or later, or any language that can make an HTTPS request.
- A rough idea of your traffic: how many conversations a month, and how long they run.
Pick a small model first
For a chatbot, response speed and price matter more than top-end reasoning. Start with a small, fast model and move up only if it can't handle your questions:
| Model | Input / output per 1M | Per month |
|---|---|---|
| GPT-6 Luna | $0.10 / $0.50 | $3.15 |
| Claude Haiku 5.5 | $0.10 / $0.50 | $3.15 |
| DeepSeek V4.1 Flash | $0.30 / $1.20 | $8.70 |
| Gemini 3.5 Flash-Lite | $0.30 / $2.50 | $11.95 |
| Gemini 3.8 Flash | $0.75 / $3.75 | $23.63 |
| GPT-6.1 Sol | $2.00 / $10.00 | $63.00 |
| Claude Sonnet 5.5 | $2.00 / $10.00 | $63.00 |
19M input and 2.5M output tokens a month. Prices verified 13 Oct 2026; this table updates automatically.
The table prices 1,000 ten-turn conversations; the section on costs below explains where those token counts come from. For a support bot that must follow detailed instructions, a mid-tier model such as Gemini 3.8 Flash or Claude Haiku 4.5 is a safer default than the very cheapest.
A minimal chatbot
Most providers accept the OpenAI Chat Completions request format, so this example works with OpenAI, DeepSeek, xAI and others by changing the URL, key and model name. It runs in a terminal with Node.js and keeps the conversation in memory:
// chat.mjs: run with OPENAI_API_KEY=... node chat.mjs
import readline from 'node:readline/promises';
const API_URL = 'https://api.openai.com/v1/chat/completions';
const MODEL = 'gpt-6-luna';
const messages = [
{ role: 'system', content: 'You are a friendly assistant for a bike shop. Answer in two or three sentences.' }
];
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
while (true) {
const text = await rl.question('You: ');
if (!text) break;
messages.push({ role: 'user', content: text });
const res = await fetch(API_URL, {
method: 'POST',
headers: { 'Authorization': `Bearer ${process.env.OPENAI_API_KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ model: MODEL, messages })
});
if (!res.ok) { console.error('Error', res.status, await res.text()); break; }
const data = await res.json();
const reply = data.choices[0].message.content;
messages.push({ role: 'assistant', content: reply });
console.log('Bot:', reply);
console.log(`(${data.usage.prompt_tokens} tokens in, ${data.usage.completion_tokens} out)`);
}
rl.close();
Two details matter. First, the model has no memory: the messages array is the memory, and the whole array is sent with every request. Second, the response reports exactly how many tokens you were billed for. Print it while you build; it is the fastest way to understand your costs.
In a real product, this code runs on your server, never in the browser, so your API key stays secret. Your web page sends the user's message to your server, and your server calls the API.
Why the cost of a conversation grows with each turn
Because every request resends the whole conversation, the input for turn ten includes the system prompt and all nine earlier exchanges. Take a 500-token system prompt, 50-token user messages and 250-token replies:
| Turn | Input tokens sent | Output tokens |
|---|---|---|
| 1 | 550 | 250 |
| 2 | 850 | 250 |
| 5 | 1,750 | 250 |
| 10 | 3,250 | 250 |
| Whole conversation | 19,000 | 2,500 |
The replies total 2,500 tokens, but the model reads 19,000. Doubling the length of a conversation more than triples its input. That is why the table at the top prices 1,000 conversations at 19M input and 2.5M output tokens: on GPT-6 Luna that comes to $3.15, and on Claude Sonnet 5.5 $63.00.
Keeping costs predictable
- Cap the reply length with the API's maximum-output setting (
max_completion_tokenson OpenAI,max_tokenson Anthropic, DeepSeek and most others) and ask for short answers in the system prompt. - Limit the history. Keep the last few turns, or replace older turns with a short summary.
- Let caching work. The system prompt and earlier turns are an identical prefix on every request, which providers bill at a discounted cache rate. With half of each conversation's input cached, the Sonnet 5.5 figure above falls to $44.95.
- Set a spending limit in your provider's billing settings, and rate-limit users on your side so one person can't run up the bill.
Before you launch
- Handle errors and rate limits. Retry on HTTP 429 and 5xx responses with a short, growing delay, and show the user a friendly message if the API is down.
- Stream responses so users see text as it is written; every major API supports it.
- Give the bot your facts. Put policies, prices and opening hours in the system prompt, or retrieve the relevant help articles for each question. Models make things up when they don't know.
- Tell users they are talking to an AI, and offer a way to reach a person.
Estimate your own traffic with the token cost calculator, compare candidates side by side with the comparison tool, and see how to cut your AI bill in half once you have real usage numbers.