# Update-API

> Update-Prüfung, Downloads und CI-Upload.

Basis-URL je Produkt: `https://updates.cyrellian.com/<produkt>`.

## Update prüfen

```
GET /v1/check?edition=basic|unlimited&channel=stable|beta&version=1.2.3&instance=<instanceId>
Authorization: Bearer <lizenz>     (optional)
X-Update-Key: <update-schlüssel>   (optional)
```

Antwort:

```json
{
  "latest": { "version": "1.3.0", "releasedAt": "…", "notes": "…", "critical": false, "manual": true,
              "sha256": "…", "signature": "…", "downloadUrl": "…" },
  "plugins": [{ "id": "newsletter", "version": "1.0.0", "sha256": "…", "signature": "…", "premium": false, "downloadUrl": "…" }],
  "changelog": [{ "version": "1.3.0", "releasedAt": "…", "notes": "…" }]
}
```

- `downloadUrl` ist eine Stunde gültig – danach einfach erneut prüfen.
- Eingeschränkte Varianten (z. B. `unlimited`) liefern statt `downloadUrl` ein `requiresAuthorization: true`, wenn
  weder der Tarif der Lizenz noch ein [Update-Schlüssel](doc:update-schluessel) sie erlaubt.
- `manual: true` = die Release Notes verlangen manuelle Schritte, nie automatisch installieren.
- Image-basierte Produkte (Docsello) liefern `image` (z. B. `ghcr.io/ceddini/docsello:0.2.0`) statt einer Datei.

Vor dem Installieren prüft die Installation SHA-256 und [Signatur](doc:signaturen).

## Upload aus der CI

```
POST /ci/release   Authorization: Bearer <CI-Token>   multipart/form-data
  variant, version, channel (stable|beta), notes, notesUrl, critical, publish (true|false), image?, file?
POST /ci/plugin    (Produkte mit Plugins)
  file (Paket), channel, notes, publish, pluginId?, version?, minCoreVersion?, name?, description?, category?, author?
```

`409` heißt: diese Version gibt es schon (z. B. erneuter Workflow-Lauf) – kein Fehler. CI-Tokens erzeugt ein Operator
in der Konsole; signiert wird auf dem Server, die CI sieht den Schlüssel nie.
