Zum Inhalt springen

Befehle für den Plattformbetrieb

Die Befehle des internen Werkzeugs szenera-ops, die nur mit einem Betreiber-Profil laufen: Geräte-Software, Approvals, Störungen, Warteschlangen, Organisationen, Betreiberkonten.

18 Minuten LesezeitCLIStand: 25.10.2026

Auf dieser Seite

Bevor Sie loslegen

Für wen
Wer die Plattform betreibt — Geräte-Software freigibt, Störungen führt, Warteschlangen und Organisationen verwaltet
Voraussetzung
der Quellbaum der Plattform, ein Profil mit audience: "operator" und die Rechte platform.* aus der Spalte „Recht". Die Spalte „Schlüssel" sagt, ob ein Betreiber-Schlüssel opk_… das Recht tragen darf.

Die Befehle des Werkzeugs szenera-ops, die nur mit einem Profil vom Publikum operator laufen — einem Betreiber-Konto oder einem Betreiber-Schlüssel opk_…. Sie betreffen Kundinnen und Kunden der Plattform nicht und gehören nicht zur Kommandozeile szenera. Sie stehen hier, weil whoami, device, audit, player, playback, permission, api-key und invoice je nach Profil beide Seiten bedienen.

Das Werkzeug liegt im Quellbaum unter tools/ops-cli und wird nicht ausgeliefert. Es läuft mit pnpm -s szenera-ops <befehl> und führt alle 230 Befehle der Plattform. Profile, Umgebungsvariablen, Ausgabe und Exit-Codes sind dieselben wie bei szenera. Dazu kennt es das Publikum operator (Profilfeld audience, Umgebungsvariable SZENERA_AUDIENCE), seine eigene Profil-Datei .secrets/szenera-profile.json im Quellbaum und den Rückfall auf die Umgebungen in .secrets/umgebungen.json. Ein Befehl, der nur einer Seite dient, weist das Profil der anderen ab, bevor ein Aufruf hinausgeht.

Die Tabellen haben dieselbe Form wie unter Befehle für Ihre Organisation: Befehl, Zweck, Route und Recht, ob ein Schlüssel das Recht tragen darf, ob der Befehl etwas verändert. Betreiber-Schlüssel laufen 1 bis 365 Tage (Vorgabe 90). Welche Rechte ein solcher Schlüssel überhaupt führen darf, zeigt szenera-ops permission catalog --key-eligible unter einem Betreiber-Profil — es sind die lesenden Betriebsrouten, die Geräte-Software und das Lesen der Vermarktung. Alles andere bleibt Menschen mit Zwei-Faktor-Anmeldung vorbehalten. Von den 230 Befehlen des Werkzeugs stehen 136 unter Befehle für Ihre Organisation, es sind die Befehle von szenera. Die übrigen 94 laufen nur unter einem Betreiber-Profil und stehen hier. 21 der 136 dienen beiden Seiten: 14 davon nehmen unter einem Betreiber-Profil einen eigenen Weg (whoami, device list, device get, audit list, audit get, player get-program, playback timeline, permission catalog, die vier Befehle api-key …, invoice list und invoice get), sieben laufen unverändert (health, health public und die fünf Befehle des Notausgangs api …).

Gesundheit

Befehl Zweck Route und Recht Schlüssel Verändert
health deep Ein Urteil aus fünf Quellen, der Befehl nach dem Aufspielen. Eine rote Quelle macht den Befehl rot, eine stumme steht als unknown GET /health/ready, GET /v1/platform/ops/platform-health, GET …/ops/jobs/health, GET …/ops/cache/health, GET …/ops/events/dispatcher/health, GET …/ops/audit/health · platform.ops.health.read, platform.jobs.health.read, platform.cache.stats.read, platform.events.dispatcher.read, platform.audit.health.read teils — Cache und Prüfprotokoll nur mit Konto nein

Mit --json trägt die Antwort das Urteil unter verdict (green oder yellow) und je Quelle unter sources die Felder name, status und hint. Ein rotes Urteil endet stattdessen mit Exit 11. Die Gegenprobe von außen ist health public: dieselbe Auskunft, die die Statusseite zeigt, ohne Ausweis und ohne Betreiber-Profil — sie beantwortet „Was sehen unsere Kunden gerade?“ und nicht „Wie steht es wirklich?“. Der Befehl steht unter Befehle für Ihre Organisation.

Geräte der Flotte

