Zum Inhalt springen

Die API nutzen

Diese API gehört zur Konsole für die Cluster, die ich für dich betreibe. Deine eigene Landschaft hat kein Portal; dort sprichst du mit kubectl oder dem CLI mit dem Garden. Alles, was die Konsole tut, tut sie über dieselbe REST-API: Cluster erstellen, Node-Pools verwalten, kubeconfigs ausstellen, die Abrechnung lesen. Diese Seite ist die Orientierung: die Form der API und die Konventionen, die über alle Endpunkte hinweg gelten. Die API-Referenz (derzeit auf Englisch) dokumentiert dann jeden Endpunkt vollständig, generiert aus dem Live-Schema.

Die API liegt unter dem Konsolen-Host, und die stabile Oberfläche ist mit dem Präfix /v1/ versioniert:

https://console.paasbox.com/api/v1/

Anfragen und Antworten sind JSON über HTTPS. Eine neue Hauptversion würde zu /v2/ wechseln, statt zu verändern, was /v1/ tut.

Zwei Wege hinein, je nachdem, wer aufruft:

  • Sitzung: Die Konsole authentifiziert dich über eine Browser-Sitzung. Das ist der interaktive Weg; du tust nichts Besonderes.
  • API-Key: für Skripte, CI und alles Nicht-Interaktive. Erstelle in der Konsole einen Key (siehe Teams & API-Keys) und sende ihn im Authorization-Header.

Keys sehen aus wie pbx_live_…, werden bei der Erstellung einmalig angezeigt, gehören einem Team-Mitglied und lassen sich jederzeit widerrufen. Sende ihn bei jeder Anfrage mit:

Terminal-Fenster
curl -s -H "Authorization: Token $PAASBOX_API_KEY" \
https://console.paasbox.com/api/v1/teams/<team>/clusters/

Behalte den Key als das dauerhafte Geheimnis und nutze ihn, um pro Lauf eine frische kubeconfig zu holen, statt langlebige Cluster-Zugangsdaten zu speichern.

Ressourcen gehören einem Team, nicht einer Person, deshalb tragen die Pfade, die Ressourcen besitzen, den Team-Slug:

/api/v1/teams/{team_slug}/clusters/
/api/v1/teams/{team_slug}/clusters/{cluster}/node-pools/

Dein Key handelt in den Teams, in denen sein Besitzer Mitglied ist. Die Seite Teams & API-Keys behandelt Rollen und was ein Key darf; das Aktivitätsprotokoll führt jede per Key ausgelöste Änderung auf eine Person zurück.

Listen-Endpunkte sind zu je 100 Einträgen paginiert. Fordere eine Seite mit ?page= an:

Terminal-Fenster
curl -s -H "Authorization: Token $PAASBOX_API_KEY" \
"https://console.paasbox.com/api/v1/teams/<team>/clusters/?page=2"

Die Antwort verpackt die Einträge in eine kleine Hülle: count ist die Gesamtzahl, next und previous sind Seiten-URLs (oder null an den Enden), und results enthält die Einträge:

{
"count": 137,
"next": "https://console.paasbox.com/api/v1/teams/acme/clusters/?page=3",
"previous": "https://console.paasbox.com/api/v1/teams/acme/clusters/?page=1",
"results": [ /* … */ ]
}

Es gelten die üblichen HTTP-Semantiken. Die, denen du begegnen wirst:

CodeBedeutung
200 / 201 / 204Erfolg: gelesen, erstellt oder gelöscht (ohne Body).
202Angenommen: Die Arbeit läuft asynchron (z. B. ein startender Cluster); frag die Ressource für den Status ab.
401 / 403Nicht authentifiziert / nicht erlaubt. Prüfe den Key und die Rolle des Aufrufers im Team.
402Ein Abrechnungs- oder Ausgabenlimit blockiert die Aktion. Kläre es in der Konsole und versuche es erneut.
404Keine solche Ressource, oder sie liegt außerhalb der Teams, die dein Key erreicht.
409Konflikt mit dem aktuellen Zustand (z. B. ein Name ist bereits vergeben).
412 / 422Die Anfrage wurde verstanden, aber abgelehnt: Eine Vorbedingung schlug fehl, oder ein Feld war ungültig.

Fehlerantworten tragen einen JSON-Body, der beschreibt, was schiefging; der Statuscode entscheidet, wie zu reagieren ist.

Die paasbox-CLI, der kostenlose Weg, auf dem du die Landschaft selbst betreibst, spricht mit zwei kleineren Flächen, die den Konventionen oben nicht folgen. Beide sind hier von Hand dokumentiert: es sind einfache Endpunkte außerhalb des Frameworks, aus dem das Schema generiert wird, sie tauchen also nicht in der API-Referenz auf.

Drei Endpunkte unter /api/cli/ auf dem Konsolen-Host implementieren den OAuth-2.0-Device-Authorization-Grant (RFC 8628) – denselben Ablauf, den gh auth login und docker login nutzen. Ein API-Key kommt hier nicht vor, denn der Sinn der Sache ist, dass der Aufrufer noch keinen hat; die Bremsen sind der Ablauf nach zehn Minuten, ein Ratenlimit pro Adresse und die Tatsache, dass nichts passiert, bis ein angemeldeter Mensch den Code bestätigt. Die Fehler-Bodies sind die von RFC 8628, nicht die Formen oben, und jeder darf ein error_description mitführen, das ein Client ignorieren kann.

POST /api/cli/device/start – eine Anmeldung eröffnen. Ohne Authentifizierung.

{ "scope": "dns", "client": "paasbox-cli/0.1.0" }
{
"device_code": "…43 URL-sichere Zeichen…",
"user_code": "FTQK-2X7M",
"verification_uri": "https://console.paasbox.com/device",
"verification_uri_complete": "https://console.paasbox.com/device?code=FTQK-2X7M",
"expires_in": 600,
"interval": 5
}

