API d'auteur de modpack : codes d'activation et mises à jour
Comment un auteur de modpack payant peut émettre des codes d'activation et publier des mises à jour via l'API Millida Hosting : versions du modpack, envoi de l'archive, publication, retour arrière, statut des codes et webhook.
Mis à jour le 6 septembre 2026
Vous n'avez pas à écrire de code. Tout ce qui est décrit ci-dessous est désormais disponible sous forme de boutons : si votre modpack est lié à votre compte Millida, un onglet « Mes modpacks » apparaît dans votre profil — vous y téléversez des versions, modifiez la fiche et créez des landing pages. Pas de lien — écrivez-nous et nous le ferons. L'API s'adresse à ceux qui déploient depuis leur propre CI.
Cet article est destiné aux auteurs de modpacks payants qui les vendent eux-mêmes et nous confient l'installation du serveur. L'acheteur n'a rien à télécharger : il saisit un code et obtient un modpack déployé. Pour voir à quoi cela ressemble de son côté, lisez Modpack payant via code d'activation.
Ce qu'il vous faut pour commencer
- Envoyez-nous l'archive serveur de votre modpack — un
.zipavecmods/à la racine (sans dossier englobant du typeServer Files/) ou un.mrpack. L'archive est stockée dans notre espace privé, et le lien n'est jamais partagé à l'extérieur. - Indiquez-nous le core, la version du jeu et la mémoire minimale — l'assistant s'en sert pour écarter les offres sur lesquelles le modpack ne tournera pas.
- Obtenez de notre part une clé de modpack (
key, par exemplearcania) et un token d'émission — votre site s'en sert pour générer des codes.
Le token n'est affiché qu'une seule fois : nous ne conservons que son empreinte. Si vous le perdez, demandez-nous de le réémettre — l'ancien cessera de fonctionner.
Comment fonctionne le schéma
- Vous encaissez le paiement vous-même, de votre côté.
- Après le paiement, votre site appelle notre API et obtient un code d'activation.
- Vous transmettez le code à l'acheteur — par e-mail, bot ou sur la page « merci ».
- L'acheteur saisit le code chez nous et obtient un serveur avec le modpack sur une offre payante.
- Les fichiers du modpack sur le serveur sont verrouillés :
modsne peut être téléchargé ni depuis le panneau, ni via SFTP.
Concrètement, l'acheteur n'a jamais le modpack serveur entre les mains — seulement un serveur fonctionnel.
Point d'accès et autorisation
URL de base — https://millida.net/v2/hosting.
Le token est transmis dans l'en-tête X-Pack-Token. Ce n'est ni un JWT ni un Bearer token — c'est un secret distinct pour votre modpack.
X-Pack-Token: mpk_pack_XXXXXXXXXXXXXXXX
Content-Type: application/json
Le token réside sur votre serveur — gardez-le dans des variables d'environnement, pas dans le code frontend.
Émettre des codes
POST /v2/hosting/packs/{key}/keys
| Champ | Type | Par défaut | Ce qu'il fait |
|---|---|---|---|
count | nombre 1–200 | 1 | Combien de codes générer par appel |
note | chaîne jusqu'à 120 | — | Votre note : numéro de commande, pseudo de l'acheteur |
maxServers | nombre 1–20 | 1 | Sur combien de serveurs un code peut être activé |
expiresAt | date ISO | — | Date d'expiration du code |
curl -X POST https://millida.net/v2/hosting/packs/arcania/keys \
-H "X-Pack-Token: $PACK_TOKEN" \
-H "Content-Type: application/json" \
-d '{"count": 1, "note": "order 4821"}'
{
"code": "A7K2-9MHD-4RTP-QW38",
"codes": ["A7K2-9MHD-4RTP-QW38"]
}
Le champ code correspond au premier code du lot, conservé pour la compatibilité ; lorsque count > 1, utilisez codes.
Les codes ne sont renvoyés qu'ici et nulle part ailleurs. Nous stockons leur hash — comme un mot de passe. Si vous perdez un code, nous ne pouvons pas le récupérer : émettez-en un nouveau et révoquez l'ancien.
La limite est de 30 requêtes par minute par modpack. Les lots allant jusqu'à 200 codes par appel existent précisément pour les ventes : générez-les en masse plutôt qu'un code par requête.
Ce qu'il est advenu des codes
GET /v2/hosting/packs/{key}/keys?limit=100
[
{
"codeHint": "A7K29MHD",
"note": "order 4821",
"maxServers": 1,
"usedCount": 1,
"state": "spent",
"expiresAt": null,
"revokedAt": null,
"createdAt": "2026-08-03T12:20:11.000Z"
}
]
Les codes eux-mêmes ne figurent pas dans la réponse et ne le peuvent pas. codeHint correspond au début du code — utilisez-le pour rattacher la ligne à votre commande.
États : free — inutilisé, spent — utilisé, expired — expiré, revoked — révoqué par vous.
Vérifier un code
POST /v2/hosting/packs/{key}/keys/status, corps {"code": "A7K2-9MHD-4RTP-QW38"}.
La réponse est la même ligne que dans la liste. Le code se place dans le corps, pas dans l'URL : les URL finissent dans les logs des proxys et l'historique du navigateur, et avant activation, le code est une clé fonctionnelle.
Les tirets et la casse n'ont pas d'importance : a7k29mhd4rtpqw38 sera trouvé exactement comme A7K2-9MHD-4RTP-QW38.
Révoquer un code
POST /v2/hosting/packs/{key}/keys/revoke, corps {"code": "..."}.
À utiliser pour les remboursements, les émissions erronées ou les litiges. La révocation bloque les activations futures mais ne supprime pas un modpack déjà déployé — un acheteur qui l'a activé conserve un serveur fonctionnel.
Webhook d'activation
Si vous nous fournissez une URL de webhook, nous l'appellerons au moment où un code est utilisé :
POST <your-address>
X-Millida-Pack: arcania
Content-Type: application/json
{
"event": "pack.activated",
"packKey": "arcania",
"codeHint": "A7K29MHD",
"serverId": "cm4x...",
"activatedAt": "2026-08-04T09:14:02.000Z"
}
L'appel n'est pas signé : vous pouvez le vérifier avec le même token via keys/status — grâce à codeHint, vous retrouverez votre ligne et verrez state: "spent". Ainsi, vous n'avez pas à stocker un second secret.
Le webhook est envoyé sans attendre de réponse et n'est pas réessayé : si votre serveur était indisponible, l'activation a tout de même eu lieu, et vous pouvez le constater dans la liste des codes. L'URL doit être publique — nous n'appelons pas les adresses internes ou locales. Les redirections ne sont pas suivies.
Fiche du modpack
GET /v2/hosting/packs/{key} est public, aucun token n'est nécessaire. Il renvoie ce que voit l'acheteur : nom, core, version, mémoire minimale, liste des offres et indicateurs de protection. La réponse ne contient aucun lien vers l'archive.
Pratique pour la page « Acheter » de votre site : les prérequis des offres proviennent d'une source unique et ne divergeront pas de ce qu'indique notre assistant.
Vous modifiez vous-même les champs vitrine de votre fiche : PATCH /v2/hosting/packs/{key} avec le token accepte name, authorName, authorUrl, iconUrl, webhookUrl. Les conditions de vente (paidOnly, requireKey, lockFiles, planCodes), l'activation du modpack dans la vitrine et les flags de lancement JVM ne peuvent pas être modifiés avec le token — ils relèvent de notre accord avec vous et de nos nœuds, écrivez-nous à ce sujet.
Mises à jour du modpack
Auparavant, une mise à jour signifiait nous écrire et attendre. Désormais, vous publiez une version vous-même, et les propriétaires de serveurs la choisissent dans leur panneau.
Le point essentiel : nous ne mettons jamais à jour qui que ce soit en silence. Le passage d'une version de modpack à une autre peut être incompatible avec le monde, et c'est le propriétaire du serveur qui décide. La version publiée est celle que reçoivent les nouveaux serveurs et celle que nous proposons à ceux déjà déployés ; les versions précédentes restent dans la liste, et vous pouvez y rester ou revenir en arrière.
À quoi ressemble le cycle
# 1. Create a version
curl -X POST https://millida.net/v2/hosting/packs/arcania/versions \
-H "X-Pack-Token: $PACK_TOKEN" -H "Content-Type: application/json" \
-d '{"label":"1.5.0","changelog":"Updated Create to 0.5.1, fixes crash on portals","minRamMb":10240}'
# 2. Upload the archive in chunks (32 MB each), addressing by offset
curl -X POST "https://millida.net/v2/hosting/packs/arcania/versions/1.5.0/archive?offset=0" \
-H "X-Pack-Token: $PACK_TOKEN" -H "Content-Type: application/octet-stream" \
--data-binary @part0.bin
# 3. Say the archive is finished, and publish after parsing
curl -X POST https://millida.net/v2/hosting/packs/arcania/versions/1.5.0/finish \
-H "X-Pack-Token: $PACK_TOKEN" -H "Content-Type: application/json" \
-d '{"archiveSha256":"<sha256 of archive>","publish":true}'
# 4. Wait for parsing
curl https://millida.net/v2/hosting/packs/arcania/versions/1.5.0 -H "X-Pack-Token: $PACK_TOKEN"
Version
| Champ | Type | Ce qu'il fait |
|---|---|---|
label | chaîne jusqu'à 40 | Numéro de version : lettres latines, chiffres, point, tiret, underscore. Immuable : le même label avec des fichiers différents transforme l'analyse d'une réclamation en devinette |
changelog | chaîne jusqu'à 4000 | Ce qui a changé — le propriétaire du serveur le lit avant de mettre à jour |
core, gameVersion | chaînes | Si la configuration de serveur est passée à un autre core ou à une autre version du jeu |
loaderBuild, javaVersion | chaînes | Épinglage de la build du loader et de Java, si la version le nécessite |
minRamMb | nombre | Mémoire minimale pour cette version précise. Celui qui n'en a pas assez verra la raison et ne perdra pas son monde |
archiveSha256 | hex 64 | Nous vérifions avant l'analyse : mieux vaut rejeter une archive arrivée incomplète que la décompresser à moitié |
Upload
POST /v2/hosting/packs/{key}/versions/{label}/archive?offset=N, corps — un morceau de .zip, Content-Type: application/octet-stream. Morceau jusqu'à 32 Mo, archive complète jusqu'à 4 Go.
Un morceau est adressé par offset, pas par « ajout à la fin » : un morceau interrompu en cours de route s'est déjà partiellement écrit dans le fichier, et une nouvelle tentative ajouterait les mêmes octets une seconde fois — l'archive arriverait silencieusement corrompue. La réponse renvoie uploadedBytes, qui sert à reprendre l'upload après une interruption.
Analyse
POST .../finish répond immédiatement (status: "processing"), tandis que l'analyse s'exécute en arrière-plan : décompresser une configuration de serveur d'un gigaoctet prend des minutes. Lisez l'état via GET .../versions/{label} : processing → ready ou failed avec le texte de la raison dans error.
Ce que l'archive doit passer :
- c'est un pack serveur : après suppression de l'unique dossier enveloppe (
Server Files/et similaires),mods/ouplugins/se trouve à la racine. Un pack client sur un serveur produit un monde vide, nous le rejetons donc au lieu de l'installer ; - pas de
.., de chemins absolus ni de séparateurs Windows dans les noms à l'intérieur de l'archive ; - pas de mot de passe, pas de méthodes de compression exotiques (uniquement store et deflate) ;
- limites : 60 000 fichiers, 12 Go décompressés, taux de compression jusqu'à 200×.
Un échec n'affecte pas la version publiée : vos clients continuent d'utiliser la précédente, et vous uploadez à nouveau. Brouillons inachevés : pas plus de trois par configuration de serveur, les abandonnés sont nettoyés automatiquement au bout d'un jour.
Publication, rollback et suppression
| Requête | Ce qu'elle fait |
|---|---|
POST .../versions/{label}/publish | Rend la version publiée. C'est aussi ainsi que se fait le rollback : publiez la précédente — les nouveaux serveurs la reçoivent à nouveau |
POST .../versions/{label}/archive-version | Retire la version de la sélection. Ceux qui l'ont déjà la conservent |
PATCH .../versions/{label} | Modifie la description d'une version déjà créée : changelog et minRamMb. Les fichiers de version sont immuables, donc le core, le loader et Java ne changent pas |
DELETE .../versions/{label} | Supprime la version ainsi que ses fichiers. Vous ne pouvez pas supprimer une version publiée ni une version présente sur au moins un serveur |
GET .../versions | Versions disponibles pour la sélection (publiques, sans token) |
GET .../versions/all | Tout ce qui vous appartient, y compris les brouillons et les échecs |
GET .../versions/rollout | Combien de serveurs sont sur quelle version — vous voyez comment la mise à jour se déploie |
La publication transfère le core, la version du jeu, l'épinglage du loader, Java et la mémoire minimale de la version dans la fiche de la configuration de serveur : les nouveaux serveurs l'obtiennent sans aucune action de votre part.
Ce que voit le propriétaire du serveur
Dans le panneau, dans le bloc de configuration de serveur premium : quelle version est installée, laquelle a été publiée, votre changelog, et une liste de versions avec un bouton « Changer ». La mise à jour n'affecte pas le monde — seuls les fichiers de la configuration de serveur sont remplacés, et nous en prenons une copie avant remplacement. Les mods personnalisés, si vous les avez autorisés, devront être ajoutés à nouveau après le changement : la configuration de serveur se déplace comme un tout, et la moitié de l'ancienne version dans mods/ signifie un crash au démarrage.
Si l'offre du propriétaire ne supporte pas une version, nous l'affichons avec la raison au lieu de la masquer : la personne doit voir ce dont elle a besoin, pas deviner pourquoi la configuration de serveur ne se met pas à jour.
Votre propre page de configuration de serveur
Vous construisez vous-même la landing page de votre configuration de serveur dans votre compte (profil → « Mes configurations de serveur » → « Pages de configuration de serveur ») : le premier écran, les fonctionnalités, les captures d'écran, les questions-réponses, vos couleurs. Les offres et la liste des versions sont remplies avec nos données pour qu'elles ne deviennent pas obsolètes.
La page terminée se trouve à millida.net/sborka/<votre-adresse> — une page de site web classique, indexée par les moteurs de recherche et incluse dans notre sitemap. Le brouillon n'est visible de personne d'autre que vous.
Les images sont uploadées au même endroit, dans votre compte : la page est servie depuis notre domaine et ses fichiers sont stockés chez nous — si votre hébergement tombe, la page reste intacte.
Les pages ne peuvent pas être modifiées via l'API : c'est un écran, pas un déploiement.
Codes de réponse
| Code | Quand | Que faire |
|---|---|---|
403 | Token d'émission invalide | Vérifiez X-Pack-Token. Le token est lié à une seule configuration de serveur : il ne fonctionne pas avec la clé de quelqu'un d'autre |
404 | La configuration de serveur est désactivée, non connectée à l'émission, ou cette version n'existe pas | Écrivez-nous |
400 | La date expiresAt ne peut pas être analysée, label de version incorrect, morceau vide ou trop volumineux | Consultez le texte de l'erreur |
409 | La version est déjà créée, déjà analysée, publiée ou installée sur des serveurs | Les labels sont immuables : publiez la suivante |
429 | Plus de 30 requêtes par minute (upload — 600) | Envoyez par lots, et envoyez des morceaux plus gros |
Comment tout tester avant de vendre
Demandez-nous quelques codes de test : émettez un code via l'API, activez-le sur votre serveur chez notre hébergement, regardez ce qui est arrivé dans le webhook et ce que montre keys/status. Vous verrez ainsi tout le parcours de l'acheteur avant que le premier client payant ne le suive.
