Fundamentals

Best Free AI APIs for Beginners: A Python Quickstart

Connect to OpenRouter, Hugging Face Inference, and Groq free tiers with Python in under 10 minutes. One unified connector, runnable scripts, no credit card.

This guide shows you how to connect to three genuinely free AI APIs from Python in under ten minutes, with one connector you can reuse everywhere. You will wire up Groq, OpenRouter, and the Hugging Face Inference API — all of which give you working keys with no credit card — and end with a single function that talks to any of them.

"API" just means a way for your code to send a request to a service and get an answer back. An "AI API" is that, where the service on the other end is a large language model (the kind of model that powers chat assistants). A "free tier" is an allowance you can keep using within set limits, as opposed to a trial that expires.

It belongs to Understanding LLM APIs, the section that walks through how any hosted model API works, and it is the cheapest place to start: nothing here costs money, so you can run every script as many times as you like.

Prerequisites

You only need a working Python setup and three free accounts. If Python or virtual environments are new to you, start with Create a Python Virtual Environment for AI, then come back.

This guide uses Python 3.10 or newer, the official openai SDK (which works against any OpenAI-compatible endpoint, not just OpenAI), and httpx for the one provider that speaks a different format.

python -m venv .venv
source .venv/bin/activate  # Windows: .venv\Scripts\activate
pip install openai httpx python-dotenv

Now grab one free key from each provider. None of these ask for a card:

  • Groq — sign up at console.groq.com and create an API key. Copy it as GROQ_API_KEY.
  • OpenRouter — sign up at openrouter.ai, open Keys, and create a key. Copy it as OPENROUTER_API_KEY.
  • Hugging Face — sign up at huggingface.co, open Settings then Access Tokens, and create a read token. Copy it as HUGGINGFACE_API_KEY.

Create a file named .env in your project root and paste them in:

GROQ_API_KEY=gsk_your_groq_key_here
OPENROUTER_API_KEY=sk-or-your_openrouter_key_here
HUGGINGFACE_API_KEY=hf_your_token_here

Add .env to your .gitignore immediately so you never commit your keys. One line in .gitignore does it:

echo ".env" >> .gitignore

A leaked key can be used by strangers and burn through your limits, so this single step matters more than anything else in the guide.

Step 1: Connect to Groq with the openai SDK

Groq runs open models on hardware tuned for speed, and its API copies OpenAI's format exactly. That means you can use the official openai SDK and only change one setting — the base_url — to point it at Groq instead.

import os
from dotenv import load_dotenv
from openai import OpenAI

load_dotenv()

groq = OpenAI(
    base_url="https://api.groq.com/openai/v1",
    api_key=os.environ["GROQ_API_KEY"],
)

response = groq.chat.completions.create(
    model="llama-3.1-8b-instant",
    messages=[{"role": "user", "content": "Explain an API in one sentence."}],
)

print(response.choices[0].message.content)

The messages list is the conversation so far. The role of "user" marks your input; the model replies in the choices array, and choices[0].message.content is the text you want. Run the file and you should see a one-sentence answer in well under a second.

Two optional settings are worth knowing early. max_tokens caps how long the reply may run, which protects your free quota, and temperature controls how varied the wording is from one run to the next — What Is Temperature in an LLM API? explains when to raise or lower it. Every OpenAI-compatible provider accepts the same request shape, so the anatomy below is worth memorising once: what you send on the left, what you read back on the right.

The anatomy of one OpenAI-compatible chat request and its reply Two labelled columns. The left column lists the three parts you put in the request — model, messages, and temperature. The right column lists the three parts of the JSON reply — choices, message content, and usage. A single arrow marks the one HTTPS call that connects them. What you send What comes back model llama-3.1-8b-instant messages role and content pairs temperature optional wording dial one HTTPS call choices a list of replies message.content the text you print usage tokens in and out
Learn these six names once and every OpenAI-compatible free tier becomes readable: three keys go out in the request, three come back in the reply.

Step 2: Connect to OpenRouter the same way

OpenRouter is a single doorway to dozens of models — some paid, several free. Because it is also OpenAI-compatible, the only things that change from Step 1 are the base_url, the key, and the model name. Free models on OpenRouter end in :free.

openrouter = OpenAI(
    base_url="https://openrouter.ai/api/v1",
    api_key=os.environ["OPENROUTER_API_KEY"],
)

response = openrouter.chat.completions.create(
    model="meta-llama/llama-3.1-8b-instruct:free",
    messages=[{"role": "user", "content": "Name three free AI APIs."}],
)

print(response.choices[0].message.content)

