Images
Generates images from a prompt. Image models run as tasks, so a slow model never runs into a request time limit: create the task, poll it, and read the images when it completes. Paid image models from providers are priced per image; see freetheai.org/models.
https://api.freetheai.org/v1/images/generationsCreate the task
curl https://api.freetheai.org/v1/images/generations \
-H "Authorization: Bearer $FTAI_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "MODEL_ID", "prompt": "A lighthouse at dawn, watercolor", "n": 1}'import base64, os, time
import requests
base = "https://api.freetheai.org/v1"
headers = {"Authorization": f"Bearer {os.environ['FTAI_KEY']}"}
task = requests.post(f"{base}/images/generations", headers=headers,
json={"model": "MODEL_ID", "prompt": "A lighthouse at dawn, watercolor", "n": 1}).json()
while task["status"] in ("queued", "in_progress"):
time.sleep(3)
task = requests.get(f"{base}/images/generations/{task['id']}", headers=headers).json()
for index, image in enumerate(task.get("data", [])):
with open(f"image-{index}.png", "wb") as out:
out.write(base64.b64decode(image["b64_json"]))import { writeFile } from 'node:fs/promises'
const base = 'https://api.freetheai.org/v1'
const headers = { 'Authorization': `Bearer ${process.env.FTAI_KEY}`, 'Content-Type': 'application/json' }
let task = await (await fetch(`${base}/images/generations`, {
method: 'POST', headers, body: JSON.stringify({ model: 'MODEL_ID', prompt: 'A lighthouse at dawn, watercolor', n: 1 }),
})).json()
while (task.status === 'queued' || task.status === 'in_progress') {
await new Promise(resolve => setTimeout(resolve, 3000))
task = await (await fetch(`${base}/images/generations/${task.id}`, { headers })).json()
}
for (const [index, image] of (task.data ?? []).entries()) {
await writeFile(`image-${index}.png`, Buffer.from(image.b64_json, 'base64'))
}| Field | Type | Description |
|---|---|---|
model | string | An image model ID from GET /v1/models ("type": "image"). |
prompt | string | What to draw. |
n | integer | Optional. How many images (default 1). |
size | string | Optional. For example 1024x1024, when the model supports it. |
response_format | string | Optional. b64_json (default) or url (links on the FreeTheAI API). |
The create call answers at once with the task:
{
"id": "task_...",
"object": "image.generation",
"status": "queued",
"progress": 0,
"poll_url": "/v1/images/generations/task_..."
}Get the images
Poll GET /v1/images/generations/{id} every few seconds. status moves from queued to in_progress to completed or failed. A completed task carries data: [{ "b64_json": "..." }], or [{ "url": "..." }] with "response_format": "url". A failed one carries error with a code and a message.
Images from provider models are kept for one read, or one hour if never read: save them the first time. A second read answers 410.
You are charged for the images you receive, never more than n. The request first holds the price of n images on your wallet; a failed or expired task costs nothing.
Errors
| Status | Meaning |
|---|---|
400 | A field has a value the endpoint does not take (the message names it). |
401 | Missing or invalid API key. |
402 | Not enough wallet balance, or the key's budget is used (paid usage errors). |
404 | No model has that ID, none of the providers you follow serve it, or the task ID is not yours. |
410 | these images were already fetched or have expired. Images are handed out once. |
503 | The provider is busy. Retry; nothing is charged. |

