List offered Kubernetes versions
const url = 'https://api.aetherplatform.cloud/api/v1/k8s-versions';const options = {method: 'GET'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request GET \ --url https://api.aetherplatform.cloud/api/v1/k8s-versionsThe Kubernetes versions a cluster can currently be created on or upgraded to. Public — no authentication required, so the pre-login portal wizard can populate its picker. Subject to the global rate limit.
This endpoint is the authoritative source for that picker: a version
absent from this list is rejected by cluster creation and by upgrade
with 422.
Each version is a minor ("1.37"), not a full patch version.
Create and upgrade accept either form — a bare minor resolves to the
latest patch Aether has verified for it, and a full
MAJOR.MINOR.PATCH is accepted when its minor is offered and the patch
is one this platform has resolved (at or below the minor’s current
patch); otherwise 422.
Every entry also carries patch: the full version that minor currently
resolves to ("1.37.0"), so a picker can show the concrete version
alongside the label without a second call.
The list is every Kubernetes minor upstream still supports that the deployed Talos worker image can run, ordered newest-first. Two bounds, not three:
- Upstream’s support window — the minors whose
endOfLifeDatein the Kubernetes release schedule has not passed. Normally three; four during the ~2-month overlap after a new minor ships. Do not assume a maximum of three entries. - The deployed Talos worker image (
AETHER_TALOS_VERSION) caps the top. A minor the worker OS cannot run is never offered: the tenant control plane would roll to a version no kubelet can match. Every patch of an offered minor is runnable by that image, so the cap never refuses a patch of a minor this endpoint lists.
aether-operator accepts the uncapped upstream window, so everything
offered here is provisionable by construction — both components read
the same resolver (github.com/plane-shift/k8s-versions-go) rather
than each deriving a window of its own.
A minor upstream supports but for which no patch release has been published yet is not offered (there is nothing to deploy), though the operator would accept it.
When the list is non-empty, exactly one entry is labelled Latest —
the topmost minor that survives the Talos cap, which is not
necessarily upstream’s latest. Every other entry is labelled Stable.
A Talos update never changes a tenant’s Kubernetes version (owner ruling 2026-09-15); it only changes which versions this endpoint can offer. The list can therefore shrink underneath a running cluster, and that cluster keeps the version it is on.
Responses
Section titled “Responses”The offered versions, newest first.
An empty items array is a valid 200, not an error condition, and
this endpoint has no failure response of its own. It means the
version service has resolved nothing yet (cold start, or upstream
unreachable) or every candidate was excluded by the bounds above.
While that lasts, cluster creation fails 422 on k8s_version and
upgrades fail 503 versions_unavailable — so a client should read
an empty list as “the picker is unavailable”, never as “no
Kubernetes versions exist”.
object
The offered versions, newest first. Never null; an unwarmed or fully-excluded version service yields an empty array. This endpoint is not paginated and emits no next_cursor.
object
The Kubernetes MINOR version — 1.37, not 1.37.4. Pass it back as k8s_version on cluster creation or target_version on upgrade, where it resolves to the latest patch Aether has verified for that minor.
Latest marks the newest offered minor and appears on exactly one entry. It is the topmost minor that survives the Talos cap, which is not necessarily upstream’s latest release. Every other entry is Stable.
The full version this minor currently resolves to — 1.37.0 for version 1.37 — with no leading v. Always present on an offered entry: a minor whose patch cannot be resolved is dropped from the list rather than advertised. Display-oriented (Latest — 1.37.0); it is not a stable identifier, since the same minor resolves to a newer patch as upstream publishes one. Send version back on create/upgrade, or send an explicit published patch of an offered minor.
Example
{ "items": [ { "version": "1.37", "label": "Latest", "patch": "1.37.0" } ]}