Chat Completions
Creates a reply to a conversation, in the OpenAI Chat Completions format. This is the endpoint most apps and SDKs use.
POST
https://api.freetheai.org/v1/chat/completionsRequest
bash
curl https://api.freetheai.org/v1/chat/completions \
-H "Authorization: Bearer $FTAI_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "fta/zai/glm-5.3",
"messages": [
{"role": "system", "content": "You are a concise assistant."},
{"role": "user", "content": "Name three uses for a paperclip."}
],
"max_tokens": 300,
"temperature": 0.7
}'python
import os
from openai import OpenAI
client = OpenAI(base_url="https://api.freetheai.org/v1", api_key=os.environ["FTAI_KEY"])
reply = client.chat.completions.create(
model="fta/zai/glm-5.3",
messages=[
{"role": "system", "content": "You are a concise assistant."},
{"role": "user", "content": "Name three uses for a paperclip."},
],
max_tokens=300,
temperature=0.7,
)
print(reply.choices[0].message.content)ts
import OpenAI from 'openai'
const client = new OpenAI({ baseURL: 'https://api.freetheai.org/v1', apiKey: process.env.FTAI_KEY })
const reply = await client.chat.completions.create({
model: 'fta/zai/glm-5.3',
messages: [
{ role: 'system', content: 'You are a concise assistant.' },
{ role: 'user', content: 'Name three uses for a paperclip.' },
],
max_tokens: 300,
temperature: 0.7,
})
console.log(reply.choices[0].message.content)js
const response = await fetch('https://api.freetheai.org/v1/chat/completions', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.FTAI_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'fta/zai/glm-5.3',
messages: [
{ role: 'system', content: 'You are a concise assistant.' },
{ role: 'user', content: 'Name three uses for a paperclip.' },
],
max_tokens: 300,
}),
})
const data = await response.json()
if (!response.ok) throw new Error(data.error?.message ?? response.statusText)
console.log(data.choices[0].message.content)Body parameters
| Parameter | Type | Description |
|---|---|---|
model | string, required | A model ID from GET /v1/models, such as fta/zai/glm-5.3. |
messages | array, required | The conversation so far. Each message has a role (system, developer, user, assistant, or tool) and content. See Messages. |
stream | boolean | Return server-sent events while the reply is written. Default false. See Streaming. |
stream_options | object | {"include_usage": true} as in the OpenAI API. Usage is in the final chunk either way. |
max_tokens | integer | The most tokens to generate, when the model supports it. max_completion_tokens is accepted too. Send 0 to ask for the model's full output limit. |
temperature | number | Sampling temperature. Some models use fixed values and ignore it. |
top_p | number | Nucleus sampling. Some models use fixed values and ignore it. |
frequency_penalty, presence_penalty | number | Repetition penalties, where the model supports them. |
stop | string or array | Text that ends the reply. |
seed | integer | Best-effort repeatable sampling, where supported. |
tools | array | Functions the model may call. See Tool calls. |
tool_choice | string or object | auto, none, required, or a specific function. |
parallel_tool_calls | boolean | Allow several tool calls in one turn, where supported. |
response_format | object | {"type": "json_object"} or a JSON schema, where the model supports it. |
thinking | object | {"type": "disabled"} turns a thinking model's reasoning off. See Thinking. |
reasoning_effort | string | none turns reasoning off; other values follow the OpenAI meaning where the model supports them. |
web_search_options | object | Send {} to let fta/dog/ and fta/lion/ models search the web first. Sources come back as url_citation annotations. See Web search. |
Other OpenAI-compatible fields are passed to the model when it supports them. A value the model refuses answers 400 with the model rejected one of the request's settings.
Messages
json
[
{ "role": "system", "content": "You are a helpful assistant." },
{ "role": "user", "content": "Hi!" },
{ "role": "assistant", "content": "Hello! How can I help?" },
{ "role": "user", "content": [
{ "type": "text", "text": "What is in this picture?" },
{ "type": "image_url", "image_url": { "url": "data:image/png;base64,..." } }
] }
]contentis a string, or an array oftextandimage_urlparts for models that read images.- Include at least one
usermessage. A request with only system or character messages answers400withthe model needs at least one message from you in the request. - Assistant messages with
tool_callsandtoolmessages with atool_call_idcarry tool calls.
Response
json
{
"id": "chatcmpl-8f3a...",
"object": "chat.completion",
"created": 1793145600,
"model": "fta/zai/glm-5.3",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "1. Holding papers together\n2. Resetting small devices\n3. A makeshift hook"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 27,
"completion_tokens": 21,
"total_tokens": 48
}
}| Field | Description |
|---|---|
id | The completion ID. |
object | chat.completion, or chat.completion.chunk for stream chunks. |
model | The model that answered. |
choices[].message.content | The reply text. |
choices[].message.reasoning_content | The model's reasoning, for models that think. Not part of the answer. |
choices[].message.tool_calls | Function calls the model asks for. |
choices[].message.annotations | url_citation entries for the web sources a search used. |
choices[].finish_reason | stop, length (hit max_tokens), tool_calls, or content_filter. |
usage | Token counts: prompt_tokens, completion_tokens, total_tokens, and details where the model reports them. |
With "stream": true the response is a stream of chat.completion.chunk events ending with data: [DONE]; see Streaming.
Errors
| Status | Common causes |
|---|---|
400 | Invalid JSON, missing model, images sent to a text-only model, a refused setting, no user message, a chat longer than the model's context, or the model's content filter. |
401 | Missing, incomplete, or revoked key. |
403 | No check-in today, email not confirmed, the key's model or IP list, or an account hold. |
404 | Unknown model ID. |
413 | Body over 8 MB. |
429 | A reply is still running, or a daily or window limit was reached. |
502 | The model failed this time, or the stream broke. |
503 | The model is busy or paused. |
Every message and its fix: Errors.

