
# Ein Branding-Asset hochladen

`POST /v1/branding/assets` · Berechtigung `branding:write`

Lädt ein Bild für die gehostete Anmeldeseite hoch: ein Logo, ein Favicon oder ein Hintergrundbild. Die `id` in der Antwort ist der Wert, den Sie in die Themenfelder `logo`, `favicon` oder `background_image` eintragen (siehe [Branding aktualisieren](./update.md)); das Bild erscheint nach dem Veröffentlichen auf der Anmeldeseite.

Jedes Bild wird in einem isolierten Prozess dekodiert und als PNG neu kodiert, höchstens 1024 × 1024 Pixel, wobei alle Metadaten entfernt werden. Ein Favicon erhält zusätzlich Versionen mit 32 px und 180 px. Die `id` ist der SHA-256-Hash des verarbeiteten PNG. Wenn dasselbe Bild erneut für dasselbe Feld hochgeladen wird, wird das vorhandene Asset mit `200 OK` zurückgegeben.

Akzeptierte Formate sind PNG, JPEG und WebP sowie ICO nur für Favicons. SVG wird nicht akzeptiert. Der Upload von Schriftarten ist nicht verfügbar.

Eine Umgebung kann höchstens 200 Assets und insgesamt 50 MB enthalten.

## Anfrage

Der Körper ist `multipart/form-data`, die Datei darf höchstens 1 MiB groß sein.

| Teil | Typ | Pflicht | Beschreibung |
|---|---|---|---|
| `kind` | string | ja | `logo`, `favicon` oder `background_image`. |
| `file` | file | ja | Das Bild. Höchstens 1 MiB und 8192 Pixel pro Seite. |

Bei einem `Idempotency-Key` muss ein Wiederholungsversuch exakt dieselben Bytes senden, einschließlich der Multipart-Begrenzung (Boundary).

## Antwort

`201 Created` für ein neues Asset, `200 OK`, wenn dasselbe Bild für dasselbe Feld bereits hochgeladen wurde.

```json
{
  "id": "3f0c…e91a",
  "kind": "favicon",
  "url": "https://acme.eu1.keenauth.app/assets/3f0c…e91a.png",
  "width": 256,
  "height": 256,
  "byte_size": 48213,
  "source_format": "ico",
  "favicon_32_url": "https://acme.eu1.keenauth.app/assets/9b1d…04c2.png",
  "favicon_180_url": "https://acme.eu1.keenauth.app/assets/c7e2…5a10.png",
  "created_at": "2026-10-19T20:30:00Z"
}
```

`byte_size` ist die Größe aller gespeicherten PNGs des Assets und zählt auf das Kontingent.

## Fehler

| HTTP | code | Wann |
|---|---|---|
| 400 | `malformed_request` | Der Multipart-Körper kann nicht gelesen werden oder enthält andere Teile als ein `kind` und eine `file`. |
| 401 | `unauthenticated` | Die Anmeldedaten fehlen, sind ungültig oder widerrufen. |
| 403 | `insufficient_permissions` | Die Anmeldedaten haben nicht die erforderliche Berechtigung. |
| 403 | `quota_exceeded` | Die Umgebung hat bereits 200 Assets oder 50 MB. |
| 413 | `payload_too_large` | Die Datei ist größer als 1 MiB. |
| 415 | `unsupported_media_type` | Der Körper ist nicht `multipart/form-data`, oder die Datei hat kein akzeptiertes Format (`unsupported_media_type`, `svg_not_allowed`, `ico_favicon_only` in `errors[]`). |
| 422 | `validation_failed` | `kind` oder `file` fehlt oder ist ungültig (`/kind font_upload_disabled` für Schriftarten), oder das Bild kann nicht verwendet werden: `invalid_image`, `image_too_large`, `image_dimensions_too_large`, `image_output_too_large`, `image_processing_limit`. |
| 422 | `idempotency_key_reuse` | Derselbe `Idempotency-Key` wurde mit einem anderen Körper verwendet. |
| 429 | `rate_limited` | Das Ratenlimit wurde überschritten; wiederholen Sie die Anfrage nach der Zeitspanne aus `Retry-After`. |
| 503 | `service_unavailable` | Der Asset-Speicher ist vorübergehend nicht verfügbar; wiederholen Sie die Anfrage nach der Zeitspanne aus `Retry-After`. |

## Beispiel

```bash
curl -X POST https://api.eu.keenauth.com/v1/branding/assets \
  -H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
  -F kind=logo \
  -F file=@logo.png
```

Mit der CLI:

```bash
keenauth branding assets upload --kind logo --file logo.png
```
