整合包作者 API:激活码与更新
付费整合包作者如何通过 Millida Hosting API 发放激活码并发布更新:整合包版本、压缩包上传、发布、回滚、激活码状态以及 webhook。
更新于 2026年9月6日
您不必编写代码。 下文描述的一切现在都可以通过按钮完成:如果您的整合包已关联到 Millida 账户,个人资料中会出现 “我的整合包” 标签页——您可以在那里上传版本、编辑卡片并搭建落地页。尚未关联——请联系我们进行关联。API 则面向从自有 CI 部署的用户。
本文面向自行销售付费整合包、并将服务器安装环节交给我们处理的作者。买家无需下载任何内容:输入激活码即可获得已部署的整合包。想了解买家侧的体验,请阅读通过激活码获取付费整合包。
开始前需要准备什么
- 将整合包的服务器归档发送给我们——根目录下包含
mods/的.zip(不要套一层Server Files/之类的目录)或.mrpack。归档保存在我们的私有存储中,链接绝不对外分享。 - 告知我们核心、游戏版本和最低内存——向导会据此过滤掉整合包无法运行的方案。
- 从我们这里获取整合包密钥(
key,例如arcania)和签发令牌——您的网站用它来生成激活码。
令牌只显示一次:我们只存储其指纹。如果丢失,请联系我们重新签发——旧令牌将失效。
方案如何运作
- 您在自己的侧自行收款。
- 付款完成后,您的网站调用我们的 API 并获取激活码。
- 您将激活码交给买家——通过电子邮件、机器人或“感谢”页面。
- 买家在我们这边输入激活码,即可在付费方案上获得一台装有该整合包的服务器。
- 服务器上的整合包文件受到锁定保护:无法从控制面板或通过 SFTP 下载
mods。
实际上,买家始终拿不到服务器整合包本体——只会得到一台可用的服务器。
接口地址与授权
基础 URL——https://millida.net/v2/hosting。
令牌通过 X-Pack-Token 请求头传递。它不是 JWT,也不是 Bearer 令牌——而是您整合包专用的独立密钥。
X-Pack-Token: mpk_pack_XXXXXXXXXXXXXXXX
Content-Type: application/json
令牌存放在您的服务器上——请保存在环境变量中,不要写进前端代码。
签发激活码
POST /v2/hosting/packs/{key}/keys
| 字段 | 类型 | 默认值 | 作用 |
|---|---|---|---|
count | 数字 1–200 | 1 | 每次调用生成多少个激活码 |
note | 字符串,最长 120 | — | 您的备注:订单号、买家昵称 |
maxServers | 数字 1–20 | 1 | 一个激活码可在多少台服务器上激活 |
expiresAt | ISO 日期 | — | 激活码到期日期 |
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"]
}
code 字段是批次中的第一个激活码,为兼容性保留;当 count > 1 时,请使用 codes。
激活码只在此处返回,其他任何地方都不会返回。 我们存储其哈希值——就像密码一样。如果丢失激活码,我们无法找回:请签发新的并吊销旧的。
限制为每个整合包每分钟 30 次请求。每次调用最多 200 个激活码的批量正是为销售而设:请批量生成,而不是每次请求只生成一个。
激活码的状态
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"
}
]
激活码本身不会出现在响应中,也不可能出现。codeHint 是激活码的开头部分——用它把记录与您的订单对应起来。
状态:free——未使用,spent——已使用,expired——已过期,revoked——已被您吊销。
查询单个激活码
POST /v2/hosting/packs/{key}/keys/status,请求体 {"code": "A7K2-9MHD-4RTP-QW38"}。
响应与列表中的记录相同。激活码要放在请求体中,而不是 URL 中:URL 会进入代理日志和浏览器历史记录,而激活前的激活码就是一把可用的钥匙。
连字符和大小写无关紧要:a7k29mhd4rtpqw38 与 A7K2-9MHD-4RTP-QW38 一样能被找到。
吊销激活码
POST /v2/hosting/packs/{key}/keys/revoke,请求体 {"code": "..."}。
用于退款、误发或纠纷。吊销会阻止后续激活,但不会移除已部署的整合包——已激活的买家仍保留一台可用的服务器。
激活 Webhook
如果您提供 Webhook URL,我们会在激活码被使用的瞬间调用它:
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"
}
该调用没有签名:您可以用同一个令牌通过 keys/status 进行验证——借助 codeHint 找到您的记录并看到 state: "spent"。这样您就不必再保存第二个密钥。
Webhook 发送后不等待响应,也不会重试:即使您的服务器当时宕机,激活依然已完成,您可以在激活码列表中看到。URL 必须是公网地址——我们不会调用内网或本地地址。不会跟随重定向。
整合包卡片
GET /v2/hosting/packs/{key} 是公开的,无需令牌。它返回买家看到的内容:名称、核心、版本、最低内存、方案列表和保护标志。响应中没有归档链接。
这对您网站上的“购买”页面很方便:方案要求来自单一数据源,不会与我们的向导产生分歧。
卡片的展示字段由您自行编辑:带令牌的 PATCH /v2/hosting/packs/{key} 接受 name、authorName、authorUrl、iconUrl、webhookUrl。销售条款(paidOnly、requireKey、lockFiles、planCodes)、在商店中启用整合包以及 JVM 启动参数无法通过令牌修改——这些是我们与您的约定以及我们的节点配置,请就这些内容联系我们。
整合包更新
以前更新意味着给我们发邮件然后等待。现在您自行发布版本,服务器所有者在其控制面板中自行选择。
关键点:我们绝不会静默更新任何人的服务器。在整合包版本之间切换可能与世界存档不兼容,决定权在服务器所有者手中。已发布的版本是新服务器获得的版本,也是我们向已部署服务器推荐的版本;之前的版本仍保留在列表中,您可以继续使用或回滚。
流程是什么样的
# 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"
版本
| 字段 | 类型 | 作用 |
|---|---|---|
label | 最长 40 的字符串 | 版本号:拉丁字母、数字、点、连字符、下划线。不可更改:同一个标签对应不同文件会让问题排查变成猜测 |
changelog | 最长 4000 的字符串 | 变更内容——服务器所有者会在更新前阅读 |
core、gameVersion | 字符串 | 如果服务器配置迁移到了其他核心或游戏版本 |
loaderBuild、javaVersion | 字符串 | 固定加载器构建和 Java 版本,如果该版本需要的话 |
minRamMb | 数字 | 该版本的内存下限。内存不足的人会看到原因,而不会丢失世界 |
archiveSha256 | 64 位十六进制 | 我们在解析前校验:与其解压到一半,不如拒绝一个没有完整到达的压缩包 |
上传
POST /v2/hosting/packs/{key}/versions/{label}/archive?offset=N,请求体——.zip 的一个分块,Content-Type: application/octet-stream。分块最大 32 MB,整个压缩包最大 4 GB。
分块通过偏移量寻址,而不是“追加到末尾”:中途中断的分块已经部分写入文件,重试会把同样的字节再追加一次——压缩包会在无声无息中损坏。响应返回 uploadedBytes,用于在中断后继续上传。
解析
POST .../finish 立即响应(status: "processing"),而解析在后台进行:解压一个 GB 级别的服务器配置需要几分钟。通过 GET .../versions/{label} 读取状态:processing → ready 或 failed,失败原因文本在 error 中。
压缩包必须通过以下检查:
- 它是服务端整合包:去掉唯一一层包装目录(
Server Files/之类)后,mods/或plugins/位于根目录。把客户端整合包放在服务端会生成一个空世界,所以我们拒绝安装它; - 压缩包内的名称中不能有
..、绝对路径或 Windows 分隔符; - 不能有密码,不能有特殊压缩方式(只允许 store 和 deflate);
- 限制:60,000 个文件,解压后 12 GB,压缩比最高 200 倍。
失败不影响已发布的版本:您的客户端继续运行上一个版本,您重新上传即可。未完成的草稿:每个服务器配置最多三个,被放弃的会在一天后自动清理。
发布、回滚和删除
| 请求 | 作用 |
|---|---|
POST .../versions/{label}/publish | 将版本设为已发布。回滚也是这样做:发布上一个版本——新服务器会重新使用它 |
POST .../versions/{label}/archive-version | 将版本从可选列表中移除。已经拥有它的服务器继续保留 |
PATCH .../versions/{label} | 编辑已创建版本的描述:changelog 和 minRamMb。版本文件不可更改,因此核心、加载器和 Java 不会变 |
DELETE .../versions/{label} | 删除版本及其文件。已发布的版本或至少在一台服务器上使用的版本无法删除 |
GET .../versions | 可供选择的版本(公开,无需令牌) |
GET .../versions/all | 您的全部版本,包括草稿和失败项 |
GET .../versions/rollout | 有多少服务器使用哪个版本——可以看到更新如何逐步铺开 |
发布会把核心、游戏版本、加载器固定项、Java 以及该版本的内存下限写入服务器配置卡片:新服务器无需您做任何额外操作即可获得。
服务器所有者看到的内容
在控制面板的高级服务器配置区块中:已安装哪个版本、已发布哪个版本、您的 changelog,以及带“切换”按钮的版本列表。更新不影响世界——只替换服务器配置文件,替换前我们会先做一份副本。自定义模组(如果您允许的话)在切换后需要重新添加:服务器配置作为一个整体迁移,mods/ 里残留一半旧版本会导致启动时崩溃。
如果所有者的套餐无法承载某个版本,我们会连同原因一起显示,而不是隐藏它:用户应该看到自己需要什么,而不是猜测服务器配置为什么不更新。
您自己的服务器配置页面
您在账户中自行搭建服务器配置的落地页(个人资料 → “我的服务器配置” → “服务器配置页面”):首屏、功能、截图、问答、您的配色。套餐和版本列表由我们的数据填充,因此不会过时。
完成的页面位于 millida.net/sborka/<您的地址>——一个普通网站页面,会被搜索引擎收录并包含在我们的站点地图中。草稿除您之外任何人都看不到。
图片也在同一个地方上传,在您的账户中:页面由我们的域名提供,其文件存储在我们这里——即使您的托管宕机,页面也完好无损。
页面无法通过 API 编辑:它是一个展示页面,不是发布流程。
响应代码
| 代码 | 何时出现 | 如何处理 |
|---|---|---|
403 | 发放令牌无效 | 检查 X-Pack-Token。令牌绑定到一个服务器配置:它无法用于别人的 key |
404 | 服务器配置已禁用、未连接发放,或不存在该版本 | 联系我们 |
400 | expiresAt 日期无法解析、版本标签错误、分块为空或过大 | 查看错误文本 |
409 | 版本已创建、已解析、已发布,或已安装在服务器上 | 标签不可更改:发布下一个版本 |
429 | 每分钟超过 30 个请求(上传为 600) | 分批发送,并发送更大的分块 |
如何在开卖前测试整个流程
向我们索取几个测试码:通过 API 发放一个码,在我们的托管上于您的服务器激活它,看看 webhook 收到了什么以及 keys/status 显示了什么。这样您就能在第一位付费客户走完流程之前,看到买家的完整路径。
