/v1/responses или /v1/chat/completions: какой API использовать

Два OpenAI-совместимых эндпоинта с разной формой запроса и ответа. В Zukko Chat Completions работает со всеми моделями, Responses — с Claude и GPT.

4 мин · · API-ключи · разработка

Responses API или Chat Completions — вопрос, который возникает, когда клиент или библиотека предлагает выбрать «протокол» OpenAI. Оба эндпоинта есть в Zukko: /v1/chat/completions работает со всеми моделями, /v1/responses — с моделями Claude и GPT. Разбираем, чем они отличаются по форме запроса и ответа и какой выбрать.

Коротко о двух API

Chat Completions (POST /v1/chat/completions) — исторический стандарт OpenAI: вы отправляете массив messages с ролями, получаете choices[0].message.content. Этот формат поддерживает почти любой OpenAI-совместимый клиент. В README официального Python SDK OpenAI он назван прежним стандартом, поддержка которого сохраняется бессрочно.

Responses (POST /v1/responses) — более новый API OpenAI. Вход передаётся в поле input (строкой или массивом сообщений), системная инструкция — отдельным полем instructions, а ответ приходит как массив элементов output. Python SDK даёт удобное свойство response.output_text с итоговым текстом.

Таблица различий

Параметр/v1/chat/completions/v1/responses
Входmessages с roleinput: строка или массив сообщений
Системная инструкциясообщение с role: systemполе instructions
Лимит длины ответаmax_tokensmax_output_tokens
Текст ответаchoices[0].message.contentэлементы output; в SDK — output_text
Поля usageprompt_tokens, completion_tokensinput_tokens, output_tokens
Стримингчанки chat.completion.chunkсобытия вида response.output_text.delta
Модели в Zukkoвсе: claude-*, gpt-*, glm-*claude-* и gpt-*, без GLM
Кто используетCursor, Cline, Kilo Code, LangChain и большинство OpenAI-совместимых клиентовCodex

Chat Completions: пример

bash
curl https://api.zukko.pro/v1/chat/completions \
  -H "Authorization: Bearer fetch_ваш_ключ" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-5",
    "messages": [
      {"role": "system", "content": "Ты опытный Python-разработчик. Отвечай кратко."},
      {"role": "user", "content": "Как прочитать JSON-файл?"}
    ],
    "max_tokens": 1000
  }'

Ответ (сокращённо):

bash
{
  "object": "chat.completion",
  "choices": [
    {
      "index": 0,
      "message": {"role": "assistant", "content": "Используйте модуль json..."},
      "finish_reason": "stop"
    }
  ],
  "usage": {"prompt_tokens": 38, "completion_tokens": 120, "total_tokens": 158}
}

То же на 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": "Ты опытный Python-разработчик. Отвечай кратко."},
        {"role": "user", "content": "Как прочитать JSON-файл?"},
    ],
    max_tokens=1000,
)
print(response.choices[0].message.content)

Стриминг: в Zukko последний чанк приходит с usage и пустым choices, поэтому перед chunk.choices[0] нужна проверка:

bash
stream = client.chat.completions.create(
    model="claude-sonnet-5",
    messages=[{"role": "user", "content": "Расскажи про генераторы в Python"}],
    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: пример

bash
curl https://api.zukko.pro/v1/responses \
  -H "Authorization: Bearer fetch_ваш_ключ" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-5.6-luna",
    "instructions": "Ты опытный Python-разработчик. Отвечай кратко.",
    "input": "Как прочитать JSON-файл?",
    "max_output_tokens": 1000
  }'

Ответ (сокращённо):

bash
{
  "object": "response",
  "status": "completed",
  "output": [
    {
      "type": "message",
      "role": "assistant",
      "content": [{"type": "output_text", "text": "Используйте модуль json..."}]
    }
  ],
  "usage": {"input_tokens": 38, "output_tokens": 120, "total_tokens": 158}
}

На Python с официальным SDK (нужна версия, в которой есть client.responses):