Befehl Zweck Route und Recht Schlüssel Verändert
device list Die Geräte aller Organisationen, auch die ohne Organisation. Dazu --tenant=<tnt_…>, --all-tenants, --silent-only (seit über einer Viertelstunde stumm) GET /v1/platform/ops/devices · platform.ops.device.read ja nein
device get <dev_…> Ein Gerät in der Betriebssicht: Organisation und Seriennummer GET /v1/platform/ops/devices/{deviceId} · platform.ops.device.read ja nein
device lookup --serial=<text> Ein Gerät über die Hardware-Seriennummer finden GET /v1/platform/ops/devices/lookup · platform.ops.device.read ja nein
device get-command <dev_…> <cmd_…> Was aus einem Befehl an ein Gerät wurde. --wait wartet bis zum Ende (Exit 11 bei failed/timeout, Exit 12 beim Zeitlimit) GET /v1/platform/ops/devices/{id}/commands/{commandId} · platform.ops.device.command-read ja nein
device release <dev_…> --reason=reconnect|factory|removed --yes Ein Gerät freigeben, der Grund ist Pflicht. reconnect und removed lassen WLAN und Fernzugang stehen, factory nimmt beides mit. Alle Displays des Geräts gehen mit POST /v1/platform/ops/devices/{deviceId}/release · platform.ops.device.reset nein ja
device block <dev_…> --reason=<text> --yes Ein Gerät sperren: Es verliert seine Organisation, alle Displays gehen mit, jedes Zertifikat wird gesperrt, und jede Anmeldung weist die API mit 409 Device.Blocked ab. Der Grund (1 bis 500 Zeichen) ist Pflicht POST /v1/platform/ops/devices/{deviceId}/block · platform.ops.device.reset nein ja
device unblock <dev_…> Die Sperre aufheben. Das Gerät steht danach ungekoppelt und lässt sich neu koppeln POST /v1/platform/ops/devices/{deviceId}/unblock · platform.ops.device.reset nein ja
device check-ota <dev_…> Ein Gerät sofort nach einem neuen OS-Stand sehen lassen. Antwort 202, --wait braucht zusätzlich platform.ops.device.command-read POST /v1/platform/ops/devices/{id}/ota-check · platform.ops.device.ota-check ja ja
device channel --channel=beta|stable|canary --device=<dev_…> --yes Den Channel mehrerer Geräte in einem Aufruf wechseln, --device darf sich bis zu 100-mal wiederholen. Jedes Gerät bekommt sein Ergebnis, ein Gerät, das scheitert, hält die übrigen nicht auf POST /v1/platform/ops/devices/channel · platform.ops.device.channel nein ja
player get-program <ply_…> Was einem Display zugewiesen ist — über alle Organisationen, protokolliert GET /v1/platform/ops/devices/{playerId}/program · platform.ops.device.playback-read ja nein
playback timeline <ply_…> Die aufgelöste Abspiel-Timeline eines Displays — über alle Organisationen, protokolliert GET /v1/platform/ops/devices/{playerId}/timeline · platform.ops.device.playback-read ja nein

Jeder Aufruf von device get-command steht im Prüfprotokoll der betroffenen Organisation. Ein Betreiber-Profil kann mit device send-command und device screenshot nichts anfangen: Diese Routen verlangen fleet.player.command.issue und weisen eine Betreiber-Identität ab. Das Werkzeug sagt das vor dem Aufruf.

Störungen und Wartungsfenster

