从一份清晰的协议开始。
萤火翻译 API 提供受授权的模型目录、完整性校验与 Android 版本分发。模型查询、配置查询和模型文件下载均需要授权;官网、文档、健康检查与安装包版本查询公开。
服务地址
https://lumitranslate.cocbc.com/api/v1两种授权方式
官方 App:首次使用时在 Android Keystore 中创建独立 P-256 签名密钥,通过硬件证明校验官方签名、锁定启动与设备持钥证明。通过后自动获得一小时访问凭证;用户无需填写 API Key。无法通过证明的设备显示配对码,由管理员人工审核,审核前不能下载。
你的其他客户端:在 管理后台 创建独立 API Key,指定有效期及权限。完整密钥只展示一次。请求通过 Authorization: Bearer <API_KEY> 发送,不放入 URL、不嵌入公开 APK。
curl -fsS \
-H "Authorization: Bearer $LUMI_API_KEY" https://lumitranslate.cocbc.com/api/v1/models权限:config:read 查询配置、models:read 查询模型、models:download 获取下载链接。只授予查询权限时,downloadUrl 返回 null。撤销 API Key 或停用设备,会使已有凭证及下载链接失效;正在传输的 HTTP 响应会继续到连接结束。
接口目录
| 方法与路径 | 用途 | 参数 |
|---|---|---|
GET /health | 服务存活状态 | 无 |
GET /config | 客户端配置 · config:read | 无 |
GET /models | 分页模型目录 · models:read | page:默认 1;pageSize:默认 20,最大 100 |
GET /models/{model_id} | 模型元数据 · models:read | q4_k_m / q6_k / q8_0 |
GET /releases/latest | 最新应用版本 | platform=android;channel=stable 或 preview,默认 stable |
App 设备协议
所有路径均相对于 /api/v1。JSON 请求与响应;签名为 SHA256withECDSA 的 DER 编码后标准 Base64;nonce 为 32 字节随机数的标准 Base64。证书列表按叶证书到根证书顺序,每项为 DER 的标准 Base64。
POST /device/challenges,新设备发送{},返回 data.id、nonce、expiresAt。挑战有效期 180 秒、仅能消费一次。- 用 nonce 解码后的字节作为 Android Keystore 的 attestationChallenge 创建 P-256 密钥;对 UTF-8 文本
LumiTranslate enroll id nonce签名(其中 id/nonce 替换为响应原值,换行为 LF)。 POST /device/enrollments发送 challengeId、name、certificates、signature。ACTIVE 返回 deviceId、accessToken、expiresAt;PENDING 返回 deviceId、pairingCode、message。状态非 ACTIVE 时没有访问凭证。- 刷新令牌时,先以
{"deviceId":"…"}请求新挑战,再签名LumiTranslate token id nonce;向POST /device/tokens提交 deviceId、challengeId、signature。 - accessToken 作为 Bearer 使用。expiresAt 为 UTC Unix 秒;客户端提前 60 秒刷新。不要持久化短期令牌,只保存 deviceId 和 Keystore 密钥。设备删除数据或卸载重装后需重新注册。
此协议不以包名、请求头或 APK 内的固定字符串作为身份凭证。硬件证明信任根与撤销状态按 Android 官方机制验证;不支持的设备进入人工审核。
安全下载与检查更新
- 获取
/models或单个模型详情。仅当available=true且 downloadUrl 非空才开始下载。 - 比较本机记录与服务器返回的
sha256。哈希变化表示模型文件已更新;revision 表示上游仓库版本。 - 从
downloadUrl下载到以哈希区分的临时文件。URL 固定在本站并包含版本及短期 ticket,不指向第三方。API Key 链接最多 2 小时有效;设备链接不会超过访问凭证有效期。不要记录或分享 ticket。过期后重新请求元数据,继续使用原临时文件续传。 - 断点续传使用
Range: bytes=N-。收到 206 时校验 Content-Range 的起点与总长度;收到 200 时从头写入,不能追加。 - 核验
sizeBytes和整个文件的sha256。成功后原子替换本机文件并保存哈希、版本记录;失败时保留旧模型。
# 获取元数据
curl -fsS -H "Authorization: Bearer $LUMI_API_KEY" https://lumitranslate.cocbc.com/api/v1/models/q4_k_m
# 将 downloadUrl 填入 MODEL_URL,断点续传
curl --fail --location --continue-at - "$MODEL_URL" -o model.gguf.part
# 核对输出与 API 的 sha256,再将文件改名为 model.gguf
sha256sum model.gguf.part二进制下载需要有效 ticket,支持 GET、HEAD、200、206、304 和 416。无票据、票据篡改、跨文件使用或撤销后返回 401/403。它们使用标准 HTTP 文件响应,不包装 JSON。文件路径不可变,旧版文件在客户端迁移期间保留。
| 关键字段 | 含义 |
|---|---|
| id | 稳定的量化变体标识,用于查询和选择 |
| revision / sha256 | 上游 commit / 文件 SHA-256 |
| sizeBytes / fileName | 精确字节数 / 建议文件名 |
| available / downloadUrl | 是否可下载;不可用或无下载权限时 URL 为 null |
| minRamMb / architectures | 建议内存与当前客户端支持的架构 |
| license / licenseUrl / sourceUrl | 许可证、完整许可证文本与上游来源 |
应用版本
当前预览渠道使用 /releases/latest?channel=preview。比较 versionCode 判断是否有新版本,安装前检查 APK SHA-256 与 signingCertificateSha256。应用更新是用户发起的操作。
预览版本用于体验与测试;没有正式版本时,stable 渠道返回 404 RELEASE_NOT_FOUND。不会用测试版本冒充正式版。
统一响应、缓存与限流
{
"error": {
"code": "MODEL_NOT_FOUND",
"message": "模型不存在。"
},
"requestId": "用于定位请求的唯一标识"
}成功响应包含 data、requestId;列表额外包含 pagination。所有 JSON API 返回 X-Request-ID。错误码使用稳定的英文常量,message 用于用户提示。
缺少或失效凭证返回 401,权限不足返回 403,参数无效返回 422,资源不存在返回 404,不支持的方法返回 405,限流返回 429,内部错误返回 500。API 每个来源 IP 每分钟最多 120 次请求,429 附带 Retry-After 秒数;后台登录有额外限制。
目录响应提供 ETag。下次请求带上 If-None-Match,内容没有变化时返回 304。必须保存上次完整响应,304 没有正文。requestId 不参与内容版本判断。下载 ticket 定期变化也会改变 ETag;它不是模型更新标识,模型更新应比较 sha256。响应为 private,不能由共享缓存跨用户复用。
在线试用
选择接口并发送请求,这里将显示实时响应。
扩展约定
v1 内以增加可选字段和能力开关扩展功能。客户端应忽略未知字段,不能依赖 JSON 字段顺序。删除字段、改变字段类型或语义需要新主版本,并提前公告弃用期。
账户、在线翻译、任务队列和术语表是后续扩展方向,当前未启用。未来可通过独立受鉴权的资源 /translations、/jobs、/glossaries 扩展;启用前须同时发布对应 OpenAPI、权限作用域和能力开关。
管理接口采用独立的 /api/admin/v1 命名空间,通过后台会话鉴权。管理面板位于 /wzmanaged。