API-Dokumentation

Version 1 · JSON · Bearer-Authentifizierung für alle /api/v1/*-Endpunkte außer dieser Dokumentation.

Basis

GET /api/v1/targets

Liefert aktive Repositories mit Git-URL, Tags und aktiven Build-Zielen (UUID, YAML-Pfad, Anzeigename).

Query: include_inactive=1 optional – dann auch deaktivierte Einträge.

Antwort 200:

{
  "repositories": [
    {
      "uuid": "…",
      "name": "Mein Repo",
      "git_url": "https://…",
      "active": true,
      "tags": [{ "id": 1, "name": "prod" }],
      "build_targets": [
        {
          "uuid": "…",
          "yaml_path": "config/device.yaml",
          "display_name": "Wohnzimmer",
          "active": true
        }
      ]
    }
  ]
}

GET /api/v1/stats

Aggregierte Auswertungen wie auf der Startseite: aktueller Stand, letzte 7 Tage, Gesamt, Friedenszeit, 14-Tage-Sparkline.

Query (optional, wie in der Weboberfläche):

Antwort 200 (Auszug):

{
  "filters": { "tags": ["prod"], "q": null },
  "current": { "ok": 5, "warning": 1, "error": 0, "unknown": 2, "total": 8, "stale": 0 },
  "week": { "ok": 12, "warning": 2, "error": 1, "unknown": 0, "total": 15, "success_rate": 93 },
  "all_time": { "…": "…" },
  "summary": {
    "targets_total": 8,
    "builds_24h": 4,
    "last_error_at": "2026-05-18 09:12:00",
    "last_error_ago": "vor 2 Tagen"
  },
  "distribution_pct": {
    "current": { "ok": 62.5, "warning": 12.5, "error": 0, "unknown": 25 },
    "week": { "…": "…" },
    "all_time": { "…": "…" }
  },
  "sparkline": [
    { "date": "2026-05-07", "builds": 0, "ok": 3, "warning": 0, "error": 0, "unknown": 1, "total": 3 }
  ]
}

Sparkline: total = nur Ziele mit bekanntem Stand (ohne unknown); builds = Anzahl Build-Läufe an dem Tag.

GET /api/v1/builds

Build-Ergebnisse (Liste), analog zur Seite „Build-Verlauf“.

Query:

Antwort 200:

{
  "scope": "week",
  "filters": { "status": null, "tags": [], "q": null },
  "limit": 250,
  "count": 2,
  "builds": [
    {
      "id": 123,
      "status": "error",
      "message": "Kompilierung fehlgeschlagen",
      "built_at": "2026-05-20 14:30:00",
      "target_uuid": "550e8400-…",
      "display_name": "Wohnzimmer",
      "yaml_path": "config/device.yaml",
      "repo_uuid": "…",
      "repo_name": "Mein Repo",
      "has_full_log": true
    }
  ]
}

Vollständiges Log: weiterhin über die Weboberfläche (/target/log); nicht Teil dieser API.

POST /api/v1/build/start

Meldet den Start eines Builds oder aktualisiert einen laufenden Build (Heartbeat). Das Ziel erscheint in der Weboberfläche unter „Laufende Builds“, bis ein finaler Status gemeldet wird oder das konfigurierte Timeout (Standard: 15 Minuten) ohne erneuten Aufruf abläuft.

JSON-Body:

Antwort 200: {"ok":true}

Während des Builds regelmäßig erneut aufrufen (z. B. alle 1–2 Minuten), damit der Eintrag nicht durch das Timeout verschwindet.

{
  "build_target_id": "550e8400-e29b-41d4-a716-446655440000",
  "message": "ESPHome compile …"
}

GET /api/v1/build/running

Liste aller aktuell laufenden Builds (nach Timeout bereinigt).

Query (optional): wie bei /api/v1/buildstag[], q

Antwort 200: running-Array mit target_uuid, display_name, yaml_path, repo_*, started_at, message

POST /api/v1/status

Finaler Status für genau ein Build-Ziel. Beendet automatisch einen laufenden Build für dieses Ziel. build_target_id ist die UUID des Ziels (nicht die interne Datenbank-ID).

JSON-Body (Pflicht / optional):

Antwort 200: {"ok":true,"build_result_id":123}

Antwort 422: {"ok":false,"error":"…"}

{
  "build_target_id": "550e8400-e29b-41d4-a716-446655440000",
  "status": "error",
  "built_at": "2026-05-20 14:30:00",
  "message": "Kompilierung fehlgeschlagen",
  "detail": "Kurzinfo für die Oberfläche",
  "full_log": "… vollständiges Log …",
  "errors": [
    {
      "title": "YAML Parse Error",
      "description": "…",
      "stack": "…",
      "file_path": "config/x.yaml",
      "line_number": 12,
      "excerpt": "… Ausschnitt …"
    }
  ],
  "warnings": []
}

GET /api/v1/secrets

Zentrale ESPHome-secrets.yaml für alle Build-Projekte (Key-Value, im Admin gepflegt).

Query: format=yaml (Standard) oder format=json

YAML (200): Content-Type: text/yaml – direkt als Datei verwendbar, z. B.:

wifi_ssid: "Mein WLAN"
wifi_password: "geheim"
api_key: "abc-123"

JSON (200): {"secrets":{"wifi_ssid":"Mein WLAN",…}}

Leerer Bestand: YAML = leerer Body, JSON = {"secrets":{}}

Fehlercodes (HTTP)