Befehl Zweck Route und Recht Schlüssel Verändert
incident list Die Störungsmeldungen, mit --id=<inc_…> eine einzelne samt Chronik GET /v1/platform/ops/incidents · platform.ops.incident.list, mit --id GET …/incidents/{id} · platform.ops.incident.read nein nein
incident create --title=… --severity=sev-1…sev-4 --scope=platform|tenant|device-fleet Eine Störung eröffnen. --public stellt sie zugleich auf die Statusseite, ohne die Flagge bleibt sie intern POST /v1/platform/ops/incidents · platform.ops.incident.open nein ja
incident update <inc_…> --message=… Einen Eintrag in die Chronik schreiben. --status wandert zugleich weiter, --public stellt die Störung auf die Statusseite, --internal nimmt sie herunter PATCH /v1/platform/ops/incidents/{id} · platform.ops.incident.update nein ja
incident resolve <inc_…> Eine Störung abschließen, dazu --postmortem=<url> POST /v1/platform/ops/incidents/{id}/resolve · platform.ops.incident.resolve nein ja
maintenance-window list Die geplanten Wartungsfenster, mit --id=<mtw_…> ein einzelnes GET /v1/platform/ops/maintenance-windows · platform.ops.maintenance.list, mit --id platform.ops.maintenance.read nein nein
maintenance-window create --title=… --start=… --end=… --scope=… Ein Wartungsfenster planen. --banner, --notify-days=<tage>, --block-mutations hält schreibende Aufrufe der Organisationen an POST /v1/platform/ops/maintenance-windows · platform.ops.maintenance.create nein ja
maintenance-window update <mtw_…> Ein Fenster verschieben oder umschreiben PATCH /v1/platform/ops/maintenance-windows/{id} · platform.ops.maintenance.update nein ja
maintenance-window cancel <mtw_…> --reason=… Ein Fenster absagen. Der Grund wandert in die Benachrichtigung DELETE /v1/platform/ops/maintenance-windows/{id} · platform.ops.maintenance.cancel nein ja

Warteschlangen, Cache, Ereignisse und Verbindungen

Befehl Zweck Route und Recht Schlüssel Verändert
job queues Die Warteschlangen samt Kennzahlen und Zustand — aus drei Quellen, eine Tabelle GET …/ops/jobs/queues, GET …/ops/jobs/metrics, GET …/ops/jobs/health · platform.jobs.queues.read, platform.jobs.metrics.read, platform.jobs.health.read ja nein
job pause <name> Eine Warteschlange pausieren. Was läuft, läuft zu Ende POST /v1/platform/ops/jobs/queues/{queueName}/pause · platform.jobs.queues.pause nein ja
job resume <name> Eine angehaltene Warteschlange fortsetzen POST /v1/platform/ops/jobs/queues/{queueName}/resume · platform.jobs.queues.resume nein ja
job failed Die endgültig gescheiterten Jobs, mit --not-replayed, --queue=<name>, --id=<kennung> GET /v1/platform/ops/jobs/dead-letter, GET …/dead-letter/{id} · platform.jobs.dead-letter.read ja nein
job replay --id=<kennung>|--all --reason=… Einen gescheiterten Job — oder viele — erneut einstellen. --max (Vorgabe 100) deckelt POST …/jobs/dead-letter/{id}/replay, POST …/jobs/dead-letter/bulk-replay · platform.jobs.replay nein ja
job kill <jobId> --queue=<name> --reason=… --yes Einen laufenden Job abbrechen, Antwort 202 POST /v1/platform/ops/jobs/{queueName}/{jobId}/force-kill · platform.jobs.force-kill nein ja
job cleanup --yes Alte Dead-Letter-Einträge räumen POST /v1/platform/ops/jobs/cleanup/run · platform.jobs.cleanup nein ja
cache stats Zustand, Trefferquote und die heißen Themen, dazu --window=1m|5m|1h GET …/ops/cache/health, GET …/ops/cache/stats, GET …/ops/cache/topics · platform.cache.stats.read nein nein
cache invalidate --topic=<thema>|--pattern=<glob> --reason=… --yes Ein Thema oder ein Muster verwerfen POST …/ops/cache/invalidate, POST …/ops/cache/invalidate-pattern · platform.cache.invalidate nein ja
event pending Was noch nicht ausgeliefert ist. --metrics hängt Zahlen und Gesundheit des Verteilers an GET /v1/platform/ops/events/outbox/pending · platform.events.outbox.read ja nein
event failed Was endgültig nicht ausgeliefert wurde GET /v1/platform/ops/events/outbox/dead-letter · platform.events.outbox.read ja nein
event get <evt_…> Ein Ereignis samt Nutzlast — genau das, was verschickt wurde GET /v1/platform/ops/events/outbox/{eventId} · platform.events.outbox.read ja nein
event replay --id=<evt_…>|--all --reason=… Ein Ereignis — oder viele — erneut zustellen, dazu --event-type, --since, --max POST …/events/outbox/{eventId}/replay, POST …/events/outbox/replay-bulk · platform.events.outbox.replay nein ja
connection list Die offenen Echtzeit-Verbindungen: Display, Portal-Sitzung oder Renderer GET /v1/platform/realtime/connections · platform.realtime.read nein nein
connection disconnect <id> --yes Eine Verbindung trennen. Der Client verbindet sich danach neu POST /v1/platform/realtime/connections/{id}/disconnect · platform.realtime.disconnect nein ja

