Building an AI chatbot is a practical way to add conversational features to a website, customer support system, or web application. With Node.js and the OpenAI API, you can create a chatbot that understands user messages and generates relevant responses without training a language model from scratch.
In this tutorial, we'll build a simple AI chatbot using Node.js, Express, and the official OpenAI JavaScript SDK. You'll learn how to configure your API key, create a backend endpoint, handle user messages, and test the chatbot.
*What You Will Build
*
By the end of this guide, you will have a basic chatbot backend that:
Accepts messages from users through an API endpoint.
Sends the messages to an OpenAI model.
Returns AI-generated responses.
Supports basic conversation history.
Handles invalid requests and API errors.
Prerequisites
Before starting, make sure you have:
Node.js and npm installed.
Basic knowledge of JavaScript and REST APIs.
An OpenAI API key with API access and billing configured.
You can download Node.js from the official Node.js website and review the OpenAI API documentation.
Step 1: Create a Node.js Project
Create a new directory for your chatbot and initialize the project.
mkdir node-openai-chatbot
cd node-openai-chatbot
npm init -y
Install the required packages:
npm install express openai dotenv
Here is what each package does:
Express: Creates the backend API.
OpenAI: Connects your application to the OpenAI API.
dotenv: Loads environment variables from a local .env file.
For more information, see the Express documentation and the official OpenAI Node.js SDK.
Step 2: Configure Your API Key
Create a file named .env in your project directory.
OPENAI_API_KEY=your_openai_api_key
OPENAI_MODEL=gpt-5.5
PORT=3000
Replace the placeholder with your actual API key. If the selected model is unavailable to your account, configure a supported model instead.
Important: Never put your API key in frontend JavaScript, a public repository, or a client-side application. Keep it on the server and add .env to your .gitignore file.
Create a .gitignore file:
node_modules/
.env
This helps prevent your local credentials from being committed to Git.
Step 3: Create the Chatbot Backend
Create a file named server.js.
Add the following code:
require("dotenv").config();
const express = require("express");
const OpenAI = require("openai");
const app = express();
const port = process.env.PORT || 3000;
app.use(express.json({ limit: "20kb" }));
if (!process.env.OPENAI_API_KEY) {
throw new Error("OPENAI_API_KEY is missing from the environment.");
}
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
app.post("/api/chat", async (req, res) => {
try {
const { message, history = [] } = req.body;
if (typeof message !== "string" || !message.trim()) {
return res.status(400).json({
error: "Please provide a valid message.",
});
}
if (!Array.isArray(history) || history.length > 10) {
return res.status(400).json({
error: "Conversation history must contain at most 10 messages.",
});
}
const validHistory = history.every(
(item) =>
item &&
["user", "assistant"].includes(item.role) &&
typeof item.content === "string" &&
item.content.length <= 4000
);
if (!validHistory) {
return res.status(400).json({
error: "Invalid conversation history.",
});
}
const input = [
...history.map((item) => ({
role: item.role,
content: item.content,
})),
{
role: "user",
content: message.trim(),
},
];
const response = await openai.responses.create({
model: process.env.OPENAI_MODEL || "gpt-5.5",
instructions:
"You are a helpful website chatbot. Answer clearly and concisely.",
input,
max_output_tokens: 500,
});
return res.json({
reply: response.output_text,
});
} catch (error) {
console.error("Chatbot request failed:", error.message);
return res.status(500).json({
error: "Unable to generate a response. Please try again.",
});
}
});
app.listen(port, () => {
console.log(Chatbot server running on port ${port});
});
This example uses the Responses API, which supports text inputs and generated text outputs. You can read more in the Responses API documentation.
How the code works
Express receives a message through the /api/chat endpoint.
The server validates the message and conversation history.
The OpenAI SDK sends the input to the configured model.
The API generates a response.
Express returns the response to the client as JSON.
The history array lets the application include previous user and assistant messages. Your frontend must send that history with each request if you want to maintain conversational context.
Step 4: Start the Server
Run the following command:
node server.js
If the configuration is correct, the server will start on port 3000.
You can now send a request to the chatbot endpoint.
Step 5: Test the Chatbot API
Use this curl command in your terminal:
curl -X POST http://localhost:3000/api/chat \
-H "Content-Type: application/json" \
-d '{
"message": "Explain what Node.js is in simple terms.",
"history": []
}'
The chatbot should return a JSON response similar to this:
{
"reply": "Node.js is a runtime that lets developers run JavaScript outside a web browser..."
}
The exact response will vary because the model generates text dynamically.
To continue the conversation, send the previous messages in the history array:
{
"message": "Can you give me an example?",
"history": [
{
"role": "user",
"content": "Explain what Node.js is in simple terms."
},
{
"role": "assistant",
"content": "Node.js lets developers run JavaScript outside a browser."
}
]
}
For production applications, store conversation history appropriately, enforce message and token limits, and avoid trusting client-supplied history as verified information.
Step 6: Add Basic Security and Error Handling
A chatbot that works locally is only the first step. Before deploying it, consider these improvements:
Protect your API key: Keep credentials in environment variables or a secure secrets manager.
Add rate limiting: Limit how many requests a user can make in a given period to reduce abuse and unexpected API costs.
Validate incoming data: Set maximum message lengths and reject malformed requests.
Control conversation history: Limit the number of previous messages and the amount of text sent to the model.
Handle errors safely: Return a generic error to users while recording appropriate diagnostic information on the server. Avoid exposing API keys or sensitive error details.
Add authentication where necessary: If the chatbot is part of a private application, restrict access to the endpoint.
You can also explore OWASP's API Security guidance when preparing the application for production.
Common Problems and How to Fix Them
Problem
Possible solution
Missing API key
Check the .env file and restart the server.
Authentication error
Verify the API key and account access.
Model unavailable
Choose a model supported by your account.
Rate limit or quota error
Review API usage, limits, and billing.
Chatbot forgets previous messages
Send relevant conversation history with each request.
Slow responses
Reduce unnecessary input, set suitable output limits, and monitor API latency.
Conclusion
Creating a chatbot with Node.js and the OpenAI API does not require a complicated architecture. With Express, the official OpenAI SDK, and a secure backend, you can build a working foundation for conversational features in a web application.
You can extend this example with a chat interface, streaming responses, user authentication, database-backed conversation history, and integrations with your existing business systems.
If you are planning a more advanced solution, explore chatbot development integration services to understand how custom chatbots can be integrated into websites and business workflows.
Related keywords: Node.js chatbot, OpenAI API integration, AI chatbot development, chatbot using Node.js, JavaScript chatbot, Express.js chatbot, conversational AI, AI chatbot API integration.
Top comments (0)