This is the payoff of OpenAI-compatible APIs: once you know one, you know all of them. If you want a side-by-side on which of these two to reach for, see Groq vs OpenRouter Free Tier.

Step 3: Connect to Hugging Face Inference with httpx

Hugging Face is the odd one out. Its general Inference API takes a plain inputs string instead of a messages array, and it returns a list of results instead of a choices object. Because it is not OpenAI-compatible, you call it directly with httpx (a modern HTTP library) rather than the openai SDK.

import httpx

HF_URL = "https://api-inference.huggingface.co/models/mistralai/Mistral-7B-Instruct-v0.2"

headers = {"Authorization": f"Bearer {os.environ['HUGGINGFACE_API_KEY']}"}
payload = {"inputs": "Explain an API in one sentence."}

response = httpx.post(HF_URL, headers=headers, json=payload, timeout=60)
response.raise_for_status()

print(response.json()[0]["generated_text"])

The model name lives in the URL here, not in the payload. The first call to a model can be slow because Hugging Face may need to load it onto a server, which is why the timeout is set generously to 60 seconds. If a request still stalls or drops halfway, Fix Connection and Timeout Errors with AI APIs explains which exception httpx raises for each failure and what to do about it.

Step 4: Wrap all three in one unified connector

You now have three working calls that look slightly different. The point of a connector is to hide those differences behind one function, so the rest of your program can say "ask provider X this prompt" and not care how each API is shaped.

import os
import httpx
from dotenv import load_dotenv
from openai import OpenAI

load_dotenv()

CLIENTS = {
    "groq": OpenAI(
        base_url="https://api.groq.com/openai/v1",
        api_key=os.environ["GROQ_API_KEY"],
    ),
    "openrouter": OpenAI(
        base_url="https://openrouter.ai/api/v1",
        api_key=os.environ["OPENROUTER_API_KEY"],
    ),
}

MODELS = {
    "groq": "llama-3.1-8b-instant",
    "openrouter": "meta-llama/llama-3.1-8b-instruct:free",
}

HF_URL = "https://api-inference.huggingface.co/models/mistralai/Mistral-7B-Instruct-v0.2"


def ask(provider: str, prompt: str) -> str:
    """Send one prompt to any free provider and return clean text."""
    if provider == "huggingface":
        headers = {"Authorization": f"Bearer {os.environ['HUGGINGFACE_API_KEY']}"}
        response = httpx.post(
            HF_URL, headers=headers, json={"inputs": prompt}, timeout=60
        )
        response.raise_for_status()
        return response.json()[0]["generated_text"]

    # OpenAI-compatible providers: Groq and OpenRouter
    completion = CLIENTS[provider].chat.completions.create(
        model=MODELS[provider],
        messages=[{"role": "user", "content": prompt}],
    )
    return completion.choices[0].message.content

Read the function from the outside in and the design is easy to hold in your head. Your script only ever calls ask; ask owns the branch between the two OpenAI-compatible clients and the Hugging Face path, and each provider keeps its own quirks behind that wall. Adding a fourth provider later means editing one dictionary, not every file that talks to a model.

How one ask function routes a prompt to three free providers A data-flow diagram. Your script sends a prompt to a single ask function, which routes it to one of three free providers: Groq and OpenRouter through the openai SDK with a changed base URL, and Hugging Face through httpx with an inputs string. Your program One function Free providers Your script one call per prompt One ask() function picks the right client Groq openai SDK, base_url OpenRouter openai SDK, base_url Hugging Face httpx, inputs string
The connector is the only place in your code that knows how each provider differs, so swapping providers never touches the rest of your program.

Now any of these three lines works, and switching providers is a one-word change:

print(ask("groq", "Give me a fun fact about octopuses."))
print(ask("openrouter", "Give me a fun fact about octopuses."))
print(ask("huggingface", "Give me a fun fact about octopuses."))

Step 5: Add safe retries for rate limits

Free tiers cap how many requests you can send per minute. When you go over, the API replies with a 429 status, which means "too many requests, slow down." The fix is to wait and try again, doubling the wait each time — a pattern called exponential backoff. This keeps short bursts from crashing your script.

import time
from openai import RateLimitError


def safe_ask(provider: str, prompt: str, retries: int = 3) -> str:
    for attempt in range(retries):
        try:
            return ask(provider, prompt)
        except (RateLimitError, httpx.HTTPStatusError) as error:
            status = getattr(getattr(error, "response", None), "status_code", None)
            if status == 429 and attempt < retries - 1:
                time.sleep(2 ** attempt)  # wait 1s, then 2s, then 4s
                continue
            raise
    raise RuntimeError(f"Failed after {retries} retries")