Der Grund bei job replay, job kill, cache invalidate und event replay ist Pflicht und mindestens zehn Zeichen lang.

Fehler- und Rechte-Katalog

Befehl Zweck Route und Recht Schlüssel Verändert
error catalog Alle Fehlercodes der API samt HTTP-Status, dazu --search=<text> GET /v1/platform/ops/errors/catalog · platform.errors.catalog.read nein nein
permission catalog Der Rechte-Katalog. --key-eligible zeigt, was ein Betreiber-Schlüssel führen darf GET /v1/permission-catalog, nur Anmeldung nicht belegt nein
permission drift Was der Bestand gegenüber dem Katalog vermissen lässt. Ändert nichts GET /v1/platform/ops/permissions/catalog-drift · platform.permissions.catalog.read nein nein
permission reload Den Katalog neu einlesen — nötig, wenn App-Rechte dazukommen POST /v1/platform/ops/permissions/catalog/reload · platform.permissions.catalog.reload nein ja
permission backfill Die Rollen der Organisationen an den Katalog nachziehen, dazu --tenant=<tnt_…>. --dry-run rechnet nur, --reconcile nimmt auch weg. Betreiber-Konten brauchen das nicht: Ihre Rechte folgen der Rolle POST …/ops/permissions/roles/backfill · platform.permissions.role.backfill nein ja
permission flush-cache --yes Den Cache der wirksamen Rechte verwerfen POST /v1/platform/ops/permissions/cache/flush · platform.permissions.cache.flush nein ja

Organisationen

Befehl Zweck Route und Recht Schlüssel Verändert
tenant list Die Organisationen der Plattform (active, frozen, suspended, deleted) GET /v1/platform/tenants · platform.tenant.list nein nein
tenant get <tnt_…> Eine Organisation in der Betriebssicht GET /v1/platform/tenants/{id} · platform.tenant.read nein nein
tenant provision --slug=… --name=… --owner-email=… --address=… Organisation, Abonnement, Inhaber und Einladung in einem Zug, dazu --licenses, --set=<k=v> POST /v1/platform/tenants/provision · platform.tenant.provision, mit --set PATCH …/tenants/{tenantId}/feature-entitlements · platform.billing.override nein ja
tenant overview <tnt_…> Die Betriebsakte: Flotte, Inhalte, Ansprechpartner GET /v1/platform/tenants/{tenantId}/overview · platform.tenant.read nein nein
tenant suspend <tnt_…> --reason=… --yes Eine Organisation sperren — kaskadiert auf ihre Konten POST /v1/platform/tenants/{id}/suspend · platform.tenant.suspend nein ja
tenant resume <tnt_…> Eine Sperre aufheben POST /v1/platform/tenants/{id}/resume · platform.tenant.resume nein ja
tenant delete <tnt_…> --slug=… --yes Eine Organisation löschen, nicht umkehrbar. Der Kurzname ist die Bestätigung. Ihre Geräte werden freigegeben und zeigen danach einen Kopplungscode DELETE /v1/platform/tenants/{id} · platform.tenant.delete nein ja
tenant entitlements <tnt_…> Vertragliche Fähigkeiten lesen und mit --set=<k=v> setzen (Schalter on oder off) GET …/tenants/{tenantId}/feature-entitlements · platform.billing.invoice.read, PATCH … · platform.billing.override nein ja
tenant licensing <tnt_…> Vertragslage: Lizenzen, Artikel, Sonderkonditionen GET /v1/platform/tenants/{tenantId}/licensing · platform.billing.invoice.read nein nein
tenant price-override <tnt_…> --sku=<code> Eine Sonderkondition setzen (--price oder --discount, nie beides) oder mit --clear zurücknehmen PUT …/tenants/{tenantId}/licensing/items/{skuCode}/override · platform.billing.override nein ja
tenant sso-recovery <tnt_…> --email=… --reason=… --yes SSO-Notfallzugang für ein Konto ausstellen POST /v1/platform/tenants/{tenantId}/sso-recovery · platform.tenant.sso-recovery nein ja
self-registration set Selbst-Registrierung lesen, mit --on/--off --reason=… schalten GET/PUT /v1/platform/self-registration · platform.self-registration.manage nein ja

