Skip to main content

freelm — free LLM API for Python & Node.js (OpenAI-compatible, auto-failover)

PyPI npm CI License: MIT

freelm turns the free tiers of Google Gemini, Groq, OpenRouter, Mistral, NVIDIA NIM and Kilo into one OpenAI-compatible LLM — in your Python or TypeScript code, or as a local /v1 endpoint for any tool. It rotates your keys, fails over across providers on rate limits, outages and retired models, and discovers which models are free today. Your own free keys, called directly: nothing to host, no relay in the middle — and the CLI even works with no keys at all.

pip install freelm          # Python >= 3.9   ·   npm install freelm  (Node >= 20, zero dependencies)
import freelm

llm = freelm.FreeLLM.from_env()      # reads GEMINI_API_KEY, GROQ_API_KEY, OPENROUTER_API_KEY, ...
print(llm.text("Explain failover in one sentence."))

Start in 60 seconds

Zero keys? pip install freelm && freelm chat "hello" already works: with no keys configured, the CLI falls back to keyless public endpoints (Kilo Gateway free routes, OVHcloud AI Endpoints anonymous tier) and says so. Their limits are low and free routes may log prompts, so for real use:

  1. Get one free key (no credit card): Google AI Studio is the most generous; add Groq and OpenRouter for failover.

  2. export GEMINI_API_KEY=... (and any others — see providers).

  3. Check what works: freelm doctor sends one tiny request per key and tells you exactly what's wrong and how to fix it:

    $ freelm doctor
      openrouter  sk-or-...a1b2    FAIL  key rejected (401): User not found. — get a new free key: https://openrouter.ai/keys
      google      AIzaSy...x9yz    OK    gemini-2.5-flash-lite · 1131 ms
      groq        gsk_ab...cd12    FAIL  key rejected (401): Invalid API Key — get a new free key: https://console.groq.com/keys
    1 of 3 key(s) working — ready: google
    
  4. Call it from code (above), the terminal (freelm chat "hi"), or any OpenAI-compatible tool (freelm serve, below).

Use free LLMs in any OpenAI-compatible tool

freelm serve runs the same router as a local OpenAI-compatible API — streaming, tool calls and failover included:

freelm serve                 # → http://127.0.0.1:4000/v1   (npx freelm serve works too)

Then point your tool at http://127.0.0.1:4000/v1 with any API key and model auto (or chat:fast, large, tools, or a concrete id):

Tool Setting
OpenAI SDK (Python / Node) OpenAI(base_url="http://127.0.0.1:4000/v1", api_key="freelm")
LangChain ChatOpenAI(base_url="http://127.0.0.1:4000/v1", api_key="freelm", model="auto")
LlamaIndex OpenAILike(api_base="http://127.0.0.1:4000/v1", api_key="freelm", model="auto", is_chat_model=True)
Vercel AI SDK createOpenAICompatible({ name: "freelm", baseURL: "http://127.0.0.1:4000/v1" })("auto")
Continue (VS Code / JetBrains) model with provider: openai, apiBase: http://127.0.0.1:4000/v1, model: auto
Cline / Roo Code API provider "OpenAI Compatible", base URL http://127.0.0.1:4000/v1, model auto
Aider aider --openai-api-base http://127.0.0.1:4000/v1 --openai-api-key freelm --model openai/auto
Open WebUI Admin → Connections → OpenAI API: http://host.docker.internal:4000/v1
n8n OpenAI credential → Base URL http://127.0.0.1:4000/v1

Or with Docker (image built on each release):

docker run --rm -p 4000:4000 -e GEMINI_API_KEY=... -e FREELM_SERVER_KEY=change-me ghcr.io/shihabshahrier/freelm

