API Chat Completions
/ Документация API← Быстрый старт с APIОткрыть как Markdown
POST https://api.opencheese.dev/v1/chat/completions — это OpenAI Chat Completions API. Его
используют SDK OpenAI, OpenCode, Zed, Harness AI и большинство чат-приложений.
Первый запрос
curl https://api.opencheese.dev/v1/chat/completions \
-H "Authorization: Bearer $OPENCHEESE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "MODEL_ID", "messages": [{"role": "system", "content": "Answer in one sentence."}, {"role": "user", "content": "What is a gateway?"}]}'
Поля model и messages обязательны. ID модели возьмите из
GET /v1/models.
Ответ приходит в привычном формате:
{
"id": "chatcmpl-abc123",
"object": "chat.completion",
"model": "MODEL_ID",
"choices": [
{
"index": 0,
"message": { "role": "assistant", "content": "A gateway passes your requests on to the models behind it." },
"finish_reason": "stop"
}
],
"usage": { "prompt_tokens": 24, "completion_tokens": 13, "total_tokens": 37 }
}
Параметры
| Поле | Примечания |
|---|---|
model |
Обязательное. Значение id из /v1/models. |
messages |
Обязательное. Сообщения с ролями system, user, assistant и tool. |
stream |
true, чтобы получить ответ в виде server-sent events. |
tools, tool_choice |
Вызов функций, если модель поддерживает инструменты. |
reasoning_effort |
Один из уровней в supported_reasoning_levels модели. |
response_format |
Структурированный вывод, если модель его поддерживает. |
temperature, top_p, max_tokens |
Необязательные. Если их не задать, используются значения модели по умолчанию. |
Потоковый ответ
curl -N https://api.opencheese.dev/v1/chat/completions \
-H "Authorization: Bearer $OPENCHEESE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "MODEL_ID", "stream": true, "messages": [{"role": "user", "content": "Count to three."}]}'
Каждое событие — это chat.completion.chunk; текст приходит в choices[0].delta.content.
Ближе к концу приходят finish_reason и usage, а завершается поток строкой data: [DONE]:
data: {"object":"chat.completion.chunk","choices":[{"index":0,"delta":{"role":"assistant","content":"One"},"finish_reason":null}]}
data: {"object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":", two, three."},"finish_reason":null}]}
data: {"object":"chat.completion.chunk","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}
data: {"object":"chat.completion.chunk","choices":[],"usage":{"prompt_tokens":12,"completion_tokens":6,"total_tokens":18}}
data: [DONE]
Вызовы инструментов
curl https://api.opencheese.dev/v1/chat/completions \
-H "Authorization: Bearer $OPENCHEESE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "MODEL_ID", "messages": [{"role": "user", "content": "What is the weather in Paris?"}], "tools": [{"type": "function", "function": {"name": "get_weather", "description": "Current weather for a city", "parameters": {"type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"]}}}]}'
Когда модель вызывает инструмент, finish_reason в ответе равен tool_calls, а сам вызов находится
в message.tool_calls. Выполните инструмент и отправьте историю обратно, добавив сообщение
tool с результатом:
{
"model": "MODEL_ID",
"messages": [
{ "role": "user", "content": "What is the weather in Paris?" },
{
"role": "assistant",
"content": null,
"tool_calls": [{ "id": "call_1", "type": "function", "function": { "name": "get_weather", "arguments": "{\"city\":\"Paris\"}" } }]
},
{ "role": "tool", "tool_call_id": "call_1", "content": "18 degrees, sunny" }
]
}
Ответ, обрезанный лимитом вывода посреди вызова инструмента, завершается с
finish_reason: "length": считайте такой вызов неполным и не выполняйте его.
Изображения в промпте
Модели, у которых modalities.input включает image, понимают изображения в частях
image_url — с адресом https:// или URL вида data::
{
"model": "MODEL_ID",
"messages": [
{
"role": "user",
"content": [
{ "type": "text", "text": "What is in this picture?" },
{ "type": "image_url", "image_url": { "url": "data:image/png;base64,iVBORw0KGgo..." } }
]
}
]
}
Уровень рассуждений
Задайте в reasoning_effort один из уровней, которые модель перечисляет в
supported_reasoning_levels (также принимаются reasoning.effort и output_config.effort из
API Anthropic). Если уровень не задан, используется уровень модели по умолчанию.
curl https://api.opencheese.dev/v1/chat/completions \
-H "Authorization: Bearer $OPENCHEESE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "MODEL_ID", "reasoning_effort": "high", "messages": [{"role": "user", "content": "Plan a three-day trip to Lyon."}]}'
Уровень, которого у модели нет, отклоняется с ошибкой unsupported_reasoning_effort, и в ошибке
перечислены уровни, которые модель поддерживает. Текст рассуждений, если модель его возвращает,
приходит в message.reasoning_content (в потоковом ответе — в delta.reasoning_content).
Модели изображений в чате
Выберите модель изображений (у неё modalities.output равно image), и последнее сообщение
пользователя станет промптом для изображения. Готовое изображение приходит в
message.images как URL вида data:, а изображение, отправленное в разговоре, модель редактирует,
если умеет. Модели изображений возвращают одно изображение на запрос; все параметры
изображений доступны в API изображений.
Ошибки, которые приходят как ответ
Проблемы, которые требуют ваших действий (например, недействительный ключ, исчерпанный тариф
или пустой баланс), возвращаются как сообщение ассистента в ответе 200, переданном потоком
text/event-stream, даже если stream равен false: так чат-приложения покажут их вам. Все
остальные ошибки приходят как обычный HTTP-статус с телом в JSON. Прежде чем разбирать ответ как
JSON, проверьте его Content-Type; подробнее — на странице
Ошибки и лимиты запросов.
SDK
Python:
from openai import OpenAI
client = OpenAI(base_url="https://api.opencheese.dev/v1", api_key="YOUR_OPENCHEESE_API_KEY")
stream = client.chat.completions.create(
model="MODEL_ID",
messages=[{"role": "user", "content": "Write a haiku about cheese."}],
stream=True,
)
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="")
JavaScript:
import OpenAI from "openai";
const client = new OpenAI({ baseURL: "https://api.opencheese.dev/v1", apiKey: process.env.OPENCHEESE_API_KEY });
const reply = await client.chat.completions.create({
model: "MODEL_ID",
messages: [{ role: "user", content: "Write a haiku about cheese." }]
});
console.log(reply.choices[0].message.content);
Чтобы запросы одного разговора отображались в панели вместе, добавьте заголовок
opencheese-session-uuid.