Die Einladungs-Adresse aus tenant provision steht im Klartext in der Ausgabe (--json: inviteUrl) — die einzige Stelle, an der dieses Token die API verlässt.

Betreiber-Konten und Betreiber-Schlüssel

Befehl Zweck Route und Recht Schlüssel Verändert
operator list Die Betreiber-Konten, mit --role=owner|manager|support|viewer, --status, --search und --with-permission=<platform.…> (Konten, deren Rolle das Recht trägt) GET /v1/platform/operators · platform.operator.list nein nein
operator get <ops_…> Ein Betreiber-Konto samt Rolle und der Stufe der Rolle je Bündel GET /v1/platform/operators/{id} · platform.operator.list nein nein
operator create --email=… --name=… --role=manager|support|viewer Ein Betreiber-Konto anlegen. Die Rolle ist Pflicht, owner gibt es hier nicht. Die Zwei-Faktor-Einrichtung erscheint genau einmal POST /v1/platform/operators · platform.operator.create nein ja
operator set-role <ops_…> --role=manager|support|viewer --yes Die Rolle ersetzen. Nur der Owner, nie die eigene, nie die des Owners. Die neuen Rechte gelten mit der nächsten Anfrage des Kontos PATCH /v1/platform/operators/{id}/role · platform.operator.create nein ja
operator transfer-owner <ops_…> --totp-code=<123456> Den Owner übertragen, Schritt 1: Der Owner bietet dem Konto an. Das Angebot gilt sieben Tage, ein neues ersetzt das frühere. --accept --totp-code=… (Schritt 2, unter dem Profil des Ziels) nimmt an, danach ist das Ziel Owner und der bisherige Owner Manager. --status zeigt das offene Angebot POST /v1/platform/operators/{id}/owner-transfer, POST …/operators/owner-transfer/accept, GET …/operators/owner-transfer · platform.operator.create, bei Annahme und Stand platform.operator.list nein ja
operator suspend <ops_…> --reason=… Ein Betreiber-Konto sperren POST /v1/platform/operators/{id}/suspend · platform.operator.suspend nein ja
operator reactivate <ops_…> Die Sperre aufheben POST /v1/platform/operators/{id}/reactivate · platform.operator.suspend nein ja
operator reset-mfa <ops_…> --reason=… --yes Zwei-Faktor neu einrichten. Der bisherige Authenticator gilt nicht mehr POST /v1/platform/operators/{id}/mfa-reset · platform.operator.mfa-reset nein ja
operator resend-onboarding <ops_…> Die Einrichtungs-Mail erneut verschicken. Sie gilt 72 Stunden POST /v1/platform/operators/{id}/onboarding-resend · platform.operator.mfa-reset nein ja
api-key list Die Betreiber-Schlüssel des Hauses GET /v1/platform/api-keys · platform.operator.api-key.list nein nein
api-key issue --name=… --permissions=<a,b,c> Einen Betreiber-Schlüssel opk_… ausstellen. --days=<1–365> (Vorgabe 90), --list-allowed zeigt die freigegebenen Rechte POST /v1/platform/api-keys · platform.operator.api-key.create nein ja
api-key rotate <oak_…> Einen Betreiber-Schlüssel erneuern, dazu --grace-hours=<0–72>, --days POST /v1/platform/api-keys/{id}/rotate · platform.operator.api-key.create nein ja
api-key revoke <oak_…> --yes Einen Betreiber-Schlüssel zurückziehen — sofort und endgültig DELETE /v1/platform/api-keys/{id} · platform.operator.api-key.revoke nein ja

Gerätesoftware

Der Baustein ist immer das erste Wort hinter dem Befehl: os, agent, renderer, host-webos oder host-tizen. Eine Version nennt der Befehl mit der Bau-Kennung (zwölf Hex-Stellen), list zeigt sie.

