/v1/responses or /v1/chat/completions: Which API to Use

Two OpenAI-compatible endpoints with different request and response shapes. On Zukko, Chat Completions works with every model, Responses with Claude and GPT.

4 min · · API keys · development

Responses API or Chat Completions is a question that comes up whenever a client or library asks you to pick an OpenAI "wire protocol". Zukko supports both: /v1/chat/completions works with every model, and /v1/responses works with Claude and GPT models. Here is how their requests and responses differ and which one to choose.

The two APIs in brief

Chat Completions (POST /v1/chat/completions) is OpenAI's long-standing standard: you send a messages array with roles and get choices[0].message.content back. Almost every OpenAI-compatible client supports it. The README of OpenAI's official Python SDK calls it the previous standard and says it is supported indefinitely.

Responses (POST /v1/responses) is OpenAI's newer API. Input goes into the input field (a string or an array of messages), the system instruction into a separate instructions field, and the answer comes back as an array of output items. The Python SDK offers a convenient response.output_text property with the final text.

Differences at a glance

Parameter/v1/chat/completions/v1/responses
Inputmessages with roleinput: a string or an array of messages
System instructiona message with role: systemthe instructions field
Answer length limitmax_tokensmax_output_tokens
Answer textchoices[0].message.contentoutput items; output_text in the SDK
Usage fieldsprompt_tokens, completion_tokensinput_tokens, output_tokens
Streamingchat.completion.chunk chunksevents such as response.output_text.delta
Models on Zukkoall: claude-*, gpt-*, glm-*claude-* and gpt-*, no GLM
Used byCursor, Cline, Kilo Code, LangChain and most OpenAI-compatible clientsCodex

Chat Completions: an example

bash
curl https://api.zukko.pro/v1/chat/completions \
  -H "Authorization: Bearer fetch_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-5",
    "messages": [
      {"role": "system", "content": "You are an experienced Python developer. Be brief."},
      {"role": "user", "content": "How do I read a JSON file?"}
    ],
    "max_tokens": 1000
  }'

Response (abridged):

bash
{
  "object": "chat.completion",
  "choices": [
    {
      "index": 0,
      "message": {"role": "assistant", "content": "Use the json module..."},
      "finish_reason": "stop"
    }
  ],
  "usage": {"prompt_tokens": 38, "completion_tokens": 120, "total_tokens": 158}
}

The same in Python:

bash
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.zukko.pro/v1",
    api_key=os.environ["OPENAI_API_KEY"],
)

response = client.chat.completions.create(
    model="glm-5.3-flash",
    messages=[
        {"role": "system", "content": "You are an experienced Python developer. Be brief."},
        {"role": "user", "content": "How do I read a JSON file?"},
    ],
    max_tokens=1000,
)
print(response.choices[0].message.content)

Streaming: on Zukko the last chunk carries usage and an empty choices, so check before accessing chunk.choices[0]:

bash
stream = client.chat.completions.create(
    model="claude-sonnet-5",
    messages=[{"role": "user", "content": "Explain Python generators"}],
    stream=True,
)
for chunk in stream:
    if chunk.choices and chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)

Responses: an example

bash
curl https://api.zukko.pro/v1/responses \
  -H "Authorization: Bearer fetch_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-5.6-luna",
    "instructions": "You are an experienced Python developer. Be brief.",
    "input": "How do I read a JSON file?",
    "max_output_tokens": 1000
  }'

Response (abridged):

bash
{
  "object": "response",
  "status": "completed",
  "output": [
    {
      "type": "message",
      "role": "assistant",
      "content": [{"type": "output_text", "text": "Use the json module..."}]
    }
  ],
  "usage": {"input_tokens": 38, "output_tokens": 120, "total_tokens": 158}
}

In Python with the official SDK (you need a version that has client.responses):

bash
response = client.responses.create(
    model="gpt-5.6-sol",
    instructions="You are an experienced Python developer. Be brief.",
    input="How do I read a JSON file?",
    max_output_tokens=1000,
)
print(response.output_text)
print(response.usage.input_tokens, response.usage.output_tokens)

A multi-turn conversation is passed as an array in input:

bash
response = client.responses.create(
    model="claude-sonnet-5",
    input=[
        {"role": "user", "content": "What is the capital of France?"},
        {"role": "assistant", "content": "Paris."},
        {"role": "user", "content": "Which river flows through it?"},
    ],
)
print(response.output_text)

Streaming in Responses is a stream of typed events; text arrives in response.output_text.delta events:

bash
stream = client.responses.create(
    model="gpt-5.6-luna",
    input="Explain Python generators",
    stream=True,
)
for event in stream:
    if event.type == "response.output_text.delta":
        print(event.delta, end="", flush=True)

On OpenAI's platform, Responses also has platform features: server-side conversation storage (store, previous_response_id) and built-in tools. Do not rely on them through the gateway: pass the history in input yourself, as above, and test any feature you need on your model.

Which models work with which endpoint

Model/v1/chat/completions/v1/responses
claude-opus-5-5yesyes
claude-sonnet-5yesyes
gpt-5.6-solyesyes
gpt-5.6-lunayesyes
glm-5.3yesno
glm-5.3-flashyesno

A request to a GLM model via /v1/responses fails with an error; use /v1/chat/completions for these models. The lineup changes: the current list is at GET https://api.zukko.pro/v1/models or on the "Models" page in the dashboard.

Codex: why only Responses

Codex is OpenAI's coding agent. In the Codex configuration reference, the provider setting wire_api accepts a single value, responses, which is also the default. So Codex talks to models only through the Responses API, and on Zukko it works with Claude and GPT models but not GLM. A ~/.codex/config.toml fragment:

bash
model = "gpt-5.6-sol"
model_provider = "zukko"

[model_providers.zukko]
name = "zukko"
base_url = "https://api.zukko.pro/v1"
wire_api = "responses"

How to pass the key and the remaining steps are in the Codex guide.

What to choose

  • Your own code from scratch, any model: /v1/chat/completions. It works with every model, GLM included, and with any OpenAI-compatible library.
  • A tool that requires Responses (Codex and similar): /v1/responses with a Claude or GPT model.
  • Code already written for Responses: keep it, unless you need GLM models.

Price does not depend on the endpoint: you pay for input and output tokens at the model's rate. More on the format is in the Chat Completions reference and the Python SDK guide. To try both APIs, create a key in the dashboard.

FAQ

I get a 404 on /responses. What is wrong?

Most often the base URL lacks /v1. The full address is https://api.zukko.pro/v1/responses; in the SDK set base_url="https://api.zukko.pro/v1" and it will append /responses itself.

I get 403 model_not_allowed_for_key. Is it the endpoint?

No. This code means the model is not in the key's list of allowed models. Add it in the key settings in the dashboard or use another key. The endpoint has nothing to do with it.

Does the price differ between endpoints?

No. Cost is based on input and output tokens and the model's price. The only difference is the usage field names: prompt_tokens/completion_tokens versus input_tokens/output_tokens.

Can I connect Codex to a GLM model?

No: Codex works only through the Responses API, and GLM models on Zukko are not available via /v1/responses. For Codex pick gpt-5.6-sol, gpt-5.6-luna, or a Claude model.

zukko

Pay 25×
less

for Claude Code & ChatGPT

One fetch_* key and base URL api.zukko.pro — for Cursor, Claude Code, Codex, and any SDK.

Get API keyDocumentation

api.zukko.pro · fetch_*

Responses API vs Chat Completions: What Is the Difference · Zukko