Разработчикам
Быстрый старт
Направьте совместимый с OpenAI клиент на хост API, используйте ключ проекта, отправьте chat completion. Формат совместим; сервис принадлежит Media Holding. Сервисы OpenAI не задействованы.
Пять шагов
Создайте ключ проекта в кабинете
Ключи принадлежат проекту вашей организации. Секрет показывается один раз; храните его в переменной окружения (
SOVEREIGN_API_KEYв примерах), никогда — в коде.Отправьте chat completion через curl
Один запрос, один ответ, учёт использования в теле ответа.
Используйте Python-клиент
Установите пакет
openaiи укажите вbase_urlхост API. Больше ничего в вашем коде не меняется; пакет лишь говорит на формате — он вызывает наш хост, а не хост OpenAI.Включите поток
Задайте
stream=Trueиstream_options={"include_usage": True}; печатайте дельты по мере поступления и читайте учёт из последнего фрагмента.Прочитайте своё использование
GET /v1/usageвозвращает запросы и число токенов вашего проекта за период — тот же реестр, из которого строится ваш счёт.
Формат API, совместимый с OpenAI. Сервисы OpenAI не задействованы. Хост API в примерах — хост платформы; кабинет показывает хост вашего выделенного инстанса.
curl
curl https://sovereignai-api.mediaholding.tech/v1/chat/completions \
-H "Authorization: Bearer $SOVEREIGN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "mh-sovereign",
"messages": [
{"role": "system", "content": "You answer briefly and cite the clause you rely on."},
{"role": "user", "content": "Summarise the termination clause of the attached contract in two sentences."}
]
}'
Python — клиент openai с base_url
Пакет openai используется только как клиент совместимого с OpenAI формата запросов. При base_url, указывающем на наш хост, ни один запрос не достигает OpenAI.
import os
from openai import OpenAI # the OpenAI-compatible client format; no OpenAI service is called
client = OpenAI(
base_url="https://sovereignai-api.mediaholding.tech/v1",
api_key=os.environ["SOVEREIGN_API_KEY"],
)
response = client.chat.completions.create(
model="mh-sovereign",
messages=[
{"role": "system", "content": "You answer briefly and cite the clause you rely on."},
{"role": "user", "content": "Summarise the termination clause of the attached contract in two sentences."},
],
)
print(response.choices[0].message.content)
print(response.usage) # prompt_tokens, completion_tokens, total_tokens
Потоковая передача
stream = client.chat.completions.create(
model="mh-sovereign",
messages=[{"role": "user", "content": "List three risks of the clause."}],
stream=True,
stream_options={"include_usage": True}, # the final chunk carries usage
)
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)
if chunk.usage:
print("\n", chunk.usage)
Размышление для числовых задач
Размышление по запросу
ИзмереноМодель 9B рассуждает перед ответом, когда для запроса включено размышление (бюджет 1 024 токена). Измерено 12.10.2026: задачи с деньгами, ценами и количествами требуют его.
# Money, prices and quantities: switch the model's thinking on for the request.
response = client.chat.completions.create(
model="mh-sovereign-reason",
messages=[{"role": "user", "content": "Invoice total 1,240.50 EUR net; VAT 24 %. Gross amount?"}],
extra_body={"chat_template_kwargs": {"enable_thinking": True}},
max_tokens=1024,
)
`chat_template_kwargs` — переключатель режима размышления модели в среде выполнения llama.cpp; окончательное поле запроса публичного API фиксируется в сгенерированной спецификации.
Выбор модели
mh-sovereign — псевдоним по умолчанию, разрешается в модель 9B (mh-sovereign-reason). Используйте mh-sovereign-small для быстрой классификации и извлечения, mh-sovereign-lingua — для многоязычных черновиков. В каталоге — измеренные показатели и известные ограничения каждой модели.
Что гарантирует API
Ключи
ПостроеноПрефикс виден в кабинете, секрет показывается один раз и хранится как ключевой односторонний хеш (HMAC-SHA-256); ротация и отзыв без простоя для других ключей проекта.
Клиентские библиотеки
ПостроеноЛюбой клиент, говорящий на совместимом с OpenAI формате chat completions, работает после замены base_url и ключа — Python, JavaScript, Go, curl. Сервисы OpenAI не задействованы.
Идентификаторы запросов
ПостроеноX-Request-Id в каждом ответе и error.request_id в каждом теле ошибки; тот же идентификатор в нашей строке аудита, чтобы поддержка нашла запрос — его метаданные, никогда не содержимое.
Лимиты частоты
Построено429 с Retry-After при лимите частоты или бюджете проекта; отступите на указанное число секунд. Заголовки лимитов запланированы; имена окончательны в сгенерированной спецификации.
Контракт ошибок
ПостроеноОдна форма JSON, восемь типов ошибок, HTTP-статус называет класс; сообщения без URL, токенов, путей и текста upstream.
Метки статуса — ИЗМЕРЕНО — существует и измерено в указанную дату указанным методом. ПОСТРОЕНО — существует и работает, под нагрузкой ещё не измерено. ЗАПЛАНИРОВАНО — спроектировано, ещё не построено. Строка без метки не является утверждением этой платформы.
Ошибки
Каждая ошибка — одна форма JSON с HTTP-статусом, называющим её класс. Сообщение никогда не содержит URL, токенов, путей или текста исключений upstream.
| HTTP | error.type | Когда | Retry-After |
|---|---|---|---|
400 | invalid_request_error | Тело запроса или параметры недопустимы. | нет |
401 | authentication_error | Отсутствующий, неверно сформированный, отозванный или неизвестный API-ключ. | нет |
403 | permission_error | Ключ действителен, но не может использовать эту модель, проект или маршрут. | нет |
404 | invalid_request_error | Неизвестная модель или маршрут; code называет их. | нет |
429 | rate_limit_error · budget_exceeded | Достигнут лимит частоты или бюджет проекта; подождите указанное число секунд. | да |
500 | server_error | Непредвиденный сбой с нашей стороны; укажите идентификатор запроса. | нет |
503 | backend_busy · upstream_unavailable | GPU занят другой задачей или поставщик инференса недоступен. Запасного варианта с внешним поставщиком не существует. | да |
Ответ с ошибкой и его заголовки
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
X-Request-Id: 5b8e2b2e-4a2f-4b7c-9d2e-1f3a4b5c6d7e
Retry-After: 12
{
"error": {
"type": "rate_limit_error",
"code": "requests_per_minute",
"message": "Too many requests for this project. Retry after the number of seconds in Retry-After.",
"request_id": "5b8e2b2e-4a2f-4b7c-9d2e-1f3a4b5c6d7e"
}
}