Befehl Zweck Route und Recht Schlüssel Verändert
device-software list <baustein> Die Versionen in der Ablage, neueste zuerst: Anzeigename mit Welt (0.6.1-prod), Bau, Stand, die Channels, in denen sie gilt, die Zahl der Geräte und die Größe GET /v1/platform/ops/device-software/{component}/builds · platform.ops.device-software.read ja nein
device-software releases <baustein> Was in den Channels gilt, und der Verlauf der Freigaben, mit --limit und --cursor GET …/device-software/{component}/releases · platform.ops.device-software.read ja nein
device-software devices <baustein> Die Geräte, die den Baustein fahren, mit Channel, Fassung, Bau und Stand zur Freigabe (current, updating, rolled-back, outdated, no-release). Dazu --channel, --build, --state GET …/device-software/{component}/devices · platform.ops.device-software.read ja nein
device-software activity Der Verlauf über alle Bausteine: Freigaben, Importe, Löschungen, Anfragen und die Rücknahmen, die Geräte meldeten. Dazu --component=<baustein> GET …/device-software/activity · platform.ops.device-software.read ja nein
device-software release <baustein> <bau> --channel=… --yes Eine Version in einem Channel gelten lassen. --pull-along=beta,canary zieht tiefere Channels im selben Schritt nach, --note, --security. Verlangt die Plattform eine zweite Person (releaseApproval.deviceSoftware), entsteht nach stable eine Anfrage, --reason=… ist dann Pflicht POST …/device-software/{component}/releases · platform.ops.device-software.release nein ja
device-software promote <baustein> --from=… --to=… --yes Den Bau, der heute im tieferen Channel gilt, im höheren freigeben, sonst wie release GET und POST …/device-software/{component}/releases · platform.ops.device-software.release nein ja
device-software delete <baustein> <bau> --yes Die Bytes einer Version löschen, der Datensatz bleibt als Grabstein. Geschützt ist eine Version, die in einem Channel gilt oder auf die eine Anfrage zeigt (DeviceSoftware.BuildInUse, Exit 6) DELETE …/device-software/{component}/builds/{build} · platform.ops.device-software.delete nein ja
device-software cleanup <baustein> --dry-run|--yes Die Versionen jenseits der neuesten --keep-newest=<n> (ohne Angabe retention.deviceSoftware.keepNewest) löschen, die sich löschen lassen. --dry-run nennt nur, was gelöscht würde POST …/device-software/{component}/builds/cleanup · platform.ops.device-software.delete nein ja
device-software nudge <baustein> <dsr_…> Die Geräte des Channels sofort an die geltende Freigabe erinnern POST …/device-software/{component}/releases/{id}/nudge · platform.ops.device-software.release nein ja
device-software image <bau> Die kurzlebige Bezugsadresse des SD-Karten-Abbilds zu einer Version von SzeneraOS GET …/device-software/os/builds/{build}/image · platform.ops.device-software.read ja nein

Einen Bau holt das Werkzeug nicht: Die Umgebung gleicht sich alle zehn Minuten mit der Registry ab, die CI beschleunigt es mit POST …/builds/import-from-registry (platform.ops.device-software.import, mit Betreiber-Schlüssel). release und promote verlangen --yes, weil eine Freigabe die Geräte des Channels erreicht.

Anfragen an eine zweite Person

Für Gerätesoftware und Apps gleich. Ob ein Release nach stable eine zweite Person braucht, stellt der Owner mit settings set releaseApproval.deviceSoftware|apps stable.

Befehl Zweck Route und Recht Schlüssel Verändert
approval list Die Anfragen, ohne --state die offenen. Dazu --state=open|approved|withdrawn|expired, --kind=device-software|app, --package=<baustein oder app> GET /v1/platform/ops/approvals · platform.ops.device-software.read oder platform.app-catalog.list ja nein
approval approve <rap_…> Eine Anfrage als zweite Person bestätigen und damit ausführen. Die anfragende Person selbst bekommt einen Satz und Exit 4 (ReleaseApproval.SamePerson) POST /v1/platform/ops/approvals/{id}/approve · platform.ops.release.approve nein ja
approval withdraw <rap_…> Eine Anfrage zurückziehen, als andere Person ablehnen. --reason=… ist freiwillig POST /v1/platform/ops/approvals/{id}/withdraw · platform.ops.release.approve oder platform.ops.device-software.release oder platform.app-catalog.promote nein ja

Plattform-Einstellungen

Befehl Zweck Route und Recht Schlüssel Verändert
settings get Alle Plattform-Einstellungen vollständig, eine nicht gesetzte mit ihrer Vorgabe GET /v1/platform/settings · platform.settings.read nein nein
settings set <einstellung> <wert> --yes Eine Einstellung ändern, zum Beispiel releaseApproval.apps stable oder retention.deviceSoftware.keepNewest 3. Der Wert wird gegen den Vertrag geprüft, bevor etwas hinausgeht PATCH /v1/platform/settings · platform.settings.manage (nur der Owner) nein ja