Call safe_ask exactly like ask, and it will quietly recover from the occasional rate-limit bump. For a deeper look at this error, read Fix the 429 Rate-Limit Error in Python.

Free API quick reference

The three providers differ in how you call them and what they are best at. Keep this table next to you while you experiment.

ProviderLibrary to useRequest shapeReads result fromBest for
Groqopenai SDK (base_url set)messages arraychoices[0].message.contentFastest responses, easiest start
OpenRouteropenai SDK (base_url set)messages arraychoices[0].message.contentTrying many models from one key
Hugging Facehttpxinputs stringjson()[0]["generated_text"]Open models for non-chat tasks

Troubleshooting

A few errors trip up almost everyone on their first run. Here is what each one means and how to clear it.

  1. KeyError: 'GROQ_API_KEY' — Python could not find that key. Cause: your .env file is missing the line, or load_dotenv() never ran. Fix: confirm the variable name matches exactly and that load_dotenv() is called before you read the key.
  2. 401 Unauthorized — the provider rejected your key. Cause: a typo, a trailing space, or a key copied for the wrong provider. Fix: regenerate the key, paste it freshly into .env, and check you are sending it to the matching service. See Fix the 401 Unauthorized Error in OpenAI Python.
  3. KeyError: 0 or TypeError on the Hugging Face response — the model returned an object, not the usual list. Cause: the model is still loading, or it returned an error message instead of text. Fix: print response.json() to see the raw reply; if it says the model is loading, wait a few seconds and retry.
  4. 429 Too Many Requests — you hit the free rate limit. Cause: too many calls in a short window. Fix: use the safe_ask retry wrapper from Step 5 and space your calls out.
  5. ModuleNotFoundError: No module named 'openai' — Python cannot see the SDK. Cause: you installed it outside the virtual environment, or the environment is not activated in the terminal you are running from. Fix: activate .venv, run pip install openai again, and check which python. Fix ModuleNotFoundError: No Module Named openai covers the less obvious causes.

When to use this vs. alternatives

  • Use these free tiers when you are learning, prototyping, or running low-volume personal projects. They cost nothing and are more than fast enough to build real scripts.
  • Reach for a paid OpenAI or Anthropic key when you need the strongest reasoning, larger context windows, or higher guaranteed rate limits for production traffic. The trade-offs are laid out in OpenAI vs Anthropic API for Beginners.
  • Self-host an open model only once your volume is large enough that per-request fees outweigh the cost and effort of running your own server. For most beginners, that day is a long way off.

The honest trigger for moving off a free tier is volume, not ambition. Track how many calls your script actually makes before you assume you have outgrown the allowance — Count Tokens in Python Before You Send shows how to measure that in a couple of lines. The decision tree below is the short version.

Choosing between a free tier, a paid key and self-hosting A decision tree. One question about which key you need branches into three usage levels — learning or a demo, a live app with steady traffic, and heavy volume — and each level points to its answer: a free tier key, a paid API key, or a self-hosted model. Which key do you actually need? Learning or a demo a few calls an hour A live app steady daily traffic Heavy volume millions of calls Free tier key Groq or OpenRouter Paid API key OpenAI or Anthropic Self-hosted model your own server
Volume, not ambition, is what pushes you off a free tier — stay on one until your own measurements say otherwise.

Back to Understanding LLM APIs.

Frequently asked questions

Which free AI API is best for a complete beginner?

Groq is the easiest to start with because it is OpenAI-compatible, very fast, and gives you a generous free request quota with no card on file. OpenRouter is the best for trying many different models from one key, and Hugging Face Inference is best when you want open models for tasks beyond chat, like summarization or classification.

Do these free AI APIs require a credit card?

No. Groq, OpenRouter, and Hugging Face all let you create an account and generate an API key without entering payment details. You only need a card if you later choose to upgrade to a paid plan with higher limits.

What is the difference between a free tier and a free trial?

A free tier is an ongoing allowance you can use indefinitely within set rate limits. A free trial is a one-time pool of credits that expires after a period or once spent. The three providers in this guide all offer genuine free tiers, not just trials.

Why does Hugging Face return a different response shape from OpenRouter and Groq?

OpenRouter and Groq both copy OpenAI's chat-completions format, so they return a choices array with message objects. The Hugging Face Inference API for many models takes a plain inputs string and returns a list of generated-text results, so your code has to read it differently.

Can I use the official openai Python SDK with these free APIs?

Yes, for the OpenAI-compatible ones. You point the openai client's base_url at OpenRouter or Groq and pass the matching API key. Hugging Face's general inference endpoint is not OpenAI-compatible, so you call it with httpx instead.