Chatbots Tutorial menu

Call an AI API from a Server

Now you will connect your chatbot to a real AI model by calling its API from a Node.js server.

What You Need

  • Node.js 18 or newer (it has fetch built in)
  • An account and an API key from an AI provider
  • The provider's base URL and a model name from their documentation

Many providers offer an OpenAI-compatible chat completions endpoint. This means the request and reply have the same shape, so the same code works with different providers by changing the base URL, key and model.

Rule Number One: Keep the Key Secret

An API key is like a password tied to your bank card. Anyone who has it can use the AI at your cost.

DoNever
Store it in an environment variableWrite it inside your code
Use it only on the serverPut it in browser JavaScript or HTML
Add .env to .gitignorePush it to GitHub
Set a spending limit with the providerShare it in WhatsApp groups

Create a file named .env in your project (and never commit it):

Example

text
AI_API_KEY=paste-your-key-here
AI_BASE_URL=https://api.example-provider.com/v1
AI_MODEL=the-model-name-from-the-docs

Node.js 20.6+ can load it with node --env-file=.env server.js. On a hosting service, you add the same variables in its dashboard instead.

The Request

Send a POST request to BASE_URL/chat/completions with the key in the Authorization header:

Example

javascript
// ai.js - runs on the server only
async function askAI(messages) {
  const response = await fetch(`${process.env.AI_BASE_URL}/chat/completions`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${process.env.AI_API_KEY}`,
    },
    body: JSON.stringify({
      model: process.env.AI_MODEL,
      messages,
      temperature: 0.3,
      max_tokens: 300,
    }),
  });

  if (!response.ok) {
    throw new Error(`AI API error ${response.status}: ${await response.text()}`);
  }
  const data = await response.json();
  return data.choices[0].message.content;
}

module.exports = { askAI };

Reading the Reply

The JSON reply looks like this (shortened). The text is in choices[0].message.content:

Example

javascript
const data = {
  choices: [
    { message: { role: "assistant", content: "Yes, we offer weekend classes." } },
  ],
  usage: { prompt_tokens: 42, completion_tokens: 8 },
};
console.log(data.choices[0].message.content);
console.log("Tokens used:", data.usage.prompt_tokens + data.usage.completion_tokens);
Output
Yes, we offer weekend classes.
Tokens used: 50

The usage part tells you how many tokens you paid for.

A Chat Endpoint with Express

Now make an endpoint the website can call. Install Express with npm install express, then:

Example

javascript
// server.js
const express = require("express");
const { askAI } = require("./ai");

const app = express();
app.use(express.json());
app.use(express.static("public"));   // your chat page lives in /public

const SYSTEM = "You are the friendly assistant for a computer institute in Karachi. " +
  "Answer briefly. If you do not know, say so and suggest calling the office.";

app.post("/api/chat", async (req, res) => {
  const incoming = Array.isArray(req.body.messages) ? req.body.messages : [];
  // Accept only user/assistant text messages, and only the last 10
  const history = incoming
    .filter((m) => (m.role === "user" || m.role === "assistant") && typeof m.content === "string")
    .map((m) => ({ role: m.role, content: m.content.slice(0, 2000) }))
    .slice(-10);
  try {
    const reply = await askAI([{ role: "system", content: SYSTEM }, ...history]);
    res.json({ reply });
  } catch (err) {
    console.error(err);
    res.status(500).json({ reply: "Sorry, something went wrong. Please try again." });
  }
});

app.listen(3000, () => console.log("Chatbot running on http://localhost:3000"));

Run it with node --env-file=.env server.js.

Notice that the server adds the system prompt. The browser only sends the user and assistant messages, and the filter throws away anything else (such as a fake system message), so users cannot replace your instructions. Each message is also cut to 2000 characters to control cost.

Handling Errors

StatusUsual meaningWhat to do
401Wrong or missing keyCheck the environment variable
429Too many requests or no creditWait and retry, check your plan
500+Provider problemRetry later, show a friendly message

Never send the raw error to the user. Log it on the server and show a short, polite message.

Exercise

Exercise

Where should the AI API key be stored in a website chatbot?

Learn Chatbots with a teacher

Join the AI & Prompt Engineering course at Workownix, online or in Orangi Town, Karachi, and get a certificate.

See the course Ask on WhatsApp