Die Einstellungen sind releaseApproval.deviceSoftware und releaseApproval.apps (off oder stable, Vorgabe off) sowie retention.deviceSoftware.keepNewest (1 bis 100, Vorgabe 5) und retention.deviceSoftware.auto (Vorgabe false). Dazu kommen retention.apps.keepNewest (1 bis 100, Vorgabe 5), retention.apps.unreferencedMonths (1 bis 120, Vorgabe 12) und retention.apps.auto (Vorgabe false). Jede Änderung steht mit altem und neuem Wert im Prüfprotokoll (platform.settings.changed).

App-Katalog

Befehl Zweck Route und Recht Schlüssel Verändert
app-release list Die Releases des App-Katalogs, mit --app=<app-id>, --channel=canary|beta|stable|deprecated|retired GET /v1/platform/app-catalog/apps, GET …/apps/{appId}/releases · platform.app-catalog.list nein nein
app-release set-notes <arl_…> --app=<app-id> --notes=… Die Release-Notizen ändern (max. 2000 Zeichen) PATCH …/apps/{appId}/releases/{id} · platform.app-catalog.update nein ja
app-release promote <arl_…> --app=<app-id> --channel=beta|stable Nach beta oder stable heben, immer ein Schritt. Nach stable hebt der Befehl sofort, wenn die Plattform keine zweite Person verlangt (releaseApproval.apps = off), sonst legt er eine Anfrage an, und --reason=… (10 bis 500 Zeichen) ist dann Pflicht POST …/apps/{appId}/releases/{id}/promote · platform.app-catalog.promote nein ja
app-release restore <arl_…> --app=<app-id> --reason=… Die Rücknahme einer veralteten oder abgelösten Fassung nach stable. Je nach Einstellung sofort oder als Anfrage, die eine zweite Person mit approval approve bestätigt. Die bis dahin geltende Fassung geht dabei nach deprecated POST …/apps/{appId}/releases/{id}/restore · platform.app-catalog.promote nein ja
app-release demote <arl_…> --app=<app-id> --channel=deprecated Ein Release aus stable nach deprecated zurückstufen, der einzige Schritt rückwärts POST …/apps/{appId}/releases/{id}/demote · platform.app-catalog.promote nein ja
app-release retire <arl_…> --app=<app-id> --reason=… --grace=regular|security|immediate Ein Release außer Betrieb nehmen. --grace wählt die Auslauffrist und hat keine Vorgabe: regular drei Monate, security einen Monat, dann ist der Sicherheitsvermerk --advisory=… für die Organisationen Pflicht, immediate keine Frist, die Plattform stellt sofort auf die nächsthöhere Fassung in stable um. Zu regular und immediate gibt es keinen Vermerk POST …/apps/{appId}/releases/{id}/retire · platform.app-catalog.retire nein ja
app-release grace-period <arl_…> --app=<app-id> Die Auslauffrist verlängern, um --months=<n> ab dem bisherigen Ende oder bis zum Ende eines Tages mit --until=<jjjj-mm-tt>, oder mit --immediately --reason=… sofort beenden. Genau eine Wahl POST …/releases/{id}/extend-grace, POST …/releases/{id}/force-retire · platform.app-catalog.retire nein ja
app-release delete-artifact <arl_…> --app=<app-id> --yes Die Bytes einer Fassung löschen, Zeile, Manifest und Historie bleiben. Geschützt ist eine Fassung in einem Kanal, mit Installation, Szene oder offener Anfrage (AppRelease.ArtifactInUse, Exit 6) DELETE …/apps/{appId}/releases/{id}/artifact · platform.app-catalog.delete nein ja
app-release cleanup --app=<app-id> --dry-run|--yes Die Bytes aller Fassungen jenseits der neuesten --keep-newest=<n> (ohne Angabe retention.apps.keepNewest) löschen, die sich löschen lassen. --dry-run nennt nur, was gelöscht würde POST …/apps/{appId}/releases/cleanup · platform.app-catalog.delete nein ja
app-status list Die Apps mit ihrem Betreiber-Status, Installationen und Ausnahmen GET /v1/platform/app-catalog/managed-apps · platform.app-catalog.list nein nein
app-status set <app> --status=active|beta|disabled --reason=… Eine App plattformweit setzen PATCH /v1/platform/app-catalog/managed-apps/{appId} · platform.app-catalog.status.manage nein ja
app-status override <app> Ausnahmen je Organisation lesen, mit --tenant und --status setzen, mit --clear entfernen GET …/managed-apps/{appId}/overrides · platform.app-catalog.list, PUT …/overrides/{tenantId}, POST …/overrides/{tenantId}/remove · platform.app-catalog.status.manage nein ja

