Manage serving (rollout, status, targeting)
Ramp, pause, resume, roll back or target a release from CI - no dashboard needed. Identified by app + channel + version. The same invariants as the dashboard apply (shared code): the rollout percentage only increases once the release has been offered (422), label targeting only broadens once offered (422), match expressions are frozen once offered (422), and a rolled-back release can never be re-served (409). Applied in order: targets, rollout, status.
Ramp, pause, resume, roll back or target a release from CI - no dashboard needed. Identified by app + channel + version. The same invariants as the dashboard apply (shared code): the rollout percentage only increases once the release has been offered (422), label targeting only broadens once offered (422), match expressions are frozen once offered (422), and a rolled-back release can never be re-served (409). Applied in order: targets, rollout, status.
Authorization
bearerAuth Mint keys from the dashboard (API keys). Shown once, stored hashed.
In: header
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
0 <= value <= 100paused halts (temporary), published resumes, rolled_back is permanent (serves the fallback below as a downgrade), deprecated marks end of life (not served, reversible; devices still on it receive their next update as required)
Value in
- "published"
- "paused"
- "rolled_back"
- "deprecated"
{ matchLabels: { key: [values] }, matchExpressions: [{ key, operator, values }] }; null clears targeting. Expression keys are label keys or the reserved $version / $platform / $arch fields (resolved from the request itself). Operators: In, NotIn, Exists, DoesNotExist, and VersionGte / VersionLt ($version only, semver-aware). All operators except DoesNotExist fail closed when the key cannot be resolved. Labels may only broaden once the release has been offered; expressions are FROZEN then (422) - cut a new release to change them.
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X PATCH "https://example.com/api/v1/releases" \ -H "Content-Type: application/json" \ -d '{ "app": "qsxsicotpbmtf8ag", "channel": "stable", "version": "2.1.0", "rollout": 50 }'{ "release": { "app": "qsxsicotpbmtf8ag", "channel": "stable", "version": "2.1.0", "rolloutPct": 50, "status": "published", "targets": null }}{ "error": "devices.0.version: Invalid version"}{ "error": "Invalid or revoked API key"}{ "error": "Unknown app"}{ "error": "A rolled-back release cannot be re-served"}{ "error": "2.1.0 has already been offered at 25% - the rollout can only increase now. Pause to stop offering, roll back to pull the release."}{ "error": "Rate limit exceeded"}Publish a release POST
Creates an immutable release on a channel. Artifacts point at your existing storage. Duplicate app+channel+version returns `409`.
GitHub release webhook (inbound) Webhook
Relayer receives GitHub `release` events at `/wh/github/{appId}` (URL + secret shown when you enable the integration in app settings). Payloads are HMAC-SHA-256 verified. Published releases land on `stable`, pre-releases on `beta`, drafts are ignored, assets are classified per platform/arch by filename, and checksum/metadata files are filtered out.