Документация / API
API для VPS
Заказ, управление и продление VPS из своего кода.
Через API можно заказывать VPS, управлять ими и продлевать их из своего кода: панели реселлера, бота, скрипта. Ещё API показывает баланс и историю операций. Домены, DNS и правила защиты через API не управляются — только в панели. Для доступа нужен токен.
Основы
- Адрес:
https://turtleguard.cloud/api/v1. - Заголовок в каждом запросе:
Authorization: Bearer crp_.... - Тела запросов и ответов — JSON. Создание сервера и остальные действия отвечают
200. - Деньги — целое число в минимальных единицах валюты из соседнего поля
currency: для долларов это центы. - Время — строки RFC 3339, идентификаторы — UUID.
- В каждом ответе есть заголовок
X-Request-Id. Приложите его, когда пишете в поддержку о конкретном запросе.
curl -s -H "Authorization: Bearer $TOKEN" https://turtleguard.cloud/api/v1/cloud/vmsПроверить токен можно запросом GET /auth/me: в ответе будут аккаунт, "auth": "token" и права токена в scopes.
Описание OpenAPI
Полное описание всех методов, полей и ответов — в файле https://turtleguard.cloud/api/v1/openapi.json (OpenAPI 3.1, доступен без токена). Его можно импортировать в Postman или Insomnia или сгенерировать по нему клиент для своего языка. Если эта страница и файл расходятся, верен файл.
Что доступно токену
- Все методы
/cloud/…из этой страницы. GET /billing/balanceиGET /billing/transactions.GET /auth/meиGET /openapi.json.
На любой другой адрес токен получит 403 с кодом auth.token_area. Пополнить баланс, сменить пароль аккаунта, выпустить или отозвать токен через API нельзя: это делается в кабинете.
Каждому методу нужно одно из трёх прав: cloud:read — смотреть серверы, cloud:write — заказывать и менять их, billing:read — видеть баланс и операции. Тарифы и образы (GET /cloud/plans, GET /cloud/cloud-images) отдаются и без токена.
Лимиты
| Что считаем | Сколько можно |
|---|---|
| Все запросы одного токена | 300 в минуту |
Запросы, которые что-то меняют (всё, кроме GET) | 30 в минуту |
Сверх лимита API отвечает 429 с кодом rate_limited и заголовком Retry-After — через столько секунд можно повторить. Лимиты считаются на каждый токен отдельно.
Не опрашивайте слишком часто
Пока сервер создаётся, проверять его статус раз в 5–10 секунд достаточно. Список серверов уже содержит последние показатели нагрузки, отдельно запрашивать каждый сервер не нужно.
Ошибки
{"error": {"code": "billing.insufficient_funds", "message": "..."}}code не меняется между версиями, по нему и стоит разбирать ответ. message — подсказка на английском. При ошибке в данных добавляется field с именем поля. Если тело запроса не является корректным JSON для метода, ответ будет простым текстом с кодом 400, 415 или 422.
| Статус | Когда | Примеры code |
|---|---|---|
401 | Токена нет, он неверный, истёк или отозван | auth.required, auth.invalid_token |
402 | Не хватает денег на балансе или сервер приостановлен за неоплату | billing.insufficient_funds, cloud.suspended |
403 | У токена нет нужных прав, адрес недоступен токенам, сервер остановлен за нарушение правил, почта не подтверждена | auth.scope, auth.token_area, cloud.abuse_stopped, auth.email_not_confirmed |
404 | Сервера нет или он принадлежит другому аккаунту; неизвестное действие | not_found |
409 | Действие сейчас невозможно: сервер занят, нет мест или свободных адресов, исчерпан лимит, повтор того же платного запроса | cloud.vm_busy, cloud.no_capacity, cloud.ip_pool_empty, cloud.duplicate_order, cloud.renew_duplicate, cloud.ip_change_cooldown, cloud.ip_change_vm_daily, cloud.ip_change_user_daily, cloud.snapshot_limit |
422 | Ошибка в данных, поле указано в field | validation.hostname, validation.password_too_short, cloud.invalid_ssh_key, cloud.image_unavailable, cloud.image_too_big |
429 | Превышен лимит запросов, ждать столько секунд, сколько в Retry-After | rate_limited |
«Сервер занят» (cloud.vm_busy) значит, что он создаётся, переустанавливается, переезжает или удаляется. Дождитесь, пока статус сменится, и повторите.
Тарифы и образы
| Метод | Что делает | Права |
|---|---|---|
GET /cloud/plans | Локации (countries), активные тарифы (plans) и цены за ядро, гигабайт памяти и диска для своей конфигурации (unit_prices) | не нужны |
GET /cloud/cloud-images | Доступные образы ОС, по строке на каждый os_key | не нужны |
- Заказывать можно в локациях с
"available": true. Код локации — полеcode, напримерde. - У тарифа цена за период —
price_monthly. Если для локации задана своя цена, она лежит вcountry_pricesпо коду локации.traffic_gb: null— трафик не ограничен. - Цены в
unit_pricesданы в миллионных долях валюты за месяц, там же пределы:min_cpu…max_disk_gb.
Заказ сервера
| Метод | Что делает | Права |
|---|---|---|
POST /cloud/vms | Заказать VPS: первый период списывается с баланса, сервер создаётся в фоне | cloud:write |
curl -s -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"plan_id": "6f1c2b9e-4d1a-4c47-9b52-1f0e7a3d8c21", "region": "de", "os_key": "ubuntu-24.04",
"hostname": "client-42", "root_password": "q7-Lm2vX9rTp", "idempotency_key": "order-1042"}' \
https://turtleguard.cloud/api/v1/cloud/vms| Поле | Что передать |
|---|---|
hostname | Обязательно. Имя сервера: латиница, цифры, дефис и точки |
root_password | Обязательно. Пароль root, от 8 до 128 символов |
plan_id | UUID тарифа из /cloud/plans. "custom", null или пропуск — своя конфигурация |
cpu, ram_gb, disk_gb | Только для своей конфигурации: ядра, память и диск в ГБ |
region | Код локации. Без него — первая доступная |
os_key | Образ из /cloud/cloud-images |
ssh_key | Строки authorized_keys (ssh-ed25519, ssh-rsa, ecdsa-…), до 32 ключей, по одному на строку |
idempotency_key | Ваш номер заказа, чтобы повтор не списал деньги дважды |
В ответе: vm_id, hostname, выданный адрес ip, списанная сумма price с currency и duplicate. Сервер появляется сразу со статусом creating и переходит в running, когда готов. Если создать его не получилось, деньги возвращаются на баланс.
Для заказа нужна подтверждённая почта аккаунта. Не хватает денег — 402, нет места в локации или свободного адреса — 409 с cloud.no_capacity или cloud.ip_pool_empty.
Повтор без двойного списания
Если ответ на заказ потерялся — оборвалась связь, истёк таймаут, — повторите тот же запрос с тем же idempotency_key. Второго сервера не будет: API вернёт первый заказ с "duplicate": true. Ключ любой непустой, он действует в пределах вашего аккаунта; удобно брать номер заказа из своей системы. Без ключа каждый запрос — новый заказ и новое списание.
Список и данные сервера
| Метод | Что делает | Права |
|---|---|---|
GET /cloud/vms | Ваши VPS с последними показателями нагрузки. Серверы приложений из маркета сюда не попадают | cloud:read |
GET /cloud/vms/{id} | Сервер целиком: параметры (vm), нагрузка (live), свежесть данных, последние 50 действий, пароль root | cloud:read |
Главное в vm: status, адреса public_ipv4 и ipv6, expires_at — до какого числа оплачен, auto_renew, price_monthly, трафик за период traffic_in и traffic_out в байтах. Пароль root лежит в root_password — последний заданный; пустая строка, если он неизвестен.
| Статус | Что значит |
|---|---|
creating | Сервер создаётся |
running, stopped | Включён или выключен |
suspended | Приостановлен: срок кончился, а денег на продление не было |
reinstalling, migrating | Переустанавливается или переезжает на другой узел |
deleting, error | Удаляется или создание не удалось |
Питание и удаление
| Метод | Что делает | Права |
|---|---|---|
POST /cloud/vms/{id}/start | Включить | cloud:write |
POST /cloud/vms/{id}/shutdown | Выключить штатно, через ОС | cloud:write |
POST /cloud/vms/{id}/stop | Выключить сразу, как кнопкой питания | cloud:write |
POST /cloud/vms/{id}/reboot | Перезагрузить через ОС | cloud:write |
POST /cloud/vms/{id}/reset | Жёсткий сброс | cloud:write |
POST /cloud/vms/{id}/destroy | Удалить сервер вместе с дисками. Оплаченный остаток не возвращается | cloud:write |
Запрос ждёт, пока действие выполнится, и возвращает новый статус: {"ok": true, "action": "reboot", "status": "running"}. Включить приостановленный за неоплату сервер нельзя (402) — сначала продлите его. Остановленный за нарушение правил — тоже (403).
Переустановка
| Метод | Что делает | Права |
|---|---|---|
POST /cloud/vms/{id}/reinstall | Поставить систему заново из образа с новым паролем root. Данные на диске стираются | cloud:write |
Тело: os_key и root_password обязательны, ssh_key — по желанию. Переустановка идёт в фоне, на это время статус — reinstalling. У приложений и игровых серверов os_key не учитывается: контейнер пересоздаётся из того же образа, и приложение ставится заново с текущими настройками.
Пароль и SSH-ключи
| Метод | Что делает | Права |
|---|---|---|
POST /cloud/vms/{id}/password | Сменить пароль root: {"password": "..."}, от 8 до 128 символов | cloud:write |
POST /cloud/vms/{id}/sshkeys | Заменить SSH-ключи: {"keys": "..."}, строки authorized_keys, до 32. Пустая строка удаляет все ключи. В ответе — сколько ключей сохранено | cloud:write |
Пароль и ключи записываются через cloud-init. У включённого сервера пароль меняется ещё и через гостевого агента, в фоне.
Смена IP
| Метод | Что делает | Права |
|---|---|---|
POST /cloud/vms/{id}/change-ip | Выдать серверу новый публичный IPv4 | cloud:write |
- Смена платная, цена указана в панели на странице сервера. Деньги списываются с баланса, сумма приходит в ответе в
charged. Не хватает денег —402. - Включённый сервер перезапускается, чтобы получить новый адрес.
- Между сменами на одном сервере — не меньше 60 секунд, иначе
409 cloud.ip_change_cooldown. - Число смен за последние 24 часа ограничено — отдельно на сервер (
cloud.ip_change_vm_daily) и на весь аккаунт (cloud.ip_change_user_daily). - В ответе старый адрес
old_ipи новыйip. Еслиapply_errorне пустой, адрес выдан, но применить его на узле сразу не вышло — мы повторим сами.
Смена тарифа и конфигурации
| Метод | Что делает | Права |
|---|---|---|
GET /cloud/vms/{id}/upgrades | Тарифы больше текущего: новая цена и сколько доплатить сейчас, плюс баланс | cloud:read |
POST /cloud/vms/{id}/upgrade | Перейти на больший тариф: {"plan_id": "..."} | cloud:write |
POST /cloud/vms/{id}/resize | Задать свою конфигурацию: {"cpu": 4, "ram_gb": 8, "disk_gb": 80} | cloud:write |
При переходе на тариф доплата считается за всё оплаченное время, а не только за текущий месяц: разница в цене × оставшиеся дни ÷ дни периода. Начатый день считается целым. Если сервер продлён на несколько периодов вперёд, доплата будет за все. Сумма к оплате видна заранее в charge_now у каждого варианта из /upgrades, там же days_left и period_days. Перейти на меньший тариф нельзя.
Своя конфигурация считается по ценам за ядро, память и диск в локации сервера. Если она дороже прежней, разница в цене за период списывается сразу; если дешевле, ничего не списываем и не возвращаем, новая цена действует с продления. Диск можно только увеличить.
В обоих случаях включённый сервер перезапускается ("restarting": true в ответе). Не хватает денег — 402. Серверы приложений из маркета так не меняются.
Продление
| Метод | Что делает | Права |
|---|---|---|
POST /cloud/vms/{id}/renew | Продлить на один период с баланса. Необязательное тело {"token": "…", "confirm": false}: повтор с тем же token (8–64 символа A-Z a-z 0-9 _ -) не спишет деньги второй раз. Второе ручное продление того же сервера в течение минуты отклоняется с 409 cloud.renew_duplicate, если не передать "confirm": true | cloud:write |
PATCH /cloud/vms/{id}/auto-renew | Включить или выключить автопродление: {"on": true} | cloud:write |
- Продление привязано к текущей дате окончания: повтор того же запроса не спишет деньги второй раз, а вернёт
"duplicate": trueи"charged": 0. Новая дата — вexpires_at. - Приостановленный за неоплату сервер после продления включается сам.
- С автопродлением деньги списываются с баланса в день окончания срока.
- Если в этот день денег не хватает, сервер выключается и получает статус
suspended. Пополните баланс в течение льготного срока — сервер продлится и включится сам, иначе будет удалён.
Снимки
| Метод | Что делает | Права |
|---|---|---|
GET /cloud/vms/{id}/snapshots | Снимки сервера, лимит на сервер (max) и свежесть данных | cloud:read |
POST /cloud/vms/{id}/snapshots | Сделать снимок, по желанию с подписью: {"description": "..."}, до 120 символов. В ответе — имя снимка | cloud:write |
DELETE /cloud/vms/{id}/snapshots/{name} | Удалить снимок | cloud:write |
POST /cloud/vms/{id}/snapshots/{name}/rollback | Откатить сервер к снимку: он выключится, откатится и включится снова | cloud:write |
Создание и удаление идут в фоне, список обновляется не сразу. Когда снимков уже max, новый не создаётся: 409 cloud.snapshot_limit. POST /cloud/vms/{id}/snapshot — то же, что POST …/snapshots.
Режим восстановления
| Метод | Что делает | Права |
|---|---|---|
POST /cloud/vms/{id}/rescue | Включить или выключить загрузку с диска восстановления. Каждый вызов переключает режим, новое состояние — в rescue | cloud:write |
Нужен, когда система не загружается. Сервер перезапускается и грузится с образа восстановления, ваш диск остаётся подключённым: его можно смонтировать и починить. Повторный вызов возвращает обычную загрузку, сервер снова перезапускается.
Консоль
| Метод | Что делает | Права |
|---|---|---|
GET /cloud/vms/{id}/console | Одноразовый пропуск в консоль VNC: token, пароль VNC password и срок expires_in — 120 секунд | cloud:write |
С пропуском откройте websocket wss://turtleguard.cloud/api/v1/vnc/{token} (подпротокол binary), например через noVNC, и введите password. Пропуск срабатывает один раз. Заголовок Authorization к этому подключению не добавляйте: пропуск уже в адресе, а с токеном адрес ответит 403.
Графики нагрузки
| Метод | Что делает | Права |
|---|---|---|
GET /cloud/vms/{id}/metrics?timeframe=day | Точки для графиков за hour, day (по умолчанию), week, month или year | cloud:read |
Каждая точка — время time в секундах Unix и значения cpu, mem, maxmem, disk, maxdisk, netin, netout (сеть — байты в секунду).
Название и комментарий
| Метод | Что делает | Права |
|---|---|---|
PATCH /cloud/vms/{id}/profile | Изменить название, цвет или картинку и комментарий сервера | cloud:write |
Поля: name — до 64 символов, comment — до 200, avatar — цвет #rrggbb или картинка data:image/... до 400 000 байт. Пустая строка очищает поле, не переданные поля остаются как были. В данных сервера они видны как display_name, comment и avatar.
Баланс и операции
| Метод | Что делает | Права |
|---|---|---|
GET /billing/balance | Баланс в основной валюте (currency, balance) и все счета в других валютах (accounts) | billing:read |
GET /billing/transactions?page=1&per_page=50 | Операции по балансу, новые сверху. per_page — от 1 до 500 | billing:read |
У операции: сумма amount (списание — со знаком минус), остаток после неё balance_after, тип kind (например, cloud_vm — заказ, продление или смена тарифа сервера, cloud_ip — смена IP, topup — пополнение), описание и ref_id — к какому серверу она относится. Пополнять баланс через API нельзя, только в кабинете.
Для реселлеров
Обычный порядок, если вы продаёте наши VPS своим клиентам:
- Проверьте баланс:
GET /billing/balance. Заказ и продление списываются с него. - Возьмите тарифы, локации и образы:
GET /cloud/plansиGET /cloud/cloud-images. - Закажите сервер:
POST /cloud/vmsсidempotency_key= номер заказа в вашей системе. При сетевой ошибке повторяйте с тем же ключом. - Опрашивайте
GET /cloud/vms/{vm_id}, покаstatusне станетrunning. - Отдайте клиенту адрес из
public_ipv4и пароль root — тот, что вы задали при заказе, он же вroot_password. - Подпишите сервер:
PATCH /cloud/vms/{id}/profileс именем клиента вnameи номером договора или контактом вcomment. Название показывается в панели вместо имени сервера, комментарий виден в данных сервера через API. - Следите за сроком по
expires_at: продлевайте черезPOST /cloud/vms/{id}/renew, когда клиент заплатил, или включите автопродление и держите на балансе запас.
Для этого нужен токен «Управление VPS». Для витрины, которая только показывает клиентам состояние серверов, хватит токена «Только чтение».