Ob nach stable eine Person allein hebt, entscheidet die Einstellung releaseApproval.apps. Verlangt die Plattform eine zweite Person und nennt POST …/promote mit stable keine Begründung, antwortet es AppRelease.SecondPersonRequired (Exit 6). Mit Begründung entsteht eine Anfrage, die eine zweite Person mit approval approve bestätigt, sie verfällt nach sieben Tagen. Trägt die Prüfliste der Fassung eine Sperre, weisen promote (nach beta wie nach stable) und die Bestätigung einer Anfrage nach stable mit AppRelease.ReviewBlocked (Exit 6) ab, und der Befehl nennt die gesperrten Punkte: „Neu in dieser Fassung“ fehlt in der Pflichtsprache, oder ein Kundentext trägt ein Semikolon oder ein gesperrtes Wort. „Neu in dieser Fassung“ entsteht auf der Prüfung der Fassung im Betreiber-Portal, set-notes setzt nur den Text für den Betrieb.

Abrechnung und Artikel

Befehl Zweck Route und Recht Schlüssel Verändert
subscription set-payment-way <tnt_…> --way=invoice|stripe|none Den Zahlweg eines Vertrags stellen PUT /v1/platform/tenants/{tenantId}/billing/payment-way · platform.billing.override nein ja
subscription approve-invoice <tnt_…> --yes Den Kauf auf Rechnung freigeben. --revoke räumt die Freigabe ab PUT /v1/platform/tenants/{tenantId}/billing/payment-way · platform.billing.override nein ja
subscription check-stripe <tnt_…> Die Bindung eines Vertrags an den Zahlungsdienstleister prüfen. Ändert nichts GET /v1/platform/tenants/{tenantId}/billing/stripe-link · platform.billing.override nein nein
subscription relink-stripe <tnt_…> --yes Einen Vertrag neu an den Zahlungsdienstleister binden. Lebt der Kunde dort noch, geschieht nichts (unchanged) POST /v1/platform/tenants/{tenantId}/billing/relink-stripe · platform.billing.override nein ja
subscription backfill-period-prices --yes Die Perioden-Stückpreise des Bestands nachziehen — der Griff, wenn der Lauf beim Start der Anwendung gescheitert ist. Idempotent POST /v1/platform/billing/period-unit-prices/backfill · platform.billing.plan.manage nein ja
invoice list --tenant=<tnt_…>|--all-tenants Die Rechnungen aller Organisationen GET /v1/platform/invoices · platform.billing.invoice.read nein nein
invoice get <inv_…> Eine Rechnung samt Positionen GET /v1/platform/invoices/{id} · platform.billing.invoice.read nein nein
invoice mark-paid <inv_…> --yes Einen Zahlungseingang buchen POST /v1/platform/invoices/{id}/mark-paid · platform.billing.invoice.mark-paid nein ja
invoice refund <inv_…> --reason=… --yes Eine Rechnung erstatten POST /v1/platform/invoices/{id}/refund · platform.billing.invoice.refund nein ja
invoice issue-documents <inv_…> --yes PDF und E-Rechnung eines Belegs nachholen. Ein Beleg, der seine Dokumente schon trägt, bleibt unangetastet POST /v1/platform/invoices/{id}/issue-documents · platform.billing.invoice.refund nein ja
catalog list Der Artikelkatalog samt gesetzter Sonderkonditionen GET /v1/platform/billing/catalog · platform.billing.plan.manage, GET /v1/platform/billing/overrides · platform.billing.override nein nein
catalog set [sku] Einen Katalog-Artikel ersetzen (alle fünf Felder) oder mit --app=<app-id> --price=<cent> den Monatspreis einer App setzen PUT /v1/platform/billing/catalog/{skuCode}, PUT /v1/platform/billing/app-prices/{appId} · platform.billing.plan.manage nein ja

Unter einem Betreiber-Profil laufen außerdem audit list und audit get gegen GET /v1/platform/audit und GET /v1/platform/audit/{id} (platform.audit.read). --tenant oder --all-tenants ist dort Pflicht.

Weiterführendes