API сервера для ботов
Клиентский API Millida Hosting: выпуск ключа, права, управление сервером и стрим консоли из своего бота или скрипта.
Обновлено 13 октября 2026 г.
Всё, что делает панель, можно делать из своего кода: поднимать сервер по расписанию, показывать статус в Discord, отправлять команды из бота.
Ключ
API доступен на любом платном тарифе — там же, где файлы, SFTP и доступ команде. На бесплатном ключ не выпускается: ключ — это тот же совместный доступ, только для бота.
Раздел «Игроки и доступ» → «API-ключи» → «Выпустить». Отметьте, что ключу разрешено, — права те же, что и у совместного доступа.
Ключ показывается один раз: у нас хранится только его отпечаток. Потеряли — выпустите новый и отзовите старый.
Ключ передаётся заголовком Authorization: Bearer mhk_live_....
Методы
Базовый адрес — https://millida.net/v2/hosting/api.
| Метод | Что делает | Нужное право |
|---|---|---|
GET /server | Карточка сервера | консоль |
GET /status | Статус и онлайн | консоль |
POST /start | Запустить | запуск |
POST /stop | Остановить | запуск |
POST /restart | Перезапустить | запуск |
POST /command | Команда в консоль | консоль |
GET /console | Живой лог (SSE) | консоль |
GET /files?path= | Список файлов | файлы |
GET /files/configs | Какие конфиги читаются формой | файлы |
GET /files/config?path= | Настройки файла с типами | файлы |
POST /files/config | Изменить настройки файла | файлы |
GET /backups | Список копий | копии |
POST /backups | Поставить копию в работу | копии |
GET /antibot | Настройки защиты от ботов, бэкенды и правила файрвола | защита |
PUT /antibot | Изменить настройки защиты | защита |
GET /antibot/overview?range= | Подключения и отказы за hour, day или week | защита |
POST /antibot/backends | Добавить бэкенд {"address":"host:порт","label":"..."} | защита |
DELETE /antibot/backends/{id} | Убрать бэкенд | защита |
POST /antibot/rules | Правило файрвола {"kind":"allow"|"deny","cidr":"1.2.3.0/24"} | защита |
DELETE /antibot/rules/{id} | Убрать правило | защита |
POST /antibot/verify-domain/check | Проверить DNS своего домена страницы проверки | защита |
Пример: поднять сервер и дождаться онлайна
KEY="mhk_live_xxx"
API="https://millida.net/v2/hosting/api"
curl -sX POST "$API/start" -H "Authorization: Bearer $KEY"
until curl -s "$API/status" -H "Authorization: Bearer $KEY" | grep -q RUNNING; do
sleep 5
done
echo "сервер онлайн"
Копии делаются в фоне
POST /backups возвращает {"id":"..."} сразу, а сам архив собирается на ноде: мир на несколько гигабайт — это минуты. Готовность смотрите в GET /backups по полю status: pending — ещё собирается, ready — лежит в хранилище (тогда же появляется реальный sizeMb), failed — не собралась.
ID=$(curl -sX POST "$API/backups" -H "Authorization: Bearer $KEY" | jq -r .id)
until curl -s "$API/backups" -H "Authorization: Bearer $KEY" \
| jq -e --arg id "$ID" '.[] | select(.id==$id) | select(.status=="ready")' >/dev/null; do
sleep 15
done
echo "копия готова"
Пока копия в работе, вторую на том же сервере поставить нельзя — нода делает их по одной.
Живая консоль
GET /console отдаёт поток Server-Sent Events: каждая строка приходит с префиксом data:. Вебсокет не нужен — SSE проходит через любой прокси.
Что стоит знать
- Каждое действие ключа попадает в журнал сервера автором «API-ключ N». Это ровно то, что нужно, когда серверами рулят и люди, и боты.
- Ограничение частоты считается по ключу, а не по адресу: смена IP лимит не обходит, а сосед по офисной сети его не расходует. Оно щедрое для нормальной автоматизации, но опрос статуса раз в секунду в него упрётся — достаточно раз в 10–15 секунд. Стрим консоли открывается до десяти раз в минуту: держите одно соединение, а не открывайте новое на каждое сообщение.
- Ключ перестаёт работать сразу, если сервер приостановлен или тариф больше не платный. Отзывать его руками для этого не нужно.
- Ключей на сервер до пяти. Отзывайте ненужные.
Защита от ботов
GET /antibot отдаёт настройки в двух полях. config — свои настройки сервера; пока их нет, там null, а сервер защищён по умолчанию (поле default). effective есть всегда: это настройки, которые действуют сейчас или с которыми начнёт работать сервер после первой правки, — читайте значения из него.
PUT /antibot принимает только те поля, которые надо поменять:
curl -sX PUT "$API/antibot" -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' -d '{"preset":"balanced"}'
Уровни (preset): off, under_attack, balanced, aggressive, custom. Уровень раскладывается в значения проверок сам, поэтому для ручной настройки выберите custom и пришлите проверки: checkCaptcha, checkPhysics, checkKeepAlive, checkTeleport, checkBrand, checkPing, checkTransfer, checkClientSettings — каждая off, under_attack или always. Списки адресов (vpnMode, datacenterMode, torMode) — off, log или block. Гео-фильтр — geoMode (off, allow, deny) и geoCountries (коды стран, например ["RU","BY"]).
Секрет форвардинга через API не выдаётся и не меняется: он показывается только владельцу в панели.
Настройки конфигов
GET /files/config?path=server.properties отдаёт разобранный файл — каждый пункт с типом, текущим значением и признаком «нужен перезапуск»:
{
"path": "server.properties",
"format": "properties",
"options": [
{ "key": "pvp", "type": "boolean", "value": "true", "owner": "sync", "requiresRestart": false },
{ "key": "difficulty", "type": "select", "value": "normal", "values": ["peaceful", "easy", "normal", "hard"], "owner": "sync", "requiresRestart": false },
{ "key": "server-port", "type": "integer", "value": "25565", "owner": "platform", "requiresRestart": true }
]
}
owner говорит, что с пунктом можно сделать: platform — значение задаёт хостинг, правка отклоняется; sync — пункт есть и в панели, и в файле; file — о нём знает только файл.
Запись меняет только присланные ключи, остальное в файле остаётся нетронутым:
curl -sX POST "$API/files/config" -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' -d '{"path":"server.properties","values":{"pvp":"false","difficulty":"hard"}}'
Формой читаются .properties, .yml/.yaml и .toml — включая конфиги плагинов, о которых панель ничего не знает: тип поля выводится из значения. Вложенные ключи адресуются через точку: settings.bungeecord, advanced.compression-threshold.
Файл целиком по-прежнему доступен через GET/PUT /files/content?path= — оба пути пишут в одно место.
Готовый клиент на Node.js и Python
Ниже — минимальный клиент: проверяет статус, запускает сервер и пишет в чат. Ключ берётся из переменной окружения MILLIDA_KEY — не вставляйте его в код, который попадает в git. Ответ с ошибкой приходит JSON с полем message: его и стоит показывать в логе бота.
Node.js 18+ (встроенный fetch):
const API = 'https://millida.net/v2/hosting/api';
const KEY = process.env.MILLIDA_KEY;
async function call(method, path, body) {
const res = await fetch(`${API}${path}`, {
method,
headers: { Authorization: `Bearer ${KEY}`, 'Content-Type': 'application/json' },
body: body ? JSON.stringify(body) : undefined,
});
if (!res.ok) throw new Error(`${method} ${path}: ${res.status} ${await res.text()}`);
return res.status === 204 ? null : res.json();
}
const status = await call('GET', '/status');
if (status.status !== 'RUNNING') await call('POST', '/start');
await call('POST', '/command', { command: 'say Hello from the bot' });
Python 3 с библиотекой requests, плюс чтение живой консоли:
import os
import requests
API = "https://millida.net/v2/hosting/api"
session = requests.Session()
session.headers["Authorization"] = f"Bearer {os.environ['MILLIDA_KEY']}"
def call(method, path, body=None):
res = session.request(method, API + path, json=body, timeout=15)
res.raise_for_status()
return res.json() if res.content else None
status = call("GET", "/status")
if status["status"] != "RUNNING":
call("POST", "/start")
call("POST", "/command", {"command": "say Hello from the bot"})
with session.get(API + "/console", stream=True, timeout=None) as stream:
for line in stream.iter_lines(decode_unicode=True):
if line and line.startswith("data:"):
print(line[5:].strip())
