Contents
FreeTheAI Gateway API
One marketplace gateway with OpenAI Chat Completions, OpenAI Responses, and Anthropic Messages wire formats. Authenticate with an API key created in the console; the routing rule on the key selects a provider per request. Use the exact model IDs from GET /v1/models: free FreeTheAI models are named fta/<provider>/<model> and need a verified email and the daily check-in on the website. Streaming responses include token usage in the final chunk.
- Base URL
https://api.freetheai.org- Authentication
Authorization: Bearer <key>- Create a key in the console. Each key carries its own routing rule, spend limit, and wallet.
Machine-readable specification: /openapi.jsonVersion 1.0.0
Inference
OpenAI Chat Completions, OpenAI Responses, and Anthropic Messages.
POST/v1/chat/completionsCreate a chat completion
Routes the OpenAI Chat Completions wire format to the provider selected by the API key.
Request body
OpenAI Chat Completions request. Unknown OpenAI-compatible fields are forwarded when supported by the selected route.
max_tokensinteger (int64)Maximum generated tokens when supported.messagesarray of objectRequiredConversation messages.modelstringRequiredModel id from GET /v1/models.streambooleanReturn server-sent events when true.
Responses
- 200
Successful provider response.
choicesarray of objectidstringmodelstringobjectstringusageobject
- 400
The request body is invalid, uses a parameter the model does not support, or calls an endpoint the model does not serve. When the provider itself refused the request, the error carries an error ID (in error.error_id and the X-Error-ID header). A refusal by the model's content filter has error.type "invalid_request_error" and error.code "content_filter".
errorobject
- 401
The API key is missing, malformed, revoked, or expired.
errorobject
- 402
Your wallet balance cannot cover this paid route.
errorobject
- 403
The request is not allowed: your email is not verified, free models need today's check-in, your account is on hold, your key does not allow this model, provider, or IP address, your network or client is blocked, or the request was relayed through a Cloudflare Worker (call the API directly).
errorobject
- 404
The model does not exist or has no available route. The error has error.type "invalid_request_error" and error.code "model_not_found", and the message names the model you sent.
errorobject
- 413
The request body is larger than the gateway accepts (8 MB, images included).
errorobject
- 429
A rate limit, concurrency limit, or your daily free request limit was reached.
errorobject
- 502
The upstream provider failed, or the stream broke after it started. The error ID (such as freetheai-1a2b3c4d5e6f) is at the end of the message, in error.error_id, and in the X-Error-ID header; a broken stream ends with an error event that carries it.
errorobject
- 503
The model is at capacity or the service is temporarily unavailable.
errorobject
POST/v1/responsesCreate a model response
Routes the OpenAI Responses wire format to the provider selected by the API key.
Request body
OpenAI Responses request. Unknown Responses fields are forwarded when supported by the selected route.
inputobjectString or structured Responses input.instructionsstringmodelstringRequiredModel id from GET /v1/models.streambooleanReturn server-sent events when true.
Responses
- 200
Successful provider response.
idstringmodelstringobjectstringoutputarray of objectusageobject
- 400
The request body is invalid, uses a parameter the model does not support, or calls an endpoint the model does not serve. When the provider itself refused the request, the error carries an error ID (in error.error_id and the X-Error-ID header). A refusal by the model's content filter has error.type "invalid_request_error" and error.code "content_filter".
errorobject
- 401
The API key is missing, malformed, revoked, or expired.
errorobject
- 402
Your wallet balance cannot cover this paid route.
errorobject
- 403
The request is not allowed: your email is not verified, free models need today's check-in, your account is on hold, your key does not allow this model, provider, or IP address, your network or client is blocked, or the request was relayed through a Cloudflare Worker (call the API directly).
errorobject
- 404
The model does not exist or has no available route. The error has error.type "invalid_request_error" and error.code "model_not_found", and the message names the model you sent.
errorobject
- 413
The request body is larger than the gateway accepts (8 MB, images included).
errorobject
- 429
A rate limit, concurrency limit, or your daily free request limit was reached.
errorobject
- 502
The upstream provider failed, or the stream broke after it started. The error ID (such as freetheai-1a2b3c4d5e6f) is at the end of the message, in error.error_id, and in the X-Error-ID header; a broken stream ends with an error event that carries it.
errorobject
- 503
The model is at capacity or the service is temporarily unavailable.
errorobject
POST/v1/messagesCreate an Anthropic message
Routes the Anthropic Messages wire format to the provider selected by the API key. Send the Anthropic version header required by your client.
Request body
Anthropic Messages request. Unknown Anthropic-compatible fields are forwarded when supported by the selected route.
max_tokensinteger (int64)RequiredMaximum generated tokens.messagesarray of objectRequiredAnthropic-format conversation messages.modelstringRequiredModel id from GET /v1/models.streambooleanReturn Anthropic server-sent events when true.systemobjectSystem prompt as a string or Anthropic content blocks.
Responses
- 200
Successful provider response.
contentarray of objectidstringmodelstringrolestringstop_reasonstringtypestringusageobject
- 400
The request body is invalid, uses a parameter the model does not support, or calls an endpoint the model does not serve. When the provider itself refused the request, the error carries an error ID (in error.error_id and the X-Error-ID header). A refusal by the model's content filter has error.type "invalid_request_error" and error.code "content_filter".
errorobject
- 401
The API key is missing, malformed, revoked, or expired.
errorobject
- 402
Your wallet balance cannot cover this paid route.
errorobject
- 403
The request is not allowed: your email is not verified, free models need today's check-in, your account is on hold, your key does not allow this model, provider, or IP address, your network or client is blocked, or the request was relayed through a Cloudflare Worker (call the API directly).
errorobject
- 404
The model does not exist or has no available route. The error has error.type "invalid_request_error" and error.code "model_not_found", and the message names the model you sent.
errorobject
- 413
The request body is larger than the gateway accepts (8 MB, images included).
errorobject
- 429
A rate limit, concurrency limit, or your daily free request limit was reached.
errorobject
- 502
The upstream provider failed, or the stream broke after it started. The error ID (such as freetheai-1a2b3c4d5e6f) is at the end of the message, in error.error_id, and in the X-Error-ID header; a broken stream ends with an error event that carries it.
errorobject
- 503
The model is at capacity or the service is temporarily unavailable.
errorobject
Media tasks
Video and image generation run as tasks. Create one, keep the returned id, and poll it every few seconds until status is completed or failed, then download the result from its content URL with the same API key. A task uses one free request: it counts when the task completes and is given back if it fails or times out. Each account can have a few tasks queued or running at once. Results are the files themselves (images inline as b64_json, video as the MP4 from its content URL), fetched when you ask for them and never stored by FreeTheAI; finished tasks stay listed for 7 days.
POST/v1/images/generationsCreate an image task
Starts an image generation task. Returns the task right away with status queued; poll GET /v1/images/generations/{id}. When it completes, data holds each image as b64_json (or a FreeTheAI download URL with response_format url).
Request body
Image task request.
imagestringOptional source image: an https URL or a base64 data URL (PNG, JPEG, or WebP).modelstringRequiredAn image model id from GET /v1/models.nintegerHow many images, 1-4 (default 1).promptstringRequiredWhat to draw (at most 7000 characters).response_formatstringb64_json (default): a completed task returns each image's bytes inline. url: it returns FreeTheAI download URLs, fetched with your API key.sizestringOutput size as WIDTHxHEIGHT.
Responses
- 200
The task was created; poll it with its id.
completed_atinteger (int64)- Unix seconds, once final.content_urlstring- Video download URL, once completed.created_atinteger (int64)- Unix seconds.dataarray of MediaTaskOutput- Images, once completed: b64_json with the image bytes, or url when the task asked for response_format url.errorMediaTaskErrorexpires_atinteger (int64)- Unix seconds after which an unfinished task is stopped.idstring- Task id (task_...).kindstring- video or image.modelstringobjectstring- video or image.generation.poll_urlstring- Path to poll this task.progressinteger- 0-100 while the provider reports progress.secondsstring- Video duration.sizestring- Video size.statusstring- queued, in_progress, completed, or failed.
- 400
The request is invalid, or the model does not generate this kind of output. A provider refusal carries an error id.
errorobject
- 401
The API key is missing, malformed, revoked, or expired.
errorobject
- 403
Not allowed: unverified email, missing daily check-in for free models, an account hold, or a key that does not allow this model or IP address.
errorobject
- 404
The model does not exist.
errorobject
- 413
The request (with its image) is larger than the gateway accepts.
errorobject
- 429
Too many tasks queued or running for your account, or your daily free request limit was reached.
errorobject
- 502
The provider failed to start the task; the message ends with an error id.
errorobject
- 503
Tasks are temporarily unavailable or the model is busy; retry later.
errorobject
GET/v1/images/generations/{id}Get an image task
Status of one image task. When status is completed, data holds the images.
Responses
- 200
The task.
completed_atinteger (int64)- Unix seconds, once final.content_urlstring- Video download URL, once completed.created_atinteger (int64)- Unix seconds.dataarray of MediaTaskOutput- Images, once completed: b64_json with the image bytes, or url when the task asked for response_format url.errorMediaTaskErrorexpires_atinteger (int64)- Unix seconds after which an unfinished task is stopped.idstring- Task id (task_...).kindstring- video or image.modelstringobjectstring- video or image.generation.poll_urlstring- Path to poll this task.progressinteger- 0-100 while the provider reports progress.secondsstring- Video duration.sizestring- Video size.statusstring- queued, in_progress, completed, or failed.
- 401
The API key is missing, malformed, revoked, or expired.
errorobject
- 403
Not allowed: unverified email, missing daily check-in for free models, an account hold, or a key that does not allow this model or IP address.
errorobject
- 404
No task with this id belongs to your account.
errorobject
- 503
Tasks are temporarily unavailable or the model is busy; retry later.
errorobject
GET/v1/images/generations/{id}/contentDownload a finished image
Streams one finished image; pick it with index. Send the same API key that created the task.
Responses
- 200
The output file.
- 401
The API key is missing, malformed, revoked, or expired.
errorobject
- 403
Not allowed: unverified email, missing daily check-in for free models, an account hold, or a key that does not allow this model or IP address.
errorobject
- 404
No such task or output for your account.
errorobject
- 409
The task has not completed yet; keep polling.
errorobject
- 502
The output could not be fetched; retry.
errorobject
- 503
Tasks are temporarily unavailable or the model is busy; retry later.
errorobject
GET/v1/tasksList all your tasks
Every task on your account (video and image), newest first.
Responses
- 200
Your tasks, newest first.
dataarray of MediaTaskobjectstring
- 401
The API key is missing, malformed, revoked, or expired.
errorobject
- 403
Not allowed: unverified email, missing daily check-in for free models, an account hold, or a key that does not allow this model or IP address.
errorobject
- 503
Tasks are temporarily unavailable or the model is busy; retry later.
errorobject
GET/v1/tasks/{id}Get any task
One task of any kind, by id.
Responses
- 200
The task.
completed_atinteger (int64)- Unix seconds, once final.content_urlstring- Video download URL, once completed.created_atinteger (int64)- Unix seconds.dataarray of MediaTaskOutput- Images, once completed: b64_json with the image bytes, or url when the task asked for response_format url.errorMediaTaskErrorexpires_atinteger (int64)- Unix seconds after which an unfinished task is stopped.idstring- Task id (task_...).kindstring- video or image.modelstringobjectstring- video or image.generation.poll_urlstring- Path to poll this task.progressinteger- 0-100 while the provider reports progress.secondsstring- Video duration.sizestring- Video size.statusstring- queued, in_progress, completed, or failed.
- 401
The API key is missing, malformed, revoked, or expired.
errorobject
- 403
Not allowed: unverified email, missing daily check-in for free models, an account hold, or a key that does not allow this model or IP address.
errorobject
- 404
No task with this id belongs to your account.
errorobject
- 503
Tasks are temporarily unavailable or the model is busy; retry later.
errorobject
GET/v1/tasks/{id}/contentDownload any task's output
Streams a finished output of any task; index picks the output when there are several.
Responses
- 200
The output file.
- 401
The API key is missing, malformed, revoked, or expired.
errorobject
- 403
Not allowed: unverified email, missing daily check-in for free models, an account hold, or a key that does not allow this model or IP address.
errorobject
- 404
No such task or output for your account.
errorobject
- 409
The task has not completed yet; keep polling.
errorobject
- 502
The output could not be fetched; retry.
errorobject
- 503
Tasks are temporarily unavailable or the model is busy; retry later.
errorobject
GET/v1/videosList your video tasks
Your video tasks, newest first.
Responses
- 200
Your tasks, newest first.
dataarray of MediaTaskobjectstring
- 401
The API key is missing, malformed, revoked, or expired.
errorobject
- 403
Not allowed: unverified email, missing daily check-in for free models, an account hold, or a key that does not allow this model or IP address.
errorobject
- 503
Tasks are temporarily unavailable or the model is busy; retry later.
errorobject
POST/v1/videosCreate a video task
Starts a video generation task, in the shape of the OpenAI Videos API. Send JSON, or multipart/form-data with the first frame as an input_reference file. Returns the task right away with status queued; poll GET /v1/videos/{id}.
Request body
Video task request (OpenAI Videos API shape). Which durations and sizes a model accepts is shown on its model page.
input_referencestringFirst frame: an https image URL or a base64 data URL (PNG, JPEG, or WebP), or a file in multipart requests. Also accepted as image.modelstringRequiredA video model id from GET /v1/models.promptstringWhat should happen in the video (at most 7000 characters).secondsstringDuration in seconds, as a string or a number.sizestringOutput size as WIDTHxHEIGHT.
Responses
- 200
The task was created; poll it with its id.
completed_atinteger (int64)- Unix seconds, once final.content_urlstring- Video download URL, once completed.created_atinteger (int64)- Unix seconds.dataarray of MediaTaskOutput- Images, once completed: b64_json with the image bytes, or url when the task asked for response_format url.errorMediaTaskErrorexpires_atinteger (int64)- Unix seconds after which an unfinished task is stopped.idstring- Task id (task_...).kindstring- video or image.modelstringobjectstring- video or image.generation.poll_urlstring- Path to poll this task.progressinteger- 0-100 while the provider reports progress.secondsstring- Video duration.sizestring- Video size.statusstring- queued, in_progress, completed, or failed.
- 400
The request is invalid, or the model does not generate this kind of output. A provider refusal carries an error id.
errorobject
- 401
The API key is missing, malformed, revoked, or expired.
errorobject
- 403
Not allowed: unverified email, missing daily check-in for free models, an account hold, or a key that does not allow this model or IP address.
errorobject
- 404
The model does not exist.
errorobject
- 413
The request (with its image) is larger than the gateway accepts.
errorobject
- 429
Too many tasks queued or running for your account, or your daily free request limit was reached.
errorobject
- 502
The provider failed to start the task; the message ends with an error id.
errorobject
- 503
Tasks are temporarily unavailable or the model is busy; retry later.
errorobject
GET/v1/videos/{id}Get a video task
Status and progress of one video task. Poll every few seconds; when status is completed, content_url points at the MP4.
Responses
- 200
The task.
completed_atinteger (int64)- Unix seconds, once final.content_urlstring- Video download URL, once completed.created_atinteger (int64)- Unix seconds.dataarray of MediaTaskOutput- Images, once completed: b64_json with the image bytes, or url when the task asked for response_format url.errorMediaTaskErrorexpires_atinteger (int64)- Unix seconds after which an unfinished task is stopped.idstring- Task id (task_...).kindstring- video or image.modelstringobjectstring- video or image.generation.poll_urlstring- Path to poll this task.progressinteger- 0-100 while the provider reports progress.secondsstring- Video duration.sizestring- Video size.statusstring- queued, in_progress, completed, or failed.
- 401
The API key is missing, malformed, revoked, or expired.
errorobject
- 403
Not allowed: unverified email, missing daily check-in for free models, an account hold, or a key that does not allow this model or IP address.
errorobject
- 404
No task with this id belongs to your account.
errorobject
- 503
Tasks are temporarily unavailable or the model is busy; retry later.
errorobject
GET/v1/videos/{id}/contentDownload a finished video
Streams the finished MP4. Send the same API key that created the task.
Responses
- 200
The output file.
- 401
The API key is missing, malformed, revoked, or expired.
errorobject
- 403
Not allowed: unverified email, missing daily check-in for free models, an account hold, or a key that does not allow this model or IP address.
errorobject
- 404
No such task or output for your account.
errorobject
- 409
The task has not completed yet; keep polling.
errorobject
- 502
The output could not be fetched; retry.
errorobject
- 503
Tasks are temporarily unavailable or the model is busy; retry later.
errorobject
Models
Model discovery.
GET/v1/modelsList available models
Returns first-party and marketplace models the calling key may reach. Per-key allowlists filter this listing; group and scope limits stay enforced at dispatch.
Responses
- 200
Model list.
dataarray of Modelobjectstring
- 401
Missing or invalid API key.
errorobject
Service
Health and status.
GET/v1/healthNo authService health
Responses
- 200
Service is reachable.
statusstring
Errors
Every error returns the same JSON shape and a generic message; upstream details are never shown. When an upstream provider fails, the message ends with an error ID that Support can look up.
{"error": {"message": "Rate or concurrency limit reached.", "type": "gateway_error"}}| Status | Meaning | What to do |
|---|---|---|
| 400 | The request body is invalid, uses a parameter the model does not support, or calls an endpoint the model does not serve. When the provider itself refused the request, the error carries an error ID (in error.error_id and the X-Error-ID header). A refusal by the model's content filter has error.type "invalid_request_error" and error.code "content_filter". | Fix the request. Check the model's endpoint and parameters on its model page. For content_filter, rephrase the request or use another model. |
| 401 | The API key is missing, malformed, revoked, or expired. | Send Authorization: Bearer <key> with an active key from the API keys page. |
| 402 | Your wallet balance cannot cover this paid route. | Add funds to your wallet, or use a free model. |
| 403 | The request is not allowed: your email is not verified, free models need today's check-in, your account is on hold, your key does not allow this model, provider, or IP address, your network or client is blocked, or the request was relayed through a Cloudflare Worker (call the API directly). | Verify your email, complete the daily check-in on the website, check the key's restrictions, or open a Support ticket if your account is on hold. |
| 404 | The model does not exist or has no available route. The error has error.type "invalid_request_error" and error.code "model_not_found", and the message names the model you sent. | List models with GET /v1/models and use an exact model ID, such as fta/zai/glm-5.3. |
| 413 | The request body is larger than the gateway accepts (8 MB, images included). | Shorten the chat history or lower your app's context size, and send fewer or smaller images. |
| 429 | A rate limit, concurrency limit, or your daily free request limit was reached. | Wait and retry. Your plan page shows your limits and when the daily count resets. |
| 502 | The upstream provider failed, or the stream broke after it started. The error ID (such as freetheai-1a2b3c4d5e6f) is at the end of the message, in error.error_id, and in the X-Error-ID header; a broken stream ends with an error event that carries it. | Retry, or try another model. If it keeps happening, send the error ID to Support. |
| 503 | The model is at capacity or the service is temporarily unavailable. | Retry with exponential backoff. |