Build a chatbot on free AI API tiers

Guide · updated November 1st, 2026

A small chatbot in Python that runs on a free AI tier, from Groq, Google Gemini or OpenRouter, and switches between them by changing one setting, because all three accept the OpenAI chat format. It keeps the conversation, so the model remembers what was said.

What you need

Python 3 with requests, and a free API key from at least one provider: the Groq API (open models on very fast hardware), the Google Gemini API (Google's models; prompts on the free tier may be used to improve Google's products) or OpenRouter (one key for many models; its free models are limited to 50 requests a day).

Keep the key on your computer or server. Never put it in JavaScript on a web page: anyone could read it and use up your limits.

One request format for all three

Each provider takes a POST to /chat/completions under its own base address, with your key as a Bearer token and a list of messages. Every message has a role (system, user or assistant) and content. The answer is in choices[0].message.content. Only the base address, the key and the model name differ.

curl

curl -X POST 'https://api.groq.com/openai/v1/chat/completions' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"model": "openai/gpt-oss-20b", "messages": [{"role": "user", "content": "Say hello"}]}'

The chatbot

Save it as chatbot.py, set your key and run it, for example GROQ_API_KEY=... python3 chatbot.py, or PROVIDER=gemini GEMINI_API_KEY=... python3 chatbot.py. It sends the whole conversation each time, which is how these APIs remember context. An empty line ends it. When a provider refuses a request, for example over a rate limit, the script shows the reason and you can ask again.

Python

import os

import requests

# Three free tiers that use the OpenAI chat format: base address, the
# environment variable with your key, and the model
PROVIDERS = {
    "groq": ("https://api.groq.com/openai/v1", "GROQ_API_KEY", "openai/gpt-oss-20b"),
    "gemini": ("https://generativelanguage.googleapis.com/v1beta/openai", "GEMINI_API_KEY", "gemini-3.8-flash"),
    "openrouter": ("https://openrouter.ai/api/v1", "OPENROUTER_API_KEY", os.environ.get("OPENROUTER_MODEL", "")),
}


def ask(messages, provider):
    base_url, key_name, model = PROVIDERS[provider]
    response = requests.post(
        base_url + "/chat/completions",
        headers={"Authorization": "Bearer " + os.environ[key_name]},
        json={"model": model, "messages": messages},
        timeout=60,
    )
    response.raise_for_status()
    return response.json()["choices"][0]["message"]["content"]


if __name__ == "__main__":
    provider = os.environ.get("PROVIDER", "groq")
    history = [{"role": "system", "content": "You are a helpful assistant. Answer in a few sentences."}]
    while True:
        question = input("You: ").strip()
        if not question:
            break
        history.append({"role": "user", "content": question})
        try:
            answer = ask(history, provider)
        except requests.HTTPError as error:
            print("The API said:", error.response.status_code, error.response.text[:200])
            history.pop()
            continue
        history.append({"role": "assistant", "content": answer})
        print("Bot:", answer)

Choosing a model on OpenRouter

OpenRouter's free models change often; their names end in :free. Its model list is public, so this prints the current ones. Set one as OPENROUTER_MODEL.

Shell

curl -s https://openrouter.ai/api/v1/models | python3 -c "import json,sys; print('\n'.join(m['id'] for m in json.load(sys.stdin)['data'] if m['id'].endswith(':free')))"

Going further

For a chat box on your website, put ask() behind a small endpoint on your own server and let the page call that endpoint, so the key never reaches the browser. Limit how often one visitor may ask, or one person can use up your free tier for everyone.

Long conversations cost more tokens with every message; keep the last ten or so. Model names change over time: when a provider retires one, pick a current one from its model list.

Other free tiers with the same format: GitHub Models, for prototypes with a GitHub account, and Cloudflare Workers AI.

The APIs in this guide