HTTP API
All bodies are JSON. Admin routes require Authorization: Bearer <ADMIN_TOKEN or API token>.
Device routes (public)
Section titled “Device routes (public)”POST /v1/check
Section titled “POST /v1/check”{ "appId": "uuid", "platform": "ios", "runtimeVersion": "1.0.0", "channel": "production", "deviceId": "random-per-install", "currentUpdateId": "uuid|null", "sdkVersion": "0.1.0" }Responses: { "status": "noUpdate" }, { "status": "rollbackToEmbedded" } or
{ "status": "update", "update": { "id": "uuid", "createdAt": "...", "channel": "production", "platform": "ios", "runtimeVersion": "1.0.0", "message": "Fix checkout", "mandatory": false, "launchAsset": { "path": "main.jsbundle", "hash": "<sha256>", "size": 123, "url": "https://.../v1/assets/<app>/<sha256>" }, "assets": [ { "path": "assets/src/img/logo.png", "hash": "...", "size": 1, "url": "..." } ], "signature": "base64 DER ECDSA-P256-SHA256 | null" } }GET /v1/assets/:appId/:sha256
Section titled “GET /v1/assets/:appId/:sha256”Immutable, Content-Encoding: gzip, cached at the edge for a year.
POST /v1/events
Section titled “POST /v1/events”{ "appId": "uuid", "deviceId": "...", "events": [ { "type": "install|rollback|download|error", "updateId": "uuid" } ] }Admin routes
Section titled “Admin routes”| method & path | body | |
|---|---|---|
GET /v1/apps |
||
POST /v1/apps |
{ name, signingPublicKey? } |
|
GET/PATCH/DELETE /v1/apps/:appId |
{ name?, signingPublicKey? } |
delete also removes R2 files |
POST /v1/apps/:appId/assets/missing |
{ hashes: [] } |
→ { missing: [] } |
PUT /v1/apps/:appId/assets/:sha256 |
gzip bytes | server verifies the hash after decompression |
POST /v1/apps/:appId/updates |
PublishUpdateRequest |
all files must be uploaded first |
GET /v1/apps/:appId/updates?channel&platform&runtimeVersion&limit |
includes stats |
|
GET /v1/apps/:appId/updates/:id |
||
PATCH /v1/apps/:appId/updates/:id |
{ enabled?, rolloutPercentage?, mandatory? } |
|
POST /v1/apps/:appId/updates/:id/promote |
{ channel, rolloutPercentage?, mandatory?, message? } |
|
GET/POST /v1/tokens, DELETE /v1/tokens/:id |
{ name } |
token shown once; stored as SHA-256 |
Signing message
Section titled “Signing message”airdrop-v1<runtimeVersion><platform><launchAsset.path>:<launchAsset.hash><asset.path>:<asset.hash> (one line per asset, sorted by path)joined with \n, signed with ECDSA P-256 / SHA-256, DER-encoded, base64.
The public key is the base64 of the 65-byte uncompressed point (04 || X || Y).