Для разработчиков
Документация API
API ModelMesh совместимо с OpenAI: поменяйте base_url и ключ — и ваш код, OpenAI SDK, Cursor, LangChain или n8n заработают с моделями ModelMesh.
Спецификацию можно импортировать в Postman, Insomnia или сгенерировать по ней клиент. ModelMesh API 1.0.0, OpenAPI 3.1.0.
Быстрый старт
Базовый адрес всех запросов:
https://api.modelmesh.shop/v1- Создайте ключ в кабинете, в разделе «API-ключи». Полный ключ показывается один раз — сохраните его.
- Укажите в OpenAI SDK base_url и ключ ModelMesh.
- Выберите модель из GET /models и отправьте запрос.
curl https://api.modelmesh.shop/v1/chat/completions \
-H "Authorization: Bearer $MODELMESH_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5-mini",
"messages": [{"role": "user", "content": "Привет!"}]
}'Авторизация
Передавайте ключ в заголовке Authorization каждого запроса:
Authorization: Bearer mm_live_...- Рабочие ключи начинаются с mm_live_, тестовые — с mm_test_.
- Тестовый ключ возвращает заглушки вместо ответов моделей и ничего не списывает — удобно для отладки интеграции.
- Ключ можно ограничить: лимит токенов (всего, в сутки, в месяц) или отдельный баланс, список моделей и категорий, число запросов в минуту, срок действия.
- Не публикуйте ключ в коде фронтенда и репозиториях. Утёкший ключ отзовите в кабинете — он перестанет работать сразу.
Эндпоинты
Все пути — относительно базового адреса. Подробные схемы запросов и ответов — в openapi.json.
- GET
/modelsСписок моделейМодели, доступные вашему ключу, с ценами в Mesh-токенах (MT).
Ответы: 200, 401
- POST
/chat/completionsЧат (OpenAI chat.completions)Поддерживает
stream: true(SSE в формате OpenAI),tools(вызов функций) и vision (картинки вcontent). Списание — с кошелька prepaid-ключа или с баланса аккаунта в пределах лимита ключа. Тестовые ключиmm_test_возвращают заглушку без списаний. Поддерживается толькоn=1. В стриме цена приходит в последнем чанкеusage(cost_mt), заголовокX-ModelMesh-Balance— баланс до запроса.- stream: true — ответ потоком (SSE в формате OpenAI).
- tools — вызов функций в формате OpenAI.
- vision — картинки в content (type: image_url) для моделей, которые их понимают.
Ответы: 200, 400, 401, 402, 403, 404, 429, 502
- POST
/embeddingsЭмбеддинги (OpenAI embeddings)Ответы: 200, 400, 401, 402, 403, 404, 429, 502
- GET
/balanceОстаток по ключуДля prepaid-ключа — баланс кошелька ключа; для limit-ключа — минимум из остатка лимита и баланса аккаунта.
GET /balance возвращает balance_mt: для ключа с отдельным балансом — баланс ключа, для ключа с лимитом — меньшее из остатка лимита и баланса аккаунта.
Ответы: 200, 401
- GET
/usageРасход по ключуGET /usage принимает необязательные from и to (ISO 8601) и возвращает расход по дням: total_cost_mt, total_requests и days[] с date, cost_mt, requests. По умолчанию — последние 30 дней.
Ответы: 200, 400, 401
- POST
/images/generationsГенерация изображений (OpenAI images)Модели категории
imageизGET /models.sizeпереводится в соотношение сторон и разрешение модели,n— число картинок (если модель умеет), прочие параметры модели — вextra(ключиui_schemaизGET /models). Ответ приходит, когда картинка готова; ссылкиurlподписаны и действуют сутки. Списывается цена только за полученные картинки, при ошибке провайдера — ничего (usage.cost_mt).Ответы: 200, 202, 400, 401, 402, 403, 404, 429, 502
- POST
/images/editsРедактирование изображений (OpenAI images/edits)multipart/form-data:image(один или несколько файлов PNG/JPEG/WebP/GIF),prompt,model,n,size,response_format. Либо JSON с картинками data-URL:images: [{ "image_url": "data:image/png;base64,..." }]. Внешние URL не принимаются,maskне поддерживается. Модели — категорииimageс полем картинок вui_schema.Ответы: 200, 202, 400, 401, 402, 403, 404, 429, 502
- POST
/audio/speechОзвучка текста (OpenAI audio/speech)Ответ — аудиофайл (
audio/*).voice— голос модели изui_schema(стандартные голоса OpenAI заменяются голосом модели по умолчанию). Цена — по числу символов.Ответы: 200, 202, 400, 401, 402, 403, 404, 429, 502
- POST
/audio/transcriptionsРаспознавание речи (OpenAI audio/transcriptions)multipart/form-data:file(MP3, WAV, M4A, OGG, MP4, MOV),model,language,response_format(json,text,verbose_json). Цена — по длительности, измеренной по файлу.Ответы: 200, 202, 400, 401, 402, 403, 404, 429, 502
- POST
/tasksАсинхронная задача: видео, музыка, любая медиа-модельСразу отвечает
202с задачей (status: queued). Токены резервируются на цену при запуске и списываются только за готовый результат; при ошибке и таймауте (2 ч) — возвращаются. О завершении можно узнать опросомGET /tasks/{id}или поwebhook_url(https): ModelMesh отправит POST с событиемtask.succeeded,task.failedилиtask.canceledи подписьюX-ModelMesh-Signature: t=<unix>,v1=<hex>— HMAC-SHA256 от<t>.<тело>секретом изGET /webhooks/secret. Неуспешная доставка (не 2xx) повторяется с паузой до ~суток; дубликаты отсекайте по заголовкуwebhook-id.Ответы: 202, 400, 401, 402, 403, 404, 409, 429
- GET
/tasks/{id}Статус и результат задачиВидны только задачи и синхронные генерации, созданные этим ключом. Ссылки на файлы подписаны и действуют сутки — запросите задачу снова, чтобы получить свежие.
Ответы: 200, 401, 404
- GET
/webhooks/secretСекрет проверки подписи webhook_urlСекрет
whsec_...для проверкиX-ModelMesh-Signatureу событий задач этого ключа.Ответы: 200, 401
Стриминг
С stream: true ответ приходит как text/event-stream: чанки data: {…} в формате OpenAI и завершающий data: [DONE]. Перед [DONE] приходит чанк с usage — в нём стоимость запроса.
curl -N https://api.modelmesh.shop/v1/chat/completions \
-H "Authorization: Bearer $MODELMESH_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5-mini",
"stream": true,
"messages": [{"role": "user", "content": "Напиши хайку про токены"}]
}'Картинки, аудио и задачи
Картинки, озвучка и распознавание речи — через привычные методы OpenAI SDK (images.generate, images.edit, audio.speech, audio.transcriptions). Видео, музыка и любые долгие генерации — асинхронными задачами /tasks.
- Синхронные методы ждут готовности до 5 минут. Не успели — ответ 202 с пустым data и задачей в modelmesh_task: результат заберите через
GET /tasks/{id}. - Параметры модели (соотношение сторон, длительность, голос…) — в
extraили вinputзадачи: ключи ui_schema изGET /models. - Токены резервируются по цене при запуске и списываются только за готовый результат; при ошибке провайдера или таймауте — возвращаются. Лимит и баланс ключа соблюдаются и для медиа.
- Ссылки на файлы результата подписаны и действуют сутки; заголовок
Idempotency-Keyзащищает от повторного запуска при сетевых ошибках.
# Картинка (ответ — когда готова)
curl https://api.modelmesh.shop/v1/images/generations \
-H "Authorization: Bearer $MODELMESH_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "nano-banana-2", "prompt": "Кот-космонавт, акварель", "size": "1792x1024"}'
# Видео — задача с уведомлением на webhook_url
curl https://api.modelmesh.shop/v1/tasks \
-H "Authorization: Bearer $MODELMESH_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "kling-3-pro", "input": {"prompt": "Маяк в шторм"}, "webhook_url": "https://example.com/modelmesh"}'
# Статус задачи
curl https://api.modelmesh.shop/v1/tasks/$TASK_ID -H "Authorization: Bearer $MODELMESH_API_KEY"Проверка webhook_url
О завершении задачи ModelMesh отправляет POST на webhook_url: тело — {"id", "type": "task.succeeded" | "task.failed" | "task.canceled", "data": задача}. Подпись в заголовке X-ModelMesh-Signature: t=<unix>,v1=<hex> — HMAC-SHA256 от "<t>.<тело>" секретом из GET /webhooks/secret. Ответьте 2xx; иначе доставка повторится (до ~суток). Повторы одного события приходят с тем же заголовком webhook-id.
import crypto from 'node:crypto';
// secret — из GET https://api.modelmesh.shop/v1/webhooks/secret (whsec_...)
export function verifyModelMeshWebhook(rawBody, header, secret) {
const { t, v1 } = Object.fromEntries(header.split(',').map((p) => p.split('=')));
const expected = crypto.createHmac('sha256', secret).update(`${t}.${rawBody}`).digest('hex');
const fresh = Math.abs(Date.now() / 1000 - Number(t)) < 300;
return fresh && crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(v1 ?? ''));
}Стоимость запросов
Цены моделей — в Mesh-токенах (MT), их видно в GET /models. Стоимость каждого запроса возвращается:
- в поле usage.cost_mt ответа (десятичная строка, MT; usage.cost_mmt — то же в тысячных долях);
- в заголовке X-ModelMesh-Cost — списано за запрос, MT;
- в заголовке X-ModelMesh-Balance — остаток после запроса, MT.
Списывается только фактическая стоимость. Тестовые ключи ничего не списывают. Тарифы и пакеты токенов
Ошибки
Ошибки — в формате OpenAI, поэтому SDK обрабатывают их как обычно:
{
"error": {
"message": "Your API key does not have access to the model `gpt-5-mini`.",
"type": "permission_error",
"param": "model",
"code": "model_not_allowed"
}
}| Статус | code | Что значит |
|---|---|---|
| 401 | invalid_api_key | Ключа нет, он неверен, приостановлен, отозван или истёк. |
| 402 | insufficient_balance | Недостаточно токенов: закончился баланс ключа, аккаунта или лимит ключа. |
| 403 | model_not_allowed | Ключу не разрешена эта модель или категория (или модель недоступна на тарифе). |
| 429 | rate_limited | Превышен лимит запросов в минуту для ключа. Повторите позже (заголовок Retry-After). |
| 400 | content_policy_violation | Запрос отклонён модерацией (нашей или провайдера модели). Токены не списаны. |
| 409 | conflict | Idempotency-Key уже использован другим запросом. |
| 502 | provider_error | Провайдер модели не справился. Токены не списаны — повторите позже. |
Примеры
Эмбеддинги, список моделей, остаток и расход по ключу:
# Эмбеддинги
curl https://api.modelmesh.shop/v1/embeddings \
-H "Authorization: Bearer $MODELMESH_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "text-embedding-3-small", "input": "Текст для поиска"}'
# Остаток по ключу
curl https://api.modelmesh.shop/v1/balance -H "Authorization: Bearer $MODELMESH_API_KEY"
# Расход по дням
curl "https://api.modelmesh.shop/v1/usage?from=2026-10-01T00:00:00Z" \
-H "Authorization: Bearer $MODELMESH_API_KEY"