GET /v1/models lists the aliases plus every discovered free model; GET /health shows key state. A model id no free provider offers (a tool's default gpt-4o) is tried, then served by auto (--no-fallback to disable). Bound to localhost by default — if you expose it (--host 0.0.0.0, Docker on Linux), set --api-key so nobody else spends your quota. In code: freelm.serve() (Python) / serve() (JS).

Python

from freelm import FreeLLM, GoogleAIStudio, Groq, OpenRouter

llm = FreeLLM(
    [GoogleAIStudio("AIza..."), Groq("gsk_..."), OpenRouter("sk-or-...")],   # or FreeLLM.from_env()
    strategy="quota_aware",   # priority | round_robin | quota_aware | latency
)

r = llm.chat([{"role": "user", "content": "Write a haiku about failover."}], model="chat:fast")
print(r.text, "via", r.provider, r.model)

for chunk in llm.stream("Count to five."):          # token streaming, failover before the first token
    print(chunk, end="", flush=True)

r = llm.chat(msgs, model="chat:tools", tools=[...], tool_choice="auto")   # function calling
r.tool_calls

llm.chat(msgs, response_format={"type": "json_object"})                    # JSON mode

Async is symmetric (AsyncFreeLLM, await llm.chat(...), async for c in llm.astream(...)). For raw OpenAI chat.completion.chunk objects — tool-call deltas, finish reasons, usage — use stream_chunks() / astream_chunks().

Drop-in for the OpenAI SDK — change one import:

# from openai import OpenAI
from freelm.compat import OpenAI

client = OpenAI()   # api_key / base_url / ... are accepted and ignored; keys come from the environment
r = client.chat.completions.create(model="auto", messages=[{"role": "user", "content": "hi"}])
print(r.choices[0].message.content)

Responses behave like the SDK's (r.choices[0].message.tool_calls[0].function.arguments, model_dump(), stream=True chunks, with blocks, client.models.list()).

JavaScript / TypeScript

import { FreeLLM } from "freelm";

const llm = FreeLLM.fromEnv();
console.log(await llm.text("Explain failover in one sentence."));
for await (const chunk of llm.stream("Count to five.", { signal: AbortSignal.timeout(30_000) })) process.stdout.write(chunk);

Same engine, same providers, zero dependencies; ESM + CommonJS. No node: imports in the library, so it also bundles for edge functions, Workers and browsers (disk cache/persistence switch on only where Node built-ins exist). See the JS README.

Free providers

Provider Get a free key Environment variable Notes
Google AI Studio (Gemini) aistudio.google.com/apikey GEMINI_API_KEY Most generous free tier; per-model limits. Pro models have no free quota.
Groq console.groq.com/keys GROQ_API_KEY Very fast; per model 30 req/min, 1K req/day. Not xAI's "Grok" (that one is paid).
OpenRouter openrouter.ai/keys OPENROUTER_API_KEY :free models + the openrouter/free router only (guarded); 20 req/min, 50 req/day (1000/day after $10 of lifetime credit).
Kilo Gateway app.kilo.ai (optional) KILO_API_KEY Free routes (:free, kilo-auto/free) work without a key (~200 req/hour per IP); a free account lifts that. Free-only guard on.
OVHcloud AI Endpoints none — anonymous — Keyless, 2 req/min per IP per model; last-resort fallback. (An OVH key is pay-as-you-go, so freelm doesn't use one.)
Cerebras cloud.cerebras.ai CEREBRAS_API_KEY ⚠️ No longer permanently free (trial credits, card required) — supported if you already have a key.
Mistral console.mistral.ai MISTRAL_API_KEY "Experiment" plan; low requests/minute.
NVIDIA NIM build.nvidia.com NVIDIA_API_KEY Free against build credits.

Several keys per provider: comma-separate them or use FREELM_<PROVIDER>_KEYS. The library never uses the keyless endpoints unless asked — FreeLLM.from_env(keyless=True) (always, as last resorts), keyless="auto" (only when no keys are set — the CLI's default) or FREELM_KEYLESS=1|auto|0. Any other OpenAI-compatible endpoint works too: Provider("key", name="myhost", base_url="https://.../v1", models=[ModelSpec("model-id", ("chat",))]).

Free tiers change constantly — models get retired, limits move, keys expire. freelm is built for that: it discovers models live (OpenRouter, Groq, Mistral, Kilo, OVHcloud, Cerebras), benches retired or overloaded models instead of retrying them, and freelm doctor tells you what works right now. The built-in fallback model lists were re-verified on 2026-10-09.

How it stays up

  • Every failure fails over. 429 → rotate the key (or just bench the model, where quotas are per-model: Gemini, Groq); 5xx / timeouts → circuit breaker + backoff; 401/402 → disable that key; a retired model (404/410) → bench it for an hour; one provider rejecting a request (unsupported parameter, moderation) → try the next provider. Only a request that several providers reject is reported as your bug.
  • Breadth-first failover: the best model of every provider is tried before any provider's second model, so a provider full of throttled or dead models can't stall the call.
  • Quota guard: per-key requests/minute bucket + daily counter; keys predicted to be exhausted are skipped.
  • Errors that explain themselves: when everything fails, NoProvidersAvailable says why per provider (openrouter: disabled (auth:401 — key invalid/expired?) | google: cooling down ~30s ...).

Choosing models

Alias Meaning
auto / chat best available chat model (non-thinking models first)
chat:fast · chat:large · chat:small by size/speed
chat:tools · vision only models that support function calling / images
reasoning prefer thinking models
vendor/model-id exactly this model, routed only to providers that list it
["vendor/id", "chat:fast"] an ordered per-call fallback chain

Bias selection with prefer=["gemini-2.5-flash", "gpt-oss"] (exact id or substring), order a static list with ModelSpec(priority=), or rank providers with priority= (lower = first).

Thinking models (gemini-2.5-flash, gpt-oss, ...) can spend a small max_tokens budget on hidden reasoning and return empty text — give them ≥ 128 tokens or use auto, which prefers non-thinking models.

Configuration

FreeLLM(...) option Default
strategy "priority" priority · round_robin · quota_aware · latency
max_attempts 12 cap on tries across providers/keys/models per call
timeout 60 seconds; also the overall deadline for one call
wait / max_wait False / 20 sleep until a key frees up instead of failing
on_event — callback for attempt / success / error / wait / discovery events (keys masked)
persist False (FREELM_PERSIST=1) keep quota/cooldown/disabled-key state across restarts (~/.cache/freelm/state.json, 0600, key hashes only)

Provider options: tier, priority, prefer, models, rpm/rpd, discover, free_only (OpenRouter defaults to True: paid ids raise ConfigError instead of billing you), cache_ttl. llm.health() shows per-key state; llm.reset_keys() gives every key a fresh start.

CLI

freelm chat "explain failover in one line" --model chat:fast --stream
freelm doctor [--json]          # live-check every key, with fixes
freelm serve [--port 4000] [--api-key KEY] [--cors]
freelm models --provider groq   # live model list
freelm health                   # this process's key state

When can freelm cost money?

Free-only by default and by guard: OpenRouter and Kilo paid models are blocked unless you pass free_only=False; Google is free unless you pick tier="tier1" (billing enabled); NIM consumes free build credits and Cerebras trial credits (requests fail when they run out — nothing is billed through freelm); Groq and Mistral free accounts only have free models; OVHcloud is used anonymously only.

How freelm compares

Project What it is Difference
freellmapi, freellmpool Self-hosted gateways pooling many free providers freelm is a library first (pip/npm install, nothing to host) with the gateway optional (freelm serve), in both Python and TypeScript
LiteLLM SDK + proxy for 100+ providers, paid and free freelm is free-only, zero-dependency, with per-key quota/breaker state and free-model discovery built in
OpenRouter One aggregator One of freelm's pools — when its free quota runs out, freelm fails over to Gemini, Groq, Cerebras, Mistral or NIM directly
LangChain / LlamaIndex Orchestration frameworks Use freelm under them via freelm serve or the OpenAI-compatible shim

FAQ

What is the best free LLM API in 2026?

Google AI Studio (Gemini) has the most generous free tier; Groq is the fastest; OpenRouter has the widest choice of :free models. Each has its own limits and outages, so the most reliable option is to use several at once — freelm pools them behind one OpenAI-compatible call and fails over automatically.

Is there a free alternative to the OpenAI API?

Yes. freelm.compat.OpenAI is a drop-in for the OpenAI SDK, and freelm serve exposes a local /v1/chat/completions endpoint, both backed by free tiers (Gemini, Groq, OpenRouter, Cerebras, Mistral, NVIDIA NIM) with streaming, tool calling and automatic failover.

How do I use free LLMs in Cursor, Cline, Continue, Open WebUI or n8n?

Run freelm serve and set the tool's OpenAI base URL to http://127.0.0.1:4000/v1 with model auto — see the table above. Tools that call the endpoint from their own servers need a public URL (for example a tunnel) plus --api-key.

How do I use free LLMs in Python or JavaScript?

pip install freelm or npm install freelm, set one free key (e.g. GEMINI_API_KEY), then freelm.FreeLLM.from_env().text("...") / await FreeLLM.fromEnv().text("...").

Can I use an LLM API with no API key at all?

Yes, for trying things out: freelm chat "hello" (or npx freelm chat "hello") works with no keys by using documented keyless endpoints — Kilo Gateway's free routes (~200 requests/hour per IP) and OVHcloud AI Endpoints' anonymous tier. Limits are low and free routes may log prompts; one free Gemini or Groq key is far more capable.

Why did my free model stop working?

Free model ids are retired constantly (NVIDIA retired its Llama 3.x endpoints on 2026-08-26; Groq retired Llama 3.3 70B on 2026-08-16). freelm discovers current models live, benches retired ones on the first 404/410 and fails over, so your code keeps working; freelm doctor shows which keys and models work today.

How do I avoid free-tier rate limits (429)?

Add more providers and keys: freelm paces each key, rotates on 429, benches per-model quotas (Gemini, Groq) and spreads load with strategy="quota_aware".

Is freelm really free? Does it see my prompts?

freelm is MIT-licensed and runs in your process (or on your machine with freelm serve); requests go straight from you to the providers whose keys you configure. It has no telemetry. Usage limits are those of each provider's free tier.

Changelog · Contributing · Security · Website & docs · PyPI · npm

MIT © Shahriar Labs

Metadata

Release files for freelm 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for freelm 0.4.0
File Size Uploaded
freelm-0.4.0.tar.gz 81.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for freelm 0.4.0
File Interpreter ABI Platform
freelm-0.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 152.2 kB

Release files / freelm-0.4.0.tar.gz

Download URL freelm-0.4.0.tar.gz
Size 81.5 kB
Tags Source
SHA-256 checksum
How to use checksums
b128f7c1cdc9cab71d1364dceeb68213639776624f49a6ac3455e512082358ea
BLAKE2b-256 checksum
How to use checksums
7a8850409478e895cf66eea35000b95948951bde7116e1838d72b3774cdffbfb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / freelm-0.4.0-py3-none-any.whl

Download URL freelm-0.4.0-py3-none-any.whl
Size 70.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
81e3c050cabe37fad16986bfec89efcad9ae07ac0ae9ed8e74af894650c8c07f
BLAKE2b-256 checksum
How to use checksums
33845f9f47f83814a9ca0f2cb74388e5bea436ebf18e085a5f10a83072d451d2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release history Release notifications | RSS feed

0.5.2

2 release files

0.5.1

2 release files

0.5.0

2 release files

This release

0.4.0 This release

2 release files

0.3.0

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page