REST API
В портале: справочник API по адресу
https://<your-domain>/apidoc(публичный) и API-ключи по адресу/api-keys. В панели администратора: в разделе Customers › API keys (/customers/apikeys) перечислены ключи, созданные клиентами.
Назначение
Каждое действие, доступное клиенту на портале — просмотр и управление ВМ, чтение счетов, управление SSH Keys, Kubernetes, хранилищем, тикетами поддержки — доступно через версионированный REST API по адресу https://<your-domain>/v1/. Клиенты обращаются к нему из скриптов и CI с помощью API key с ограниченной областью действия. Этот же API используется cmp утилитой командной строки и MCP-сервером, а справочник генерируется на основе запущенной системы, поэтому он всегда содержит именно те функции, которые у вас включены.
Требования
| Параметр | Требование |
|---|---|
| Публичный HTTPS-адрес | API работает на вашем основном домене (и на собственном домене каждого реселлера). |
| API-ключ | Создаётся клиентом в портале; см. API keys. |
| Зависимости | Нет. Эндпоинты модулей, которые вы не включили (например, Kubernetes или Object Storage), скрыты из справочника и отклоняются. |
Подготовка инфраструктуры
Ничего устанавливать не нужно. Если перед NexCMP используется reverse proxy, перенаправляйте /v1/, /mcp, /cli/ и /apidoc на панель (в конфигурации nginx установщика это уже настроено).
Подключение в NexCMP
Интерактивный справочник
Откройте https://cloud.example.com/apidoc (замените хост на ваш домен; клиенты реселлера видят справочник на домене реселлера и с его именем). Здесь представлена документация по эндпоинтам с примерами запросов и ответов для curl, cmp CLI, JavaScript, Python и Go, поле поиска (Ctrl или Cmd + K) и панель Try it. Функция Try it отправляет запросы только к текущему сайту с ключом, который вставляет посетитель (он сохраняется в сессии браузера); по умолчанию она работает только на чтение, а для операций записи или платных вызовов требуются дополнительный переключатель и подтверждение.
Загрузки и машиночитаемые документы
Все они публичны, не требуют ключа и генерируются для каждого сайта:
| URL | Содержимое |
|---|---|
/apidoc | Интерактивный справочник. |
/v1/public/openapi.json | Документ OpenAPI 3.1. |
/v1/public/openapi.yaml | То же, YAML. |
/v1/public/postman.json | Коллекция Postman. |
/v1/public/insomnia.json | Экспорт для Insomnia. |
/v1/public/api.md | Справочник в виде одного файла Markdown. |
/v1/public/api-catalog | Облегчённый JSON: бренд, базовый URL, префикс ключа, каждый scope и каждый эндпоинт с указанием метода, пути, scope и необходимости Idempotency-Key. |
bash
curl -s https://cloud.example.com/v1/public/api-catalog | python3 -m json.tool | head -40
curl -sO https://cloud.example.com/v1/public/openapi.yamlВ Postman выберите Import › Link и вставьте https://cloud.example.com/v1/public/postman.json. На странице справочника также доступны однофайловые клиенты API для JavaScript и Python.
Аутентификация
Передавайте ключ в заголовке Authorization:
bash
curl -s https://cloud.example.com/v1/billing/wallet \
-H "Authorization: Bearer vk_XXXX"- Ключи клиентов начинаются с
vk_. Ключи привязаны к сайту: ключ, созданный наcloud.example.com, не работает на домене реселлера. - Токены сессий браузера (
pt_...) предназначены только для портала; для автоматизации используйте ключ. - Scopes ключа определяют доступные операции; при отсутствии scope возвращается HTTP 403
scope_required. См. API keys. - Проверить ключ можно с помощью
GET /v1/apikeys/self: запрос возвращает имя ключа, scopes, срок действия и остаток лимита запросов (доступно любому ключу).
Примеры
bash
# List virtual machines
curl -s "https://cloud.example.com/v1/vm?page=1" -H "Authorization: Bearer vk_XXXX"
# Start one (needs vm:write)
curl -s -X POST https://cloud.example.com/v1/vm/3f2a1c9e-0000-4000-8000-000000000000/start \
-H "Authorization: Bearer vk_XXXX"
# Create a VM (paid: needs vm:create and an Idempotency-Key)
curl -s -X POST https://cloud.example.com/v1/vm \
-H "Authorization: Bearer vk_XXXX" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d @vm.jsonТочные поля запроса для каждой операции приведены в /apidoc.
Ошибки
Каждая ошибка возвращается в формате JSON со стабильным code и понятным сообщением message:
json
{"error": {"code": "scope_required", "message": "Key lacks scope vm:write"}}| HTTP | Типичный code | Значение |
|---|---|---|
| 401 | unauthenticated, key_invalid, key_revoked, key_expired, key_ip_denied, site_mismatch, api_keys_disabled | Ключ отсутствует, неизвестен, отозван или просрочен; IP клиента вне белого списка ключа; ключ от другого сайта или API keys отключены. |
| 403 | scope_required, endpoint_not_public, account_blocked, quota_exceeded, impersonate_forbidden | У ключа нет нужного scope; эндпоинт недоступен для ключей; аккаунт заблокирован; достигнута квота; действие запрещено в сессии подмены пользователя. |
| 404 | not_found | Не найдено — также возвращается для ресурсов других пользователей. |
| 422 | invalid_argument | Ошибка валидации (поле указано в ответе). |
| 429 | rate_limited | Слишком много запросов; подождите до Retry-After. |
| 503 | maintenance | Включён режим обслуживания: чтение работает, операции записи отклоняются. |
Лимиты запросов
| Лимит | По умолчанию |
|---|---|
| На ключ | 120 запросов в минуту |
| На аккаунт (все ключи суммарно) | 300 запросов в минуту |
Каждый ответ содержит X-RateLimit-Limit, X-RateLimit-Remaining и X-RateLimit-Reset; при ошибке 429 добавляется Retry-After.
Идемпотентность
Для платных и неповторяемых команд (создание, смена тарифа, покупка, удаление и т. д.) требуется заголовок Idempotency-Key (любая строка до 200 символов; отлично подходит UUID). Отправьте тот же ключ повторно после таймаута, и сервер вернёт исходный результат (с заголовком Idempotency-Replayed: 1) вместо повторного выполнения операции. Повторное использование ключа для другой команды возвращает 422; если запрос ещё обрабатывается, возвращается 409/Retry-After. Без этого заголовка платный вызов отклоняется.
Проверка
Создайте ключ со scope
vm:readв портале (API keys › Create key).Выполните:
bashcurl -i https://cloud.example.com/v1/apikeys/self -H "Authorization: Bearer vk_XXXX"Вы получите HTTP 200 и заголовки с лимитами запросов.
curl -s https://cloud.example.com/v1/vm -H "Authorization: Bearer vk_XXXX"возвращает список VM аккаунта. В портале вызовы отображаются в столбце ключа Last used и в Key usage log.
Ограничения и примечания
- Недоступно через ключ: пополнение баланса, вывод средств, изменение карт или автопополнения, смена пароля, e-mail или 2FA, удаление аккаунта, создание, редактирование и отзыв других ключей. Для этих действий требуется активная сессия в браузере.
- Скрытые модули: в справочнике и документе OpenAPI отображаются только те возможности, которые включены на данном сайте.
- Размер ответа и пагинация: эндпоинты со списками используют пагинацию (
page,per_page); точные параметры для каждого эндпоинта смотрите в документе OpenAPI. - Время и суммы: суммы указываются в центах USD, если в названии поля не указано иное.
- Admin API: в консоли администратора есть собственный раздел System › Admin › API и ключи администратора (
ofw_...) для управления системой; они отделены от описанного здесь API клиента. - Версионирование: префикс пути
/v1стабилен; в ответы могут добавляться новые поля.
Устранение неполадок
| Симптом | Причина | Решение |
|---|---|---|
| 401 при использовании нового ключа | Ключ от другого домена, истек или введен с пробелами | Создайте ключ на вызываемом домене; проверьте заголовок Authorization: Bearer vk_.... |
403 scope_required | Отсутствует scope | Отредактируйте ключ в портале и добавьте scope. |
401 key_ip_denied или site_mismatch | Ключ ограничен другими IP-адресами («allowed IPs») или создан на другом домене | Добавьте IP-адрес своего сервера в разрешенные IP ключа или обращайтесь к домену, на котором он был создан. |
| 404 для существующей VM | VM принадлежит другому аккаунту | Используйте ключ владельца. |
400/422 с требованием Idempotency-Key | Платная операция без заголовка | Добавьте Idempotency-Key: <uuid>. |
| 429 | Превышен лимит | Снизьте частоту запросов; используйте Retry-After. |
/apidoc возвращает меньше данных, чем ожидалось | Модуль отключен | Включите модуль в License & updates. |