Free AI Image Generation APIs in 2026: How to Get a Key and What Each Free Tier Allows
Only a few image-generation APIs are free to call from your own code in 2026. Cloudflare Workers AI gives 10,000 neurons a day — about 57 FLUX.1 [schnell] images. A free Hugging Face account gets five GPU minutes a day on ZeroGPU Spaces. Pollinations, Puter.js and Stability AI cover the rest. Gemini’s image API has no free tier.


( Before you start )
Which image APIs are actually free?
| API | Free allowance | What you need | Best for |
|---|---|---|---|
| Cloudflare Workers AI | 10,000 neurons a day — about 57 FLUX.1 [schnell] images | Account ID + API token | A real app’s backend |
| Hugging Face Spaces | 5 GPU minutes a day with a free account, 2 without one | Nothing; a token raises the quota | Scripts and prototypes |
| Pollinations | One-time Pollen from dashboard quests; FLUX.1 [schnell] costs 0.002 Pollen | API key | Quick experiments |
| Puter.js | Free for you — each visitor pays from their own Puter account | Nothing | Browser-only apps |
| Stability AI | 25 credits once — 8 Stable Image Core images | API key | Trying Stability’s models |
Checked on 20 October 2026 against each provider’s own pricing and documentation, and every free route here was called from code that day — the Cloudflare figures are measured on a free account. Free tiers change often; each section links to the page to check again.
Not free, whatever you read elsewhere: the Gemini API lists no free tier for any image model, Together AI’s image models are all paid, and Hugging Face’s Inference Providers include no monthly credits for free accounts. Details in Not free, despite the claims.
How to choose
- Building a site or app that generates images for visitors? Cloudflare Workers AI. It has the most dependable daily allowance, a stable REST API and published rate limits (720 requests a minute for image models).
- Running a script on your own machine? A Hugging Face Space through
gradio_client. No account needed to start. - A static site with no server at all? Puter.js — no key to hide, because each visitor signs in and pays for their own images.
- Selling the images or using them for a client? FLUX.1 [schnell] is released under Apache-2.0, which allows commercial use. Check the model card for any other model you pick.
Whichever you choose, the prompt matters more than the API. How to write AI image prompts walks through a formula that works with all of them.
Set up a .env file first
Every key below goes in one file at the root of your project, never in the code itself. Create .env, one line per key, no quotes and no spaces around =:
CF_ACCOUNT_ID=your-account-id
CF_API_TOKEN=your-cloudflare-token
HF_TOKEN=hf_...
POLLINATIONS_KEY=sk_...
STABILITY_API_KEY=sk-...Keep it out of git before anything else, so it can never be pushed by accident:
echo ".env" >> .gitignore
git status # .env must not appear in the list- In the terminal (for the
curlexamples):set -a; source .env; set +aloads every key into the current shell. - In Node 20 or later:
node --env-file=.env script.mjs— no package needed. - In Next.js: keys in
.envare read on the server automatically. Never prefix them withNEXT_PUBLIC_, which would send them to the browser.
If a key leaks — pasted in a chat, pushed to GitHub, shown in a screenshot — replace it at once: Cloudflare under My Profile → API Tokens (Roll or delete), Hugging Face under Access Tokens → Manage, Pollinations and Stability by deleting the key on their dashboards and making a new one.
( Get a key and make your first image )
Cloudflare Workers AI
Every Cloudflare account, including the free plan, gets 10,000 neurons a day, reset at 00:00 UTC. Each response reports what it used: a 1024 × 1024 FLUX.1 [schnell] image at the default 4 steps came to 172.8 neurons in my test — about 57 images a day. (The bill is 4.8 neurons per 512 × 512 tile plus 9.6 per tile per step, so a 1024 × 1024 image is 4 tiles.) On the free plan, requests over the limit fail until the reset — you are never billed.
Get the key
- Sign up at dash.cloudflare.com and verify your email. The free plan is enough.
- In the dashboard, open AI → Workers AI and select Use REST API.
- Select Create a Workers AI API Token. A form opens with most fields already filled — check them against the table below.
- Select Continue to summary, then Create Token, and copy the token straight away. Cloudflare shows it only once.
- Back on the Workers AI page, under Get Account ID, copy the Account ID.
- Put both in your
.envasCF_ACCOUNT_IDandCF_API_TOKEN(see Set up a .env file first).
| Field in the form | What to put |
|---|---|
| Token name | Anything. One token per project is easiest to manage — portfolio-image-api, for example. |
| Permissions, row 1 | Account → Workers AI → Read. If the last box shows 0, that is an empty value: click the arrows and pick Read. |
| Permissions, row 2 | Account → Workers AI → Edit. Usually already set. |
| Account Resources | Include → your own account (shown as “<your email>’s Account”). |
| Client IP Address Filtering | Leave empty. Later, on a server with a fixed IP, you can lock the token to it. |
| TTL | Leave empty for a token that does not expire, or set an end date for a test token. |
Cloudflare’s docs require both Workers AI Read and Workers AI Edit; with only one, calls to the models fail.
Check the key works
curl -s https://api.cloudflare.com/client/v4/user/tokens/verify \
-H "Authorization: Bearer $CF_API_TOKEN"
# {"result":{"id":"…","status":"active"},"success":true,"errors":[],
# "messages":[{"code":10000,"message":"This API Token is valid and active"}]}Use the /user/tokens/verify address. The token this form makes is a user token, so /accounts/<id>/tokens/verify answers Invalid API Token for it — even though it works for Workers AI.
Make an image
curl -s https://api.cloudflare.com/client/v4/accounts/$CF_ACCOUNT_ID/ai/run/@cf/black-forest-labs/flux-1-schnell \
-H "Authorization: Bearer $CF_API_TOKEN" \
-d '{ "prompt": "a red apple on a white table, soft daylight", "steps": 4 }' \
| jq -r .result.image | base64 --decode > apple.jpgThe response is JSON with the image as a base64 JPEG in result.image. The same call from Node 20 or later, with no packages:
// cf-image.mjs — run with: node --env-file=.env cf-image.mjs "a red apple on a white table"
import { writeFileSync } from 'node:fs';
const prompt = process.argv[2] ?? 'a red apple on a white table';
const url = `https://api.cloudflare.com/client/v4/accounts/${process.env.CF_ACCOUNT_ID}/ai/run/@cf/black-forest-labs/flux-1-schnell`;
const res = await fetch(url, {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.CF_API_TOKEN}` },
body: JSON.stringify({ prompt, steps: 4 }),
});
const data = await res.json();
if (!data.success) throw new Error(JSON.stringify(data.errors));
writeFileSync('image.jpg', Buffer.from(data.result.image, 'base64'));stepsgoes up to 8. Each extra step costs another 38.4 neurons at 1024 × 1024: 8 steps measured 326.4 neurons, about 30 images a day. Smaller images cost less — 512 × 512 is a single tile.@cf/black-forest-labs/flux-2-klein-4bis the newer FLUX.2 option. It takes multipart form data rather than JSON (curl -F prompt=… -F width=1024 -F height=1024), and its response does not report neurons, so check the usage graph before relying on it. Check its model card for the licence too.- The Leonardo models (
phoenix-1.0,lucid-origin) cost over 500 neurons per tile, so only a handful fit in the free allowance. - Not every model runs on the free plan. Some answer
Model … is not available on the Workers Free plan(error 5035); FLUX.1 [schnell] and FLUX.2 klein do run on it.
If it fails
| What you see | Why | Fix |
|---|---|---|
Model … is not available on the Workers Free plan (code 5035) | The model is paid-only | Use FLUX.1 [schnell], or move to Workers Paid |
prompt is required (code 3030) from flux-2-klein-4b | That model takes form data, not JSON | Send -F prompt=… instead of -d '{…}' |
| An authentication error | Wrong token, wrong account ID, or a permission missing | Run the verify call above; check both Read and Edit rows |
| Errors after a day of use | The 10,000 neurons are used up | Wait until 00:00 UTC; nothing is billed |
Source: Workers AI pricing and FLUX.1-schnell on Workers AI.
Hugging Face Spaces (ZeroGPU)
Many public demos on Hugging Face run on ZeroGPU, shared GPUs with a daily quota: 2 minutes without an account, 5 minutes with a free one, reset 24 hours after your first use. Black Forest Labs’ own FLUX.1-schnell Space can be called like an API. In my test a 1024 × 1024 image took about 4 seconds end to end, so five minutes is in the region of 75–100 images — fewer when the queue is busy.
Get a token (optional, raises 2 to 5 minutes)
- Create a free account at huggingface.co/join and verify your email.
- Open Settings → Access Tokens and select New token (or Create new token).
- Fill the form as below, create the token and copy it.
- Put it in your
.envasHF_TOKEN.
| Field in the form | What to put |
|---|---|
| Token type | Read. It is all that calling a Space needs. Never Write for this — a leaked write token can change your repositories. |
| Token name | What it is for, such as image-script. Hugging Face recommends one token per app or machine, so you can cancel one without breaking the others. |
For a production app, Hugging Face recommends a Fine-grained token instead, limited to exactly what the app needs.
Check the key works
curl -s https://huggingface.co/api/whoami-v2 -H "Authorization: Bearer $HF_TOKEN"
# a JSON description of your account, starting with your user nameA missing or wrong token answers {"error":"Invalid username or password."}.
Make an image
pip install gradio_client# hf_image.py — run with: python hf_image.py
import os, shutil
from gradio_client import Client
client = Client("black-forest-labs/FLUX.1-schnell", token=os.environ.get("HF_TOKEN"))
path, seed = client.predict(
prompt="a red apple on a white table, soft daylight",
seed=0,
randomize_seed=True,
width=1024,
height=1024,
num_inference_steps=4,
api_name="/infer",
)
shutil.copy(path, "apple.webp") # the Space returns a WebP in a temp folder
print("seed", seed)Without Python, it is two plain HTTP calls: one queues the job and returns an event_id, the second waits for the result and returns a URL to the image.
SPACE=https://black-forest-labs-flux-1-schnell.hf.space/gradio_api/call/infer
ID=$(curl -s -X POST $SPACE -H 'Content-Type: application/json' \
-d '{"data": ["a red apple on a white table", 0, true, 1024, 1024, 4]}' | jq -r .event_id)
curl -s -N $SPACE/$ID # ends with "event: complete" and the image URLIf it fails
| What you see | Why | Fix |
|---|---|---|
Invalid username or password. | Token missing or mistyped | Copy it again from Access Tokens; check HF_TOKEN is loaded |
| An error about your GPU quota | The day’s ZeroGPU minutes are used | Wait — the quota refills 24 hours after your first use that day |
| A long wait before the image | The Space’s queue is busy | Retry later, or duplicate the Space into your account |
| An error about the inputs | The Space’s author changed its form | Open …hf.space/gradio_api/info to see the current inputs |
A Space is a demo, not a service with an uptime promise: its author can change the inputs or take it down. For something you rely on, duplicate it into your own account — free accounts in good standing (verified email, older than 30 days) can host two ZeroGPU Spaces. Source: ZeroGPU documentation.
Pollinations
Pollinations puts dozens of image models behind one simple URL. Its current endpoint, gen.pollinations.ai, needs an API key: in my test on 20 October 2026 it served two images without one, then answered 401 — A valid API key is required. Usage is paid in Pollen. The hourly free refill ended in July 2026; free Pollen now comes from one-time quests in the dashboard. FLUX.1 [schnell] costs 0.002 Pollen an image, and Pollen sells at about $1 each — so even after the quests run out it is roughly $0.002 an image.
Get the key
- Go to enter.pollinations.ai and sign in with GitHub.
- Complete the quests on the dashboard and claim their Pollen — claiming is only possible there.
- Under Keys, create a secret key (
sk_…) with the settings below and copy it. - Put it in your
.envasPOLLINATIONS_KEY. A secret key belongs on a server only — never in a browser, an app or a repository.
| Key setting | What to choose |
|---|---|
| Name | What it is for, such as image-script. |
| Model permissions | Only what you use: the image category, or just black-forest-labs/flux.1-schnell. |
| Budget | A small Pollen cap, such as 1 — at 0.002 Pollen an image that is still 500 images. |
| Expiry | A few days for a test key; longer for one a server keeps using. |
| Spend only Quest Pollen | On. The key then stops when the free Pollen runs out instead of spending a paid balance. |
Check the key works
curl -s https://gen.pollinations.ai/account/key -H "Authorization: Bearer $POLLINATIONS_KEY" # valid? type, permissions
curl -s https://gen.pollinations.ai/account/balance -H "Authorization: Bearer $POLLINATIONS_KEY" # Pollen leftMake an image
curl -o apple.jpg -H "Authorization: Bearer $POLLINATIONS_KEY" \
"https://gen.pollinations.ai/image/a%20red%20apple%20on%20a%20white%20table?model=black-forest-labs%2Fflux.1-schnell&width=1024&height=1024"If it fails
| What you see | Why | Fix |
|---|---|---|
401 A valid API key is required or Authentication required | No key sent, or the key is wrong | Send Authorization: Bearer $POLLINATIONS_KEY; check it with /account/key |
| 402 Payment required | The account or the key’s budget is out of Pollen | Check /account/balance; claim more quests or raise the key’s budget |
| 429 or 503 | Too many requests, or the model is busy | Wait for the number of seconds in the Retry-After header |
The response is the image itself, not JSON. GET https://gen.pollinations.ai/image/models lists every model with its price and a paid_only flag — only models marked false can be paid with Quest Pollen. The old keyless endpoint, image.pollinations.ai/prompt/…, still answers, but in my test it returned the Sana model with a “pollinations.ai” logo in the corner — fine for a placeholder, not for a product. Source: Pollinations API docs.
Puter.js
Puter.js works the other way round: there is no key and no bill for you, because each visitor signs in with their own Puter account and their usage is charged to it (Puter calls this “user-pays”). That makes it the one option here that is safe to call straight from a static page. The cost is that every visitor sees a Puter sign-in, and Puter publishes no number for how much a free Puter account can generate.
<script src="https://js.puter.com/v2/"></script>
<script>
puter.ai
.txt2img('a red apple on a white table, soft daylight', { model: 'black-forest-labs/flux-schnell' })
.then((img) => document.body.appendChild(img));
</script>There is no key to create: add the script tag and call it. The first time a visitor triggers it, Puter asks them to sign in or create a free Puter account; after that their images are charged to that account. txt2img resolves to an <img> element. The model list includes FLUX, Imagen 4, Gemini and GPT image models; leave model out for the default. Source: Puter.js image generation.
Stability AI
A new account gets 25 free credits, once. A credit is $0.01; Stable Image Core costs 3 credits an image, so the free credits make 8 images (or 10 with SD 3.5 Flash at 2.5 credits). Enough to judge the models, not to run anything.
Get the key
- Create an account at platform.stability.ai and sign in.
- Open your account page and find API Keys. A key (
sk-…) is already there — there is no form to fill. Copy it. - Put it in your
.envasSTABILITY_API_KEY.
Check the key works
curl -s https://api.stability.ai/v1/user/balance -H "Authorization: Bearer $STABILITY_API_KEY"
# {"credits": …} — 25 on a new accountWithout the header it answers missing authorization header. Check the balance before a batch: each Stable Image Core image takes 3 credits, and the free 25 do not come back.
Make an image
curl -f -sS https://api.stability.ai/v2beta/stable-image/generate/core \
-H "Authorization: Bearer $STABILITY_API_KEY" \
-H "Accept: image/*" \
-F prompt="a red apple on a white table, soft daylight" \
-F output_format=webp \
-o apple.webpThe request is multipart form data, not JSON. Source: Stability AI pricing.
( Going further )
Keep the key on the server
Any key in front-end code can be copied from the browser and spent by someone else. Put the call in a server route and let the page talk to that. In Next.js, a route handler for Cloudflare:
// app/api/image/route.ts — the token never leaves the server
export async function POST(request: Request) {
const { prompt } = await request.json();
if (typeof prompt !== 'string' || !prompt.trim() || prompt.length > 500) {
return new Response('Bad prompt', { status: 400 });
}
const res = await fetch(
`https://api.cloudflare.com/client/v4/accounts/${process.env.CF_ACCOUNT_ID}/ai/run/@cf/black-forest-labs/flux-1-schnell`,
{
method: 'POST',
headers: { Authorization: `Bearer ${process.env.CF_API_TOKEN}` },
body: JSON.stringify({ prompt, steps: 4 }),
},
);
const data = await res.json();
if (!data.success) return new Response('Generation failed', { status: 502 });
return new Response(Buffer.from(data.result.image, 'base64'), {
headers: { 'Content-Type': 'image/jpeg' },
});
}The page then calls fetch('/api/image', { method: 'POST', body: JSON.stringify({ prompt }) }) and shows the result with URL.createObjectURL(await res.blob()). On a public site, add a per-visitor rate limit too — otherwise one visitor can use up the whole day’s allowance.
Not free, despite the claims
- Gemini API. Every image model shows “Not available” in the free-tier column. The cheapest, Nano Banana 2 Lite, is about $0.034 per 1K image. Making images in the Gemini app or AI Studio is a different product from the API. Source: Gemini API pricing.
- Together AI. No free image model is listed any more; FLUX.2 [dev] starts at $0.0154 an image. Source: Together pricing.
- Hugging Face Inference Providers. Free accounts get no monthly credits; PRO accounts get $2 a month. This is separate from the ZeroGPU Spaces above. Source: Inference Providers pricing.
- NVIDIA build.nvidia.com. It hands out a free trial key and hosts FLUX.1 [schnell], but publishes no quota, and developers reported days-long outages of its FLUX endpoints in October 2026. Fine for an experiment; do not build on it.
For no limits at all, run FLUX.1 [schnell] yourself with ComfyUI on a machine with a capable GPU — the model is free to download from Hugging Face.
( Questions )
Free image generation API FAQ
- Is there a free image generation API with no limits?
- Not a hosted one. The most dependable free allowance is Cloudflare Workers AI’s 10,000 neurons a day, about 57 FLUX.1 [schnell] images at 1024 × 1024. With no limit at all, you run the model on your own GPU.
- Does the Gemini API have a free tier for images?
- No. Google’s pricing page lists no free tier for any Gemini image model; the cheapest costs about $0.034 per image. The free Gemini app is a different product from the API.
- Can I use the images commercially?
- FLUX.1 [schnell] is released under Apache-2.0, which allows commercial use, so images from it on Cloudflare or Hugging Face are fine. For any other model, read its model card and the service’s terms.
- Can I call these APIs from the browser?
- Not with a secret key — anyone can copy it from the page. Call the API from a server route instead, or use Puter.js, which is built for the browser because each visitor pays for their own images.
- What happens when the free quota runs out?
- Cloudflare’s free plan returns errors until 00:00 UTC. Hugging Face refills 24 hours after your first use. A Pollinations key limited to Quest Pollen simply stops. None of them charges you unless you add paid credit.