---
title: "Publish a new mablnet worker release (operator / release CI)"
method: POST
path: "/link/mablnet/releases"
tags: ["LinkMablnet"]
---

# Publish a new mablnet worker release (operator / release CI)

`POST /link/mablnet/releases`

Stores a signed release manifest and initialises the channel's rollout. The request body is the signed manifest produced by the release pipeline (see `link/mablnet/docs/deployment/release-pipeline.md` § Aggregate job). The api derives `channel` and `version` from the manifest, stores the manifest verbatim, sets the channel's `current_version` to the new version and `fallback_version` to the prior current, and applies the default staged rollout schedule (1% → 10% → 50% → 100% over 24h).
Auth: a release-engineering identity, not an interactive customer. The publishing principal is CI rather than a user-OAuth admin, so the exact machine-auth shape is an open api-team decision — see design doc § Release-publisher auth.

## Request body

- MablnetManifestEnvelope — Transport envelope carrying a signed mablnet worker release manifest as opaque bytes. The `manifest` field is the **exact** signed manifest document (structure: `manifest-format.md in link/mablnet/docs` § Schema), base64-encoded so it survives the api's JSON layer byte-for-byte — the api never deserialises or reformats the manifest, which is what keeps its Ed25519/JCS signature verifiable on the consumer. The mabl-API transport wraps the manifest this way; the GCS and update-service transports return the same bytes unwrapped, so an API-channel consumer decodes this field before verifying.
  - `manifest` string, required — Base64 of the exact signed manifest bytes. Decode, then verify + parse per manifest-format.md.
  - `rollout_schedule` MablnetRolloutStage[] — Optional rollout schedule for this publish. Omit for the default gradual staged schedule (prod / `stable`). Pass a single `[{percent: 100, since_ms: 0}]` stage to make the version current fleet-wide immediately — used for the `dev`/latest and per-branch channels, where the (typically single) tracking Host must resolve to the new build at once rather than wait out the gradual ramp. api-only orchestration metadata; rides outside the signed manifest bytes, so it does not affect the manifest's signature.
    - `percent` integer, required — Target rolled-out percentage at this stage (0–100).
    - `since_ms` integer, required — Milliseconds after `published_at` at which this stage becomes active.

## Response `200`

Release stored; the resulting channel rollout state is returned.

- MablnetRolloutState — Per-channel staged-rollout state owned by the api (one entity per channel). Unlike the manifest/keystore this is api-owned data, not a signed document, so normal date-time handling applies. The manifest endpoint reads this to decide which version a given Host receives — see design doc § Manifest resolution.
  - `id` string — Datastore key for this entity — equals `channel` (one entity per channel). Server-set.
  - `channel` string, required — Release channel this state governs.
  - `current_version` string, required — The version being rolled out to (Hosts inside the rolled-out percentage receive this).
  - `fallback_version` string — What Hosts not yet inside the rollout receive. Unset once a rollout reaches 100% and the current version is fully rolled out.
  - `rollout_schedule` MablnetRolloutStage[], required — Time-based stages; the rolled-out percentage is the max stage whose `since_ms` has elapsed since `published_at`.
    - `percent` integer, required — Target rolled-out percentage at this stage (0–100).
    - `since_ms` integer, required — Milliseconds after `published_at` at which this stage becomes active.
  - `force_percent` integer — When set, overrides the time-based schedule with an explicit rolled-out percentage (operator force-advance). Cleared by resuming the schedule.
  - `published_at` string, date-time — When the current rollout started; the schedule's `since_ms` offsets are relative to this.
  - `paused` boolean, required — When true, the manifest endpoint stops advancing the rollout — Hosts stay on whichever version they have.

## Other responses

- `400` — Invalid or missing parameter
- `401` — User not authenticated
- `403` — User not authorized
- `409` — A release with this channel + version already exists (republish goes through PUT channels/{channel}/current).
- `default` — Unknown error

---

[API](https://skmtc.net/mabl/apis/mabl-api.md) · [All operations](https://skmtc.net/mabl/apis/mabl-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/mabl/mabl-api/revisions/d0fc0114da66/schema)