bash
response = client.responses.create(
    model="gpt-5.6-sol",
    instructions="Ты опытный Python-разработчик. Отвечай кратко.",
    input="Как прочитать JSON-файл?",
    max_output_tokens=1000,
)
print(response.output_text)
print(response.usage.input_tokens, response.usage.output_tokens)

Диалог из нескольких реплик передаётся массивом в input:

bash
response = client.responses.create(
    model="claude-sonnet-5",
    input=[
        {"role": "user", "content": "Как называется столица Франции?"},
        {"role": "assistant", "content": "Париж."},
        {"role": "user", "content": "А какая река там протекает?"},
    ],
)
print(response.output_text)

Стриминг в Responses — это поток событий разных типов; текст приходит в событиях response.output_text.delta:

bash
stream = client.responses.create(
    model="gpt-5.6-luna",
    input="Расскажи про генераторы в Python",
    stream=True,
)
for event in stream:
    if event.type == "response.output_text.delta":
        print(event.delta, end="", flush=True)

У OpenAI в Responses есть и возможности своей платформы: хранение диалога на сервере (store, previous_response_id) и встроенные инструменты. Через шлюз на них не рассчитывайте — передавайте историю в input сами, как в примере выше, и проверяйте нужную функцию на своей модели.

Какие модели работают с каким эндпоинтом

Модель/v1/chat/completions/v1/responses
claude-opus-5-5дада
claude-sonnet-5дада
gpt-5.6-solдада
gpt-5.6-lunaдада
glm-5.3данет
glm-5.3-flashданет

Запрос к GLM через /v1/responses завершится ошибкой — для этих моделей используйте /v1/chat/completions. Набор моделей меняется: актуальный список — GET https://api.zukko.pro/v1/models или страница «Модели» в кабинете.

Codex: почему только Responses

Codex — агент для программирования от OpenAI. В справочнике конфигурации Codex параметр провайдера wire_api принимает единственное значение responses, и оно же используется по умолчанию. Значит, Codex ходит к модели только через Responses API, и в Zukko с ним работают модели Claude и GPT, но не GLM. Фрагмент ~/.codex/config.toml:

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

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

Как передать ключ и остальные шаги — в инструкции по Codex.

Что выбрать

  • Свой код с нуля, любая модель — /v1/chat/completions: работает со всеми моделями, включая GLM, и с любой OpenAI-совместимой библиотекой.
  • Инструмент требует Responses (Codex и подобные) — /v1/responses с моделью Claude или GPT.
  • Код уже написан на Responses — оставьте как есть, если не нужны GLM-модели.

Цена от эндпоинта не зависит: платите за входные и выходные токены по прайсу модели. Подробнее о формате — в справке по Chat Completions и руководстве по Python SDK. Чтобы попробовать оба API, создайте ключ в кабинете.

Частые вопросы

Получаю 404 на /responses. Что не так?

Чаще всего base URL указан без /v1. Полный адрес — https://api.zukko.pro/v1/responses; в SDK задайте base_url="https://api.zukko.pro/v1", и путь /responses он добавит сам.

Получаю 403 model_not_allowed_for_key. Это из-за эндпоинта?

Нет, этот код означает, что модель не входит в список разрешённых моделей ключа. Добавьте её в настройках ключа в кабинете или используйте другой ключ. Эндпоинт тут ни при чём.

Отличается ли цена между эндпоинтами?

Нет. Стоимость считается по числу входных и выходных токенов и цене модели. Разница только в названиях полей usage: prompt_tokens/completion_tokens против input_tokens/output_tokens.

Можно ли подключить Codex к GLM-модели?

Нет: Codex работает только через Responses API, а GLM-модели в Zukko через /v1/responses недоступны. Для Codex выбирайте gpt-5.6-sol, gpt-5.6-luna или модели Claude.

zukko

Платите в 25×
меньше

за Claude Code & ChatGPT

Один ключ fetch_* и base URL api.zukko.pro — в Cursor, Claude Code, Codex и любом SDK.

Responses API или Chat Completions: в чём разница · Zukko