ADFREELLM // PUBLIC API
FREE AI API. NO SIGNUP.
AdFreeLLM exposes the same machines the web terminal uses as an OpenAI-compatible API. Point any OpenAI SDK at our base URL, click below for a key, and start streaming. The deal is simple and stated up front: every answer comes back with one clearly labeled sponsored block appended, and that block is what pays for your tokens.
BASE URL
https://api.adfreellm.com/v1
NO SIGNUP · NO EMAIL · 2 PER IP PER DAY
MODELS
| MODEL ID | NOTES |
|---|---|
| gemini-3.6-flash | Fast, general — the default |
| deepseek/deepseek-v4-flash | Reasoning and code |
| gemini-3.5-flash-lite | Fastest, lightest |
| glm-5.2 | Reasoning, strongest Chinese — most reliable in our sampling |
| google/gemma-4-31b-it | Open weights — least stable of the five |
01QUICK START
Two calls: one to mint a key, one to chat. The endpoint is OpenAI-compatible, so any client that speaks /v1/chat/completions works unchanged — just swap the base URL.
# 1. get a free key (no signup, no email)
curl -X POST https://api.adfreellm.com/v1/keys
# 2. use it exactly like the OpenAI API
curl https://api.adfreellm.com/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ADFREE_KEY" \
-d '{
"model": "gemini-3.6-flash",
"messages": [{"role": "user", "content": "Hello!"}]
}'02PYTHON (OPENAI SDK)
The official openai package works as-is. Set base_url and drop in the key you just minted.
from openai import OpenAI
client = OpenAI(
api_key="sk-...", # from POST /v1/keys
base_url="https://api.adfreellm.com/v1",
)
resp = client.chat.completions.create(
model="gemini-3.6-flash",
messages=[{"role": "user", "content": "Hello!"}],
)
print(resp.choices[0].message.content)
# The answer ends with a [AD:...]...[/AD] sponsored block.
# Show it to your users — that block is what pays for this call.03JAVASCRIPT / STREAMING
Streaming works as normal SSE. The ad is delivered as one extra delta chunk immediately before the finish_reason chunk, so your existing accumulate-the-deltas loop picks it up without changes.
const resp = await fetch("https://api.adfreellm.com/v1/chat/completions", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.ADFREE_KEY}`,
},
body: JSON.stringify({
model: "gemini-3.6-flash",
messages: [{ role: "user", content: "Hello!" }],
stream: true,
}),
});
// Streaming: the ad arrives as one extra delta chunk right before
// the finish_reason chunk, and carries a "sponsored" field.04THE SPONSORED BLOCK
Every answer gets exactly one ad, appended after the model finishes. It arrives two ways at once: as a delimited text block inside the content (so plain-text clients still show it), and as a structured `sponsored` field on the response (so real UIs can render a proper card instead). Which ad you get is chosen server-side by a small model reading the question — and when the question is about grief, medical distress, or anything where an ad would be predatory, no ad is sent at all.
{
"choices": [{ "message": { "content": "…answer…\n\n[AD:namebarn-001]\n━━ SPONSORED ━━\nNEED A NAME FOR THIS THING?\nNAMEBARN — Grab the .com…\nhttps://…\n[/AD]" } }],
"sponsored": {
"id": "namebarn-001",
"advertiser": "NAMEBARN",
"hook": "NEED A NAME FOR THIS THING?",
"pitch": "Grab the .com before someone smarter does.",
"url": "https://…"
}
}05SENDING CONVERSATIONS BACK
Multi-turn is safe: put the assistant's previous answer back into messages exactly as you received it, ad block included. The gateway strips every [AD:…][/AD] block out of assistant messages before the model ever sees them, so ads never pollute the context, never get imitated by the model, and never cost you prompt tokens. You do not need to clean anything yourself.
06WHEN NO AD IS INJECTED
Machine-consumed responses are left completely untouched: requests using response_format json_object / json_schema, requests with tools or functions defined, requests with tool_choice set, and requests with n > 1. If you are parsing structured output or running a tool loop, you get clean responses — injecting into those would simply break your program, so we don't.
07LIMITS AND HONESTY
A free key is good for roughly 500 short requests per day and resets nightly (long-context calls burn the allowance faster — the real limit is a daily token quota). Two keys per IP per day, and a limited number of new keys site-wide each day — that daily allocation is set automatically from the previous day's measured upstream health and how many issued keys actually got used, so it grows when the pool is healthy and shrinks the moment it is not. The live number is shown on the button above. There is no SLA: the capacity behind these models is free capacity, so expect occasional 5xx and retry — Gemma 4 31B in particular fails a meaningful fraction of calls. Do not put this on a production critical path. If you need more headroom or actual reliability, email us and say what you are building.
NEED MORE?
Higher limits, a dedicated key, or an ad-free commercial tier — tell us what you are building and we will answer honestly about whether we can support it.
[email protected]