API serveur pour les bots
L'API client Millida Hosting : génération d'une clé, permissions, gestion du serveur et streaming de la console depuis votre propre bot ou script.
Mis à jour le 13 octobre 2026
Tout ce que fait le panneau est réalisable depuis votre propre code : démarrer un serveur selon un planning, afficher le statut dans Discord, envoyer des commandes depuis un bot.
Clé
L'API est disponible sur toute offre payante — au même endroit que les fichiers, le SFTP et l'accès d'équipe. Sur l'offre gratuite, aucune clé n'est délivrée : une clé, c'est le même accès partagé, mais pour un bot.
Section « Joueurs et accès » → « Clés API » → « Délivrer ». Vérifiez ce que la clé est autorisée à faire — les permissions sont les mêmes que pour l'accès partagé.
La clé n'est affichée qu'une seule fois : nous ne conservons que son empreinte. Si vous la perdez, délivrez-en une nouvelle et révoquez l'ancienne.
La clé se transmet dans l'en-tête Authorization: Bearer mhk_live_....
Méthodes
URL de base — https://millida.net/v2/hosting/api.
| Méthode | Ce qu'elle fait | Permission requise |
|---|---|---|
GET /server | Fiche du serveur | console |
GET /status | Statut et joueurs en ligne | console |
POST /start | Démarrer | start |
POST /stop | Arrêter | start |
POST /restart | Redémarrer | start |
POST /command | Commande vers la console | console |
GET /console | Journal en direct (SSE) | console |
GET /files?path= | Lister les fichiers | files |
GET /files/configs | Quels fichiers de configuration sont lus par le formulaire | files |
GET /files/config?path= | Paramètres du fichier avec leurs types | files |
POST /files/config | Modifier les paramètres du fichier | files |
GET /backups | Lister les sauvegardes | backups |
POST /backups | Créer une sauvegarde | backups |
GET /antibot | Paramètres anti-bot, backends et règles de pare-feu | protection |
PUT /antibot | Modifier les paramètres de protection | protection |
GET /antibot/overview?range= | Connexions et refus pour hour, day ou week | protection |
POST /antibot/backends | Ajouter un backend {"address":"host:port","label":"..."} | protection |
DELETE /antibot/backends/{id} | Supprimer un backend | protection |
POST /antibot/rules | Règle de pare-feu {"kind":"allow"|"deny","cidr":"1.2.3.0/24"} | protection |
DELETE /antibot/rules/{id} | Supprimer une règle | protection |
POST /antibot/verify-domain/check | Vérifier le DNS du domaine de votre page de vérification | protection |
Exemple : démarrer un serveur et attendre sa mise en ligne
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 "server online"
Les sauvegardes sont créées en arrière-plan
POST /backups renvoie immédiatement {"id":"..."}, tandis que l'archive elle-même est assemblée sur le nœud : un monde de plusieurs gigaoctets prend plusieurs minutes. Vérifiez l'état via GET /backups avec le champ status : pending — assemblage en cours, ready — stockée dans le stockage (c'est alors qu'apparaît le vrai sizeMb), failed — échec de l'assemblage.
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 "backup ready"
Tant qu'une sauvegarde est en cours, vous ne pouvez pas en créer une seconde sur le même serveur — le nœud les traite une par une.
Console en direct
GET /console renvoie un flux Server-Sent Events : chaque ligne arrive avec le préfixe data:. Aucun WebSocket n'est nécessaire — le SSE passe à travers n'importe quel proxy.
Bon à savoir
- Chaque action de la clé est journalisée dans le journal du serveur avec l'auteur « API key N ». C'est exactement ce qu'il vous faut quand des humains et des bots exploitent des serveurs.
- La limitation de débit est calculée par clé, pas par adresse : changer d'IP ne contourne pas la limite, et un voisin sur le réseau du bureau ne la consomme pas. Elle est généreuse pour une automatisation normale, mais interroger le statut une fois par seconde la déclenchera — une fois toutes les 10–15 secondes suffit. Le flux de la console peut être ouvert jusqu'à dix fois par minute : gardez une seule connexion au lieu d'en ouvrir une nouvelle pour chaque message.
- La clé cesse de fonctionner immédiatement si le serveur est suspendu ou si l'offre n'est plus payée. Pas besoin de la révoquer manuellement pour cela.
- Jusqu'à cinq clés par serveur. Révoquez celles dont vous n'avez pas besoin.
Protection anti-bot
GET /antibot renvoie les paramètres dans deux champs. config — les paramètres propres au serveur ; tant qu'ils n'existent pas, c'est null, et le serveur est protégé par défaut (le champ default). effective est toujours présent : ce sont les paramètres actuellement en vigueur ou avec lesquels le serveur fonctionnera après la première modification — lisez les valeurs depuis ce champ.
PUT /antibot n'accepte que les champs que vous souhaitez modifier :
curl -sX PUT "$API/antibot" -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' -d '{"preset":"balanced"}'
Niveaux (preset) : off, under_attack, balanced, aggressive, custom. Le niveau se déploie tout seul en valeurs de vérification, donc pour une configuration manuelle, choisissez custom et envoyez les vérifications : checkCaptcha, checkPhysics, checkKeepAlive, checkTeleport, checkBrand, checkPing, checkTransfer, checkClientSettings — chacune à off, under_attack ou always. Listes d'adresses (vpnMode, datacenterMode, torMode) — off, log ou block. Filtre géographique — geoMode (off, allow, deny) et geoCountries (codes de pays, par ex. ["RU","BY"]).
Le secret de forwarding n'est ni délivré ni modifié via l'API : il n'est montré qu'au propriétaire dans le panneau.
Paramètres de configuration
GET /files/config?path=server.properties renvoie le fichier analysé — chaque entrée avec son type, sa valeur actuelle et un indicateur « redémarrage requis » :
{
"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 vous indique ce qui peut être fait avec l'entrée : platform — la valeur est définie par l'hébergement, les modifications sont rejetées ; sync — l'entrée existe à la fois dans le panneau et dans le fichier ; file — seul le fichier la connaît.
Une écriture ne modifie que les clés que vous envoyez ; tout le reste du fichier reste intact :
curl -sX POST "$API/files/config" -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' -d '{"path":"server.properties","values":{"pvp":"false","difficulty":"hard"}}'
Le formulaire lit les .properties, .yml/.yaml et .toml — y compris les configurations de plugins dont le panneau ignore tout : le type du champ est déduit de la valeur. Les clés imbriquées s'adressent avec un point : settings.bungeecord, advanced.compression-threshold.
Le fichier entier reste accessible via GET/PUT /files/content?path= — les deux chemins écrivent au même endroit.
Client prêt à l'emploi en Node.js et Python
Voici un client minimal : il vérifie le statut, démarre le serveur et écrit dans le chat. La clé provient de la variable d'environnement MILLIDA_KEY — ne la collez pas dans du code qui finit dans git. Une réponse d'erreur est un JSON avec un champ message ; c'est ce que votre bot doit journaliser.
Node.js 18+ (fetch intégré) :
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 avec la bibliothèque requests, plus la lecture de la console en direct :
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())
