---
url: https://docs.freetheai.org/api/responses.md
description: >-
  POST /v1/responses - the OpenAI Responses format on FreeTheAI, used by Codex
  CLI and newer OpenAI SDK code. Parameters, examples, streaming events, and
  tools.
---

# Responses

Creates a model response in the OpenAI Responses format. Codex CLI and newer OpenAI SDK code use it. Every free model answers here, streamed or not, with tool calls.

`POST https://api.freetheai.org/v1/responses`

## Request

::: code-group

```bash [curl]
curl https://api.freetheai.org/v1/responses \
  -H "Authorization: Bearer $FTAI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "fta/zai/glm-5.3",
    "instructions": "Answer in one sentence.",
    "input": "Why is the sky blue?"
  }'
```

```python [Python]
import os
from openai import OpenAI

client = OpenAI(base_url="https://api.freetheai.org/v1", api_key=os.environ["FTAI_KEY"])

response = client.responses.create(
    model="fta/zai/glm-5.3",
    instructions="Answer in one sentence.",
    input="Why is the sky blue?",
)
print(response.output_text)
```

```ts [TypeScript]
import OpenAI from 'openai'

const client = new OpenAI({ baseURL: 'https://api.freetheai.org/v1', apiKey: process.env.FTAI_KEY })

const response = await client.responses.create({
  model: 'fta/zai/glm-5.3',
  instructions: 'Answer in one sentence.',
  input: 'Why is the sky blue?',
})
console.log(response.output_text)
```

:::

## Body parameters

| Parameter | Type | Description |
| --- | --- | --- |
| `model` | string, **required** | A model ID from [`GET /v1/models`](/api/models). |
| `input` | string or array | The input: a string, or a list of input items (messages with `input_text` and `input_image` content, or `function_call_output` items). |
| `instructions` | string | A system-style instruction for this response. |
| `stream` | boolean | Return server-sent events. Default `false`. |
| `max_output_tokens` | integer | The most tokens to generate. Send `0` to ask for the model's full output limit. |
| `temperature`, `top_p` | number | Sampling, where the model supports it. |
| `tools` | array | Function tools (`{"type": "function", "name": ..., "parameters": ...}`), or `{"type": "web_search"}` for the `fta/dog/` and `fta/lion/` models. |
| `tool_choice` | string or object | `auto`, `none`, `required`, or a specific function. |
| `reasoning` | object | For example `{"effort": "low"}`, where the model supports it. |

Other Responses fields are passed to the model when it supports them.

::: info Conversation state
Send the conversation in `input` each time. Server-side conversation storage (`previous_response_id` and `store`) is not something to rely on: FreeTheAI does not store prompts or replies.
:::

## Response

```json
{
  "id": "resp_7c1e...",
  "object": "response",
  "model": "fta/zai/glm-5.3",
  "output": [
    {
      "type": "message",
      "role": "assistant",
      "content": [
        { "type": "output_text", "text": "Air molecules scatter short blue wavelengths of sunlight more than long red ones." }
      ]
    }
  ],
  "usage": { "input_tokens": 22, "output_tokens": 17, "total_tokens": 39 }
}
```

| Field | Description |
| --- | --- |
| `output` | Output items: `message` items with `output_text` content, `function_call` items, and reasoning items for models that think. |
| `output_text` | SDK helper that joins the text of every `output_text` part. |
| `usage` | `input_tokens`, `output_tokens`, `total_tokens`. |

## Streaming

With `"stream": true`, the response is a stream of typed events: `response.created`, then `response.output_text.delta` events with the text, and `response.completed` with the full response and usage.

```python
stream = client.responses.create(model="fta/zai/glm-5.3", input="Tell me a joke.", stream=True)
for event in stream:
    if event.type == "response.output_text.delta":
        print(event.delta, end="", flush=True)
```

## Tool calls

```python
import json

tools = [{
    "type": "function",
    "name": "get_weather",
    "description": "Get the current weather for a city.",
    "parameters": {
        "type": "object",
        "properties": {"city": {"type": "string"}},
        "required": ["city"],
    },
}]

items = [{"role": "user", "content": "Weather in Oslo?"}]
response = client.responses.create(model="fta/zai/glm-5.3", input=items, tools=tools)

for item in response.output:
    if item.type == "function_call":
        args = json.loads(item.arguments)
        items.append(item.model_dump(exclude_none=True))
        items.append({
            "type": "function_call_output",
            "call_id": item.call_id,
            "output": json.dumps({"city": args["city"], "temperature_c": 6}),
        })

final = client.responses.create(model="fta/zai/glm-5.3", input=items, tools=tools)
print(final.output_text)
```

## Codex CLI

Codex uses this endpoint. A tested `config.toml` is in the [Codex CLI guide](/guides/codex).

## Errors

The same statuses as [Chat Completions](/api/chat-completions#errors). Every message: [Errors](/errors).
