API: Releases

Generated from openapi.json 0.12.0-draft (draft)

The release pointer every scale-out and healing action boots from.

Create a release and move the group's current pointer to it

post/groups/{groupId}/releasesstable

With a token that has the releases:write ability, of a member who may change the group. Records a release and makes it the group's current release. Every scale-out and every healing action boots or deploys from current; :latest is never used. The group's generation is incremented, which discards scaling decisions made against the previous release, and group.release_changed goes on the group's timeline; servers already running keep the release they booted from. For a snapshot group, ref is the numeric id of a snapshot in the group's Hetzner project, and Hetscale reads it back before it takes it: a snapshot, available, of the group's CPU architecture and no larger than the disk of the group's server type. For a webhook group, ref names the build its pipeline deploys — an image digest, a tag or a commit, 1 to 200 visible characters — never a mutable :latest; the group's endpoint receives group.release_changed, and every later node.created names the new release. The group must be Live or paused, have release v1 and no snapshot of its seed in progress. Naming the current ref and build again changes nothing and answers 200 with the current release; naming an earlier ref again is a new release.

Parameters

ParameterTypeDescription
groupId (path)*stringGroup identifier: the group's ULID in lower case, prefixed with grp_. Read in either case. Example: grp_01j8x4v9k2n7q3r5s6t7v8w9xb.
Idempotency-Key (header)stringOptional on every state-changing request: 1 to 255 visible ASCII characters, kept for 24 hours per organisation and bound to the token that first sent it. A retry by the same token with the same key and the same request (method, path, query string and exact body) gets the first answer again, marked Idempotent-Replayed: true, instead of a second effect. The same key with a different request, or from another token of the organisation, is answered 422 idempotency_key_reused; while the first request still runs, its own token gets 409 idempotency_key_in_flight. A request that failed validation or on the server leaves no answer behind, so its retry runs again. Example: deploy-4711-node-01j8x4v9k2n7q3r5s6t7v8w9xc.

* required

Request body

FieldTypeDescription
ref*stringThe artefact to boot or deploy from: for a snapshot group the numeric id of a snapshot in the group's Hetzner project, for a webhook group the build its pipeline deploys, such as an image digest.
build_idstring | nullThe customer's own build identifier for this release; nodes report it so stale nodes can be found.

* required

{
  "ref": "231456789",
  "build_id": "4712"
}

Responses

200
The group already points at this image and build; nothing changed.
FieldTypeDescription
release*Release
group*Group

* required

201
The release was recorded and is now the group's current release; the group with its new generation.
FieldTypeDescription
release*Release
group*Group

* required

{
  "release": {
    "id": "rel_01j8x4v9k2n7q3r5s6t7v8w9xe",
    "version": 4,
    "ref": "231456789",
    "build_id": "4712",
    "source": "api",
    "created_at": "2026-09-15T12:40:00Z"
  },
  "group": {
    "id": "grp_01j8x4v9k2n7q3r5s6t7v8w9xb",
    "name": "api-prod",
    "generation": 43
  }
}
400
The Idempotency-Key header is not 1 to 255 visible ASCII characters (`idempotency_key_invalid`).

Body: Error

401
The API token is missing, unknown, expired or revoked, or the member it acts for left the organisation (`unauthenticated`).

Body: Error

403
The token lacks the ability the operation needs (`forbidden`).

Body: Error

404
The group or node does not exist or belongs to another organisation (`not_found`).

Body: Error

409
The group's state stands in the way: not Live or paused (`not_live`), releases from Coolify deployments (`not_snapshot_group`), no release v1 (`release_missing`) or a snapshot of the seed in progress (`snapshot_in_progress`). Also `idempotency_key_in_flight`.

Body: Error

422
The ref cannot become the release: `ref_invalid`, `ref_mutable` (a `:latest` tag), `image_not_found`, `image_not_snapshot`, `image_not_available`, `architecture_mismatch` or `image_too_large`. Also `validation_failed` and `idempotency_key_reused`.

Body: Error

429
The organisation's API rate limit, 60 requests a minute by default, is exhausted (`rate_limited`); retry after the seconds in `Retry-After`.

Body: Error

502
Hetzner refused to describe the image with the project's token (`provider_error`); a retry will not help until the connection is fixed.

Body: Error

503
Hetzner could not be asked just now (`provider_unavailable`), or Hetscale could not open the stored secrets: its key service did not answer (`key_service_unavailable`) or its master key is unavailable (`secrets_unavailable`); retry, after the seconds in `Retry-After` when it is sent.

Body: Error

Example

curl -X POST https://api.hetscale.com/v1/groups/grp_01j8x4v9k2n7q3r5s6t7v8w9xb/releases \
  -H "Authorization: Bearer $HETSCALE_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "ref": "231456789", "build_id": "4712" }'

See what Hetscale would have done with your real data — connect read-only, get your report in minutes.

Connect read-only