# Die Kommandozeile szenera

`szenera` wählt die Form der Ausgabe selbst, trennt die Fehlerarten über Exit-Codes und bündelt Umgebung und Ausweis in einem Profil. Ein fertiges Paket zum Herunterladen gibt es heute nicht; wie Sie das Werkzeug beziehen, steht zusammen mit der ausführlichen Referenz — Anmelden, jeder Befehl mit allen Flaggen, Ausgabe als JSON, Exit-Codes — unter `https://developer.szenera.com/cli`.

> **Typ:** nachschlagen
> **Für wen:** Wer Szenera aus Skripten heraus bedient oder sich schnell etwas ansehen will, ohne das Portal zu öffnen.
> **Voraussetzung:** Für die meisten Befehle ein API-Schlüssel Ihrer Organisation oder ein Konto Ihrer Organisation samt zweitem Faktor. `szenera health` kommt ohne beides aus.

## Der Grundsatz: eine Ausgabe für Menschen, eine für Prozesse

`szenera` entscheidet die Form selbst. Ist die Standardausgabe ein Terminal, kommt eine Tabelle mit einer Kopfzeile darüber. Ist sie es nicht — weil die Ausgabe in eine Datei oder eine Weiterleitung geht —, kommt JSON. Erzwingen lässt sich beides mit `--table` und `--json`.

Im JSON-Modus steht auf der Standardausgabe das Ergebnis und sonst nichts: keine Hülle, kein Statusfeld, keine Zeitmessung. Ein Skript liest also `.items[]` und nicht `.daten.items[]`. Fehler gehen ausnahmslos auf die Fehlerausgabe — eine umgeleitete Ausgabe hinterlässt im Fehlerfall keine Datei, die aussieht wie ein Ergebnis.

## Die wichtigsten Befehle

Diese Befehle brauchen Sie am häufigsten; `szenera --help` zeigt den vollständigen Satz.

| Befehl | Was er tut |
|---|---|
| `szenera health` | Meldet, ob die Umgebung sich bereit meldet. Braucht keinen Schlüssel. |
| `szenera whoami` | Sagt, wer der eigene Ausweis ist. |
| `szenera device list` | Die Geräte der Organisation. |
| `szenera location list` | Die Standorte samt der Zahl der Displays, die an ihnen hängen. |
| `szenera hygiene get` | Zählt, was liegen geblieben ist: unbenutzte Medien, Szenen ohne Zuweisung, Displays ohne Programm oder lange ohne Meldung, ruhende Konten, tote Ereignis-Ziele. |
| `szenera api get <path>` | Liest einen beliebigen Pfad der API. |
| `szenera api post\|put\|patch\|delete <path> [body]` | Der Notausgang zu jedem schreibenden Pfad. Der Rumpf steht als JSON direkt im Aufruf oder als `@datei.json`. |

`szenera <befehl> --help` zeigt einen einzelnen Befehl mit seinen Stellungen, Flaggen und Beispielen. Die Hilfe entsteht aus derselben Beschreibung, aus der die Befehle selbst entstehen — eine Hilfe, die etwas anderes sagt als das Werkzeug, kann es hier nicht geben.

Eine Flagge trägt ihren Wert immer am Gleichheitszeichen: `--limit=20`, nicht `--limit 20`.

Jeder verändernde Aufruf trägt von selbst einen frischen Idempotenz-Schlüssel. Selbst setzen können Sie ihn nur beim rohen Aufruf: `szenera api post <path> <body> --idempotency-key=<schluessel>`. Nötig ist das, um eine abgebrochene Wiederholung fortzusetzen, ohne dass der Vorgang ein zweites Mal passiert.

## Exit-Codes

Die Codes trennen die Fehlerarten, damit ein Skript reagieren kann, ohne Text zu vergleichen. Im JSON-Modus steht die Art zusätzlich als Wort in der Fehlerausgabe, unter `error.kind`.

| Code | Art | Bedeutung |
|---|---|---|
| `0` | `ok` | Alles in Ordnung. |
| `1` | `usage` | Der Aufruf war falsch: unbekannter Befehl, fehlende Angabe, falsche Flagge — oder eine Anfrage, die dem Vertrag widerspricht. |
| `2` | `config` | Die Konfiguration trägt nicht: Profil fehlt oder ist kaputt, Ausweis fehlt, Profil gesperrt. |
| `3` | `auth` | Anmeldung abgelehnt. |
| `4` | `forbidden` | Recht fehlt. |
| `5` | `not-found` | Nicht gefunden. |
| `6` | `conflict` | Konflikt. |
| `7` | `validation` | Die Angaben wurden abgewiesen. |
| `8` | `rate-limited` | Zu viele Aufrufe in kurzer Zeit. |
| `9` | `server` | Server — oder eine Antwort, die dem Vertrag widerspricht. |
| `10` | `network` | Gar keine Antwort. |
| `11` | `failed` | Der Aufruf kam durch und der Vorgang endete rot. |
| `12` | `timeout` | Zeitlimit erreicht; der Ausgang ist unbekannt. |

Die letzten beiden sind bewusst nicht `9`. Beide kamen durch, und wer ein Zeitlimit wie einen Fehlschlag behandelt, stößt einen bereits laufenden Vorgang ein zweites Mal an.

Bricht eine **Antwort** den Vertrag, ist der häufige Grund ein Versatz der Stände: Die Gegenstelle ist älter oder neuer als das Werkzeug, das sie fragt. Die Meldung sagt das und nennt die Felder; `--raw` legt zusätzlich die unveränderte Antwort auf die Standardausgabe.

## Profile

Ein Profil bündelt zwei Dinge: den Ausweis und die Zuordnung von Dienst zu Basis-Adresse. Die Profildatei liegt unter `~/.config/szenera/profile.json`. Als Ausweis dient in der Regel ein API-Schlüssel, der nicht nach Minuten abläuft und deshalb ohne Sitzungspflege auskommt. Wer nur kurz nachsehen will, meldet sich stattdessen mit Kennwort und zweitem Faktor an. Ein Profil kann schreibgeschützt sein (`readOnly`) — dann bricht jeder verändernde Befehl ab, statt sich auf Ihre Umsicht zu verlassen.

Statt einer einzelnen Adresse trägt ein Profil eine Zuordnung. Solange alles auf demselben Server liegt, genügt der Eintrag `*`. Zieht ein Dienst später um, kommt er mit eigener Adresse dazu, und kein Skript ändert sich.

Umgebungsvariablen stehen über der Datei, damit ein Lauf ohne Datei auskommt und kein Geheimnis auf eine Platte muss:

| Variable | Wirkung |
|---|---|
| `SZENERA_PROFILE` | Welches Profil gilt. `--profile=` schlägt sie. |
| `SZENERA_BASE_URL` | Setzt den `*`-Eintrag und trägt damit ohne Datei ein ganzes Profil. |
| `SZENERA_API_KEY` | Der API-Schlüssel; er ersetzt den Ausweis des Profils. |
| `SZENERA_OUTPUT` | `json` oder `table`. `--json` und `--table` schlagen sie. |
| `SZENERA_PROFILE_FILE` | Wo die Profildatei liegt. |

Ein Konto, das zu mehreren Organisationen gehört, bricht die Anmeldung ab, statt zu raten. Ein Schlüssel kennt diese Frage nicht: Er gehört genau einer Organisation.

## Weiterführendes

- [Einen API-Schlüssel erzeugen, rotieren und widerrufen](/docs/entwickler/api-schluessel-erzeugen)
- [Was können eigene Programme mit Szenera tun?](/docs/entwickler/was-es-gibt)