400 trägt invalid_scope oder invalid_request; 429 trägt slow_down, wenn von einer Adresse zu viele Anmeldungen starten.

POST /api/cli/device/token – im Takt von interval abgefragt, bis der Mensch entschieden hat. Ohne Authentifizierung; der Device-Code ist das Zugangsdatum.

{ "device_code": "" }

Solange es wartet, 400 mit einem von authorization_pending, slow_down, expired_token, access_denied oder invalid_grant (ein unbekannter oder bereits verbrauchter Device-Code); 429 mit slow_down bei zu vielen Abfragen von einer Adresse. Wer schneller als interval abfragt, bekommt slow_down und schiebt die Sperre um ein weiteres Intervall nach hinten – ein Client, der das ignoriert, bekommt es also weiterhin.

Einmal, und nur einmal, antwortet die Abfrage mit 200 und der Bewilligung:

{
"token": "",
"team": "Acme GmbH",
"label": "acme",
"endpoint": "https://dns.paasbox.com/v1",
"zone": "paasbox.app",
"base": "paasbox.app",
"scopes": ["dns"]
}

Jede spätere Abfrage mit demselben Device-Code bekommt invalid_grant. Der Token entsteht beim Abholen, nicht beim Bestätigen, liegt dazwischen also nirgends. endpoint, zone und base kommen aus der Konfiguration des antwortenden Portals statt aus einer festen Zeichenkette – lies sie aus der Antwort, statt sie fest zu verdrahten.

GET /api/cli/whoami – was ein gespeicherter Token ist, für paasbox auth status. Schick den Token als Bearer-Zugangsdatum:

Terminal-Fenster
curl -s -H "Authorization: Bearer $DNS_TOKEN" \
https://console.paasbox.com/api/cli/whoami
{
"team": "Acme GmbH",
"label": "acme",
"scopes": ["dns"],
"created": "2026-09-07T10:12:31+00:00",
"endpoint": "https://dns.paasbox.com/v1",
"zone": "paasbox.app",
"base": "paasbox.app"
}

401 mit invalid_token heißt, der Token ist unbekannt oder wurde widerrufen – die CLI liest das als „abgemeldet“, nicht als vorübergehende Störung.

Die kostenlosen gehosteten Namen unter <team>.paasbox.app werden über eine Hetzner-Cloud-kompatible Zone- und rrset-API auf einem eigenen Host geschrieben:

https://dns.paasbox.com/v1

Sie bildet den Ausschnitt der Hetzner-Cloud-API nach, den Gardeners DNS-Extension, der Aufbau und die hcloud-CLI tatsächlich aufrufen, Anfrage für Anfrage, und ergänzt das eine, was Hetzner nicht kann: einen Bearer-Token mit Team-Scope. Ein unveränderter Client funktioniert also dagegen – richte ihn auf den Endpunkt und gib ihm den Team-Token statt eines Hetzner-Tokens:

Terminal-Fenster
export HCLOUD_ENDPOINT=https://dns.paasbox.com/v1
export HCLOUD_TOKEN=$DNS_TOKEN
hcloud zone rrset set-records --record 203.0.113.7 paasbox.app api.garden.acme A
EndpunktWas er tut
GET /v1/zonesListe, gefiltert per ?name=; liefert die eine Zone, die dein Token sieht
GET /v1/zones/{zone}per Id oder per Name
GET /v1/zones/{zone}/rrsetsnur die Record-Sets deines Teams
POST /v1/zones/{zone}/rrsetsanlegen
GET / DELETE /v1/zones/{zone}/rrsets/{name}/{type}eines lesen oder entfernen
POST …/rrsets/{name}/{type}/actions/{action}set_records, add_records, remove_records, change_ttl
GET /v1/actions?id= und GET /v1/actions/{id}Actions abfragen, so wie Hetzners Go-Client es tut

Request- und Response-Bodies sind unverändert die von Hetzner, bis hin zur meta.pagination-Hülle und der Form {"error": {"code": …, "message": …}}. Verweigert die Gegenstelle etwas, werden ihre Antwort und ihr Statuscode wörtlich durchgereicht.

Anders ist, was der Token darf:

  • Schreiben ist auf den eigenen Namen deines Teams und alles darunter erlaubt. Der Zonen-Apex, die Namen jedes anderen Teams und alle unsere werden mit 403 forbidden abgelehnt.
  • Lesen ist gefiltert. Eine Liste zeigt nur die Record-Sets deines Teams; jeder andere Name antwortet 404 not_found statt 403, damit sich die Zone durch diese Tür nicht aufzählen lässt.
  • Typen sind auf A, AAAA, CNAME und TXT begrenzt. NS wird überall verweigert.
  • Actions sind auf Zonen-Actions gefiltert, die fortlaufenden Action-Ids eines Hetzner-Projekts verraten also nichts anderes.
  • Kontingente (Stand: 2026-09-07): 200 Records und fünf aktive Tokens pro Team.
  • 401 unauthorized ohne Bearer-Token, 502 upstream_unavailable, wenn Hetzner nicht erreichbar ist.

Jeder Schreibvorgang wird festgehalten – Team, Token, Name, Typ, Aktion, Zeit und der Status, den die Gegenstelle geliefert hat – auch die verweigerten.

Die API-Referenz listet jeden Endpunkt, Parameter, Request-Body und jede Antwortform auf. Sie wird aus dem Schema des laufenden Dienstes generiert und folgt so der API, wie sie ausgeliefert wird. Die beiden CLI-Flächen oben liegen außerhalb dieses Schemas und sind deshalb auf dieser Seite dokumentiert.