Keural API
Отправка запросов в формате OpenAI Chat Completions с помощью ключа API.
Вызов модели, зарегистрированной в Keural, в формате OpenAI Chat Completions.
Base URL имеет вид https://<публичный домен API для среды>/llm/v1. Публичный домен API зависит от среды, уточните его у администратора.
| Метод | Путь | Описание |
|---|---|---|
POST | /llm/v1/chat/completions | Создание диалога (поддерживается потоковая передача) |
GET | /llm/v1/models | Список моделей, подключённых к ключу |
GET | /llm/v1/models/{model} | Информация о модели, подключённой к ключу |
Пути для эмбеддингов, генерации изображений, голоса и Responses API не поддерживаются и возвращают 404.
Порядок использования
| Шаг | Что делать |
|---|---|
| 1. Выпуск ключа | В Настройки → API выберите модель и выпустите ключ. Скопируйте ID модели и ключ. |
| 2. Подключение клиента | Укажите в приложении или коде Base URL, ключ API и ID модели. |
| 3. Использование и управление | На том же экране проверяйте использование, при необходимости переиздайте или отзовите ключ. |
Предварительные условия
| Пункт | Содержание |
|---|---|
| Аккаунт Keural | Нужен аккаунт, с которым вы можете войти. |
| Меню API | Если в настройках нет меню API, попросите администратора включить функцию. |
| Права участника организации | Чтобы получить ключ в рабочем пространстве организации, администратор организации должен сначала разрешить вам использование API. См. Разрешения API для участников организации. |
| Base URL | Публичный адрес API, который указал администратор. |
| Клиент | Приложение или SDK с поддержкой подключения, совместимого с OpenAI API. |
Выпуск ключа API
- Откройте меню аккаунта, выберите Настройки → API. В настольном и мобильном приложениях раздел находится в группе Инструменты.
- На вкладке API keys выберите владельца ключа (личное или рабочее пространство организации) и Model ID.
- При необходимости задайте New key expiration (optional, Korea time). Если поле оставить пустым, ключ будет действовать бессрочно, пока его не отзовут.
- Нажмите Issue key и скопируйте ключ кнопкой Copy key, затем сохраните его в надёжном месте. Полный ключ отображается только один раз.
- Ключ привязан к выбранному рабочему пространству и одной модели. Использование относится к тому, кто выпустил ключ.
- Для одного рабочего пространства и модели существует только один ключ. Чтобы получить новый, переиздайте или отзовите существующий.
- Если ключ утерян, переиздайте его: посмотреть ключ повторно нельзя. После переиздания предыдущий ключ сразу перестаёт работать.
- Если моделей для выпуска нет, попросите администратора проверить публичные настройки модели, тариф и разрешение API организации.
Разрешения API для участников организации
Этот раздел предназначен для владельцев и администраторов организации. Чтобы участники получали ключи в рабочем пространстве организации, администратор должен сначала разрешить им это. По умолчанию доступ заблокирован для всех участников.
Управление организацией → Organization API состоит из трёх разделов. Если меню не отображается, функция API выключена или у аккаунта нет права управления организацией.
| Раздел | Назначение |
|---|---|
| API permissions by user | Включение и выключение использования API для каждого участника. |
| Issued keys | Просмотр состояния ключей, выпущенных в организации, и их отзыв. Полный ключ не отображается. |
| API usage | Просмотр запросов и использования токенов по ключам, выпущенным в организации. |
| Действие | Результат |
|---|---|
| Включить разрешение | Участник может выпускать ключи в рабочем пространстве организации. |
| Выключить разрешение | Новые выпуски и вызовы с существующими ключами блокируются. Выпущенные ключи автоматически не удаляются, поэтому при необходимости отзовите их в разделе Issued keys. |
Когда участник выходит из организации или удаляется из неё, ключи, полученные им от организации, автоматически отзываются.
Подключение к клиенту
В приложении, совместимом с OpenAI API (клиент для чата, расширение IDE, инструмент автоматизации), укажите три значения:
| Значение | Что указать | Название в приложениях |
|---|---|---|
| Base URL | Публичный адрес API, который предоставил администратор (…/llm/v1) | Base URL, API Base, Endpoint, Host |
| API Key | Выпущенный ключ (без пробелов в начале и в конце) | API Key, Token, Secret Key, Authorization |
| Model | Model ID с экрана выпуска. Должен точно совпадать с моделью, подключённой к ключу | Model, Model ID, Model Name |
- В настройках приложения добавьте подключение, совместимое с OpenAI (Connection).
- Укажите Base URL и API Key и сохраните.
- Выберите модель в списке моделей. В списке отображается только одна модель, подключённая к ключу.
- Отправьте короткое сообщение и проверьте, что пришёл ответ.
Формат запросов:
| Тип | Содержание |
|---|---|
| Запрос диалога | POST <Base URL>/chat/completions |
| Получение моделей | GET <Base URL>/models |
| Заголовок аутентификации | Authorization: Bearer <выпущенный ключ> |
| Заголовок содержимого | Content-Type: application/json |
Первый запрос
export KEURAL_API_KEY='your_issued_key'
export KEURAL_BASE_URL='https://<публичный домен API для среды>/llm/v1'
export MODEL_ID='ID модели с экрана выпуска'
curl "$KEURAL_BASE_URL/chat/completions" \
-H "Authorization: Bearer $KEURAL_API_KEY" \
-H 'Content-Type: application/json' \
-d "{\"model\":\"$MODEL_ID\",\"messages\":[{\"role\":\"user\",\"content\":\"Здравствуйте.\"}]}"Значение model в теле запроса должно совпадать с ID модели, подключённой к ключу. Если перед ним стоит путь вида provider/ID-модели, сравнивается часть после последнего /. Если не совпадает, возвращается 403. В ответе поле model всегда содержит ID модели из ключа.
from openai import OpenAI
import os
client = OpenAI(
api_key=os.environ["KEURAL_API_KEY"],
base_url=os.environ["KEURAL_BASE_URL"],
)
res = client.chat.completions.create(
model=os.environ["MODEL_ID"],
messages=[{"role": "user", "content": "Здравствуйте."}],
)
print(res.choices[0].message.content)Поддерживаемые поля запроса
Принимаются только 18 полей верхнего уровня, перечисленных ниже. При отправке другого поля возвращается 400. Необязательные поля со значением null считаются не отправленными.
| Поле | Правило |
|---|---|
model | Обязательно. ID модели ключа |
messages | Обязательно. От 1 до 4 096 элементов |
stream · stream_options | stream_options отправляется только при stream: true. Поддерживается include_usage. |
tools | До 128. Имена функций: [A-Za-z0-9_-], от 1 до 64 символов |
tool_choice | none · auto · required · конкретная функция. Для required нужны tools. |
parallel_tool_calls | Если модель не поддерживает, возвращается 400 |
response_format | text · json_object · json_schema |
max_tokens · max_completion_tokens | Отправляйте только одно из двух. Если не отправлено ни одно, используется 4 096 (или меньшее ограничение модели, если оно ниже). Превышение ограничения модели возвращает 400. |
temperature | От 0 до 2. Если модель не поддерживает, возвращается 400 |
top_p | От 0 до 1 |
frequency_penalty · presence_penalty | От -2 до 2 |
stop | Строка или массив до 4 элементов |
seed | Целое число |
user | До 256 символов |
n | Только 1 |
Сообщения
| Роль | Принимаемые поля |
|---|---|
system · developer | content, name |
user | content (строка или массив текстовых и графических частей), name |
assistant | content, name, refusal, tool_calls |
tool | content, tool_call_id |
- Сообщение
toolотвечает на каждыйidиз предыдущихtool_callsтолько один раз. - Графические части (
image_url) добавляются только в сообщенияuserдля моделей, которые принимают изображения. Используйте адресhttpилиhttps, либо data URI в base64 формата PNG, JPEG, GIF или WebP.detail:auto,lowилиhigh.
Тело запроса
| Параметр | Ограничение |
|---|---|
| Content-Type | application/json |
| Размер | 1 МиБ |
| Структура JSON | Один объект верхнего уровня, глубина вложенности не более 64, без повторяющихся ключей |
| Время запроса | До 600 секунд |
Нарушение правил тела запроса возвращает 400, при этом param: body.
Потоковая передача
Если в запросе указано "stream": true, ответ отправляется через SSE. Каждый фрагмент передаётся как событие data: ..., в конце передаётся data: [DONE]. Если указано "stream_options": {"include_usage": true}, непосредственно перед [DONE] передаётся ещё один фрагмент с данными об использовании токенов.
При include_usage каждый фрагмент содержит usage: null, а последний фрагмент с использованием имеет пустой массив choices. Непотоковый ответ содержит usage только тогда, когда подтверждены и входные, и выходные токены.
Идентификатор ответа id имеет вид chatcmpl-<x-request-id>. Во всех заголовках ответа есть x-request-id.
При ошибке во время потоковой передачи отправляется событие data: с JSON ошибки, и соединение завершается без [DONE]. Если один фрагмент превышает 1 МиБ или ответ превышает 16 МиБ, ответ завершается с кодом 503.
curl -N "$KEURAL_BASE_URL/chat/completions" \
-H "Authorization: Bearer $KEURAL_API_KEY" \
-H 'Content-Type: application/json' \
-d "{\"model\":\"$MODEL_ID\",\"messages\":[{\"role\":\"user\",\"content\":\"Здравствуйте.\"}],\"stream\":true,\"stream_options\":{\"include_usage\":true}}"Лимиты использования
Ограничения действуют по пользователю, организации и модели: по числу одновременных запросов, числу запросов в минуту (RPM) и числу токенов в минуту (TPM). Фактические значения зависят от среды.
Токены в минуту списываются заранее, при получении запроса. Входной текст считается как 1 токен на 4 английских символа, остальные символы как 1 токен на символ, одно изображение как 2 000 токенов. Выход учитывается в объёме max_tokens (максимум 4 096), поэтому если задавать ограничение вывода только в нужном объёме, запас по лимиту будет больше.
Код 429 | Причина | Retry-After |
|---|---|---|
rate_limit_exceeded | Превышены RPM, TPM или число одновременных запросов | Для RPM и TPM: 60 секунд, для одновременных запросов: 1 секунда |
api_busy | Превышена пропускная способность сервера | Нет. Подождите немного и повторите попытку. |
upstream_rate_limit | Превышен лимит поставщика модели | Нет |
Управление ключами
На вкладке API keys в разделе Настройки → API можно проверить состояние ключей (действует, истёк срок, отозван), переиздать или отозвать их.
Ключ представляет собой строку из 51 символа, которая начинается с krl_llm_. Для одного владельца может быть только один ключ. Если он уже есть, ключ переиздаётся, а не выпускается новый. Срок действия можно задать только на дату после сегодняшнего дня.
| Действие | Результат | Важно |
|---|---|---|
| Переиздать | Вы получаете новый ключ. | Предыдущий ключ сразу перестаёт работать. Обновите ключ и в подключённых приложениях. |
| Отозвать | Ключ сразу блокируется. | Используйте при подозрении на утечку ключа. Отозванный ключ нельзя восстановить. |
Проверка использования
Запросы через API и использование токенов можно проверить в двух местах.
| Где | Что |
|---|---|
| Вкладка Настройки → API → API usage | Использование ключей, которые вы выпустили в текущем рабочем пространстве |
| Управление организацией → Organization API, затем API usage внизу | Использование всех ключей, выпущенных в организации (владельцы и администраторы организации) |
Условия поиска
| Условие | Описание |
|---|---|
| Время начала · Время окончания | По корейскому времени. Время начала включается, время окончания не включается. Если поля пустые, показываются последние 7 дней. За один раз можно запросить до 90 дней. |
| Model ID | Показываются только запросы к выбранной модели. Если поле пустое, показываются все. |
| Состояние запроса | Выберите из: All · Running · Completed · Failed · Cancelled · Unknown. |
Задайте условия и нажмите Search. Чтобы увидеть последние запросы, нажмите Refresh.
Значения на экране
- Applied time range (KST): фактически запрошенный период. Если время начала или окончания не задано или период превышает 90 дней, отображается период, скорректированный сервером.
- Requests и итоги Input tokens · Output tokens · Total tokens: суммируются только подтверждённые значения. Непроверенные токены отображаются как Unconfirmed.
- Список запросов: для каждого запроса показываются время запроса, Model ID, состояние запроса, входные, выходные и общие токены. На странице 20 записей, переход выполняется кнопками Previous и Next.
Нажмите Request details в строке, чтобы показать следующие значения.
| Пункт | Описание |
|---|---|
| ID запроса | Значение, которое сообщают при обращении в поддержку. |
| Тип ответа | Потоковый или обычный ответ |
| Состояние подтверждения использования | Confirmed · Partially confirmed · Unconfirmed |
| Время окончания · Время ответа (мс) | Когда запрос завершился и сколько он занял |
| Чтение кэша · Создание кэша · Токены рассуждений | Отображаются, только если модель возвращает эти значения. |
Использование записывается и для потоковых запросов без stream_options.include_usage. Если запрос прервался, он может остаться со статусом Partially confirmed или Unconfirmed.
Формат ошибок
Ошибки возвращаются в формате, совместимом с OpenAI.
{
"error": {
"message": "Понятное описание ошибки",
"type": "authentication_error",
"code": "invalid_api_key",
"param": null
}
}type определяется кодом состояния, а code позволяет различить причину.
| Состояние | type | code | Причина |
|---|---|---|---|
400 | invalid_request_error | invalid_request | Нарушение правил поля, значения или тела запроса. В param указано проблемное поле |
400 | invalid_request_error | upstream_rejected_request | Поставщик модели отклонил запрос |
401 | authentication_error | invalid_api_key | Ошибка формата ключа, ключ отсутствует, истёк, отозван или переиздан, либо заголовков Authorization больше одного |
403 | permission_error | api_disabled | Функция Keural API выключена |
403 | permission_error | model_api_disabled | Публичный API для модели выключен |
403 | permission_error | model_not_allowed | model отличается от модели ключа, или у участника нет разрешения на API |
404 | invalid_request_error | not_found | Путь не существует |
405 | invalid_request_error | method_not_allowed | Неверный метод. Разрешённые методы указаны в заголовке Allow |
429 | rate_limit_error | См. таблицу Лимиты использования выше | Превышено ограничение |
503 | server_error | upstream_timeout | Ответ не завершился за 600 секунд |
503 | server_error | invalid_upstream_response | Нестандартный формат ответа поставщика, превышен размер потока |
503 | server_error | dependency_unavailable · unsupported_provider | Временная внутренняя проблема. При обращении в поддержку укажите x-request-id |
Устранение неполадок
| Симптом | Код ответа | Что проверить |
|---|---|---|
| Список моделей пуст или соединение не устанавливается | 404 · 405 | Заканчивается ли Base URL на …/llm/v1 |
| Ошибка аутентификации | 401 | Опечатки или пробелы в начале и в конце ключа, истёк ли срок, отозван ли или переиздан ключ |
| Соединение есть, но модель недоступна | 403 | Совпадает ли ID модели с моделью ключа, разрешение API организации |
| Ответы медленные или иногда завершаются ошибкой | 429 | Лимиты использования |
| Долго нет ответа | 5xx | Повторите попытку через некоторое время |
| Использование не отображается или отличается от фактического | — | Период поиска и рабочее пространство ключа |
Если проблема не решается, обратитесь к администратору и передайте следующие сведения. Полный ключ и содержимое промптов не отправляйте.
- Время возникновения проблемы
- Использованный ID модели
- Название и версия клиентского приложения
x-request-idиз заголовков ответа- Сообщение об ошибке, показанное на экране