Skip to content
View as Markdown

Chat Completions

Creates a reply to a conversation, in the OpenAI Chat Completions format. This is the endpoint most apps and SDKs use.

POSThttps://api.freetheai.org/v1/chat/completions

Request ​

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 ​

ParameterTypeDescription
modelstring, requiredA model ID from GET /v1/models, such as fta/zai/glm-5.3.
messagesarray, requiredThe conversation so far. Each message has a role (system, developer, user, assistant, or tool) and content. See Messages.
streambooleanReturn server-sent events while the reply is written. Default false. See Streaming.
stream_optionsobject{"include_usage": true} as in the OpenAI API. Usage is in the final chunk either way.
max_tokensintegerThe 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.
temperaturenumberSampling temperature. Some models use fixed values and ignore it.
top_pnumberNucleus sampling. Some models use fixed values and ignore it.
frequency_penalty, presence_penaltynumberRepetition penalties, where the model supports them.
stopstring or arrayText that ends the reply.
seedintegerBest-effort repeatable sampling, where supported.
toolsarrayFunctions the model may call. See Tool calls.
tool_choicestring or objectauto, none, required, or a specific function.
parallel_tool_callsbooleanAllow several tool calls in one turn, where supported.
response_formatobject{"type": "json_object"} or a JSON schema, where the model supports it.
thinkingobject{"type": "disabled"} turns a thinking model's reasoning off. See Thinking.
reasoning_effortstringnone turns reasoning off; other values follow the OpenAI meaning where the model supports them.
web_search_optionsobjectSend {} 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,..." } }
  ] }
]
  • content is a string, or an array of text and image_url parts for models that read images.
  • Include at least one user message. A request with only system or character messages answers 400 with the model needs at least one message from you in the request.
  • Assistant messages with tool_calls and tool messages with a tool_call_id carry 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
  }
}
FieldDescription
idThe completion ID.
objectchat.completion, or chat.completion.chunk for stream chunks.
modelThe model that answered.
choices[].message.contentThe reply text.
choices[].message.reasoning_contentThe model's reasoning, for models that think. Not part of the answer.
choices[].message.tool_callsFunction calls the model asks for.
choices[].message.annotationsurl_citation entries for the web sources a search used.
choices[].finish_reasonstop, length (hit max_tokens), tool_calls, or content_filter.
usageToken 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 ​

StatusCommon causes
400Invalid 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.
401Missing, incomplete, or revoked key.
403No check-in today, email not confirmed, the key's model or IP list, or an account hold.
404Unknown model ID.
413Body over 8 MB.
429A reply is still running, or a daily or window limit was reached.
502The model failed this time, or the stream broke.
503The model is busy or paused.

Every message and its fix: Errors.

FreeTheAI documentation. Paid models and plans are coming soon; the free tier has daily limits.