
# Caricare una risorsa di branding

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

Carica un'immagine per la pagina di accesso ospitata: un logo, un favicon o un'immagine di sfondo. L'`id` nella risposta è il valore che inserisci nei campi del tema `logo`, `favicon` o `background_image` (vedi [Aggiornare il branding](./update.md)); l'immagine compare nella pagina di accesso dopo la pubblicazione.

Ogni immagine viene decodificata in un processo isolato e ricodificata come PNG, al massimo 1024 × 1024 pixel, con tutti i metadati rimossi. Un favicon riceve anche le versioni a 32 px e 180 px. L'`id` è lo SHA-256 del PNG elaborato: caricare di nuovo la stessa immagine per lo stesso campo restituisce la risorsa esistente con `200 OK`.

I formati accettati sono PNG, JPEG e WebP, e ICO solo per i favicon. SVG non è accettato. Il caricamento dei font non è disponibile.

Un ambiente può contenere al massimo 200 risorse e 50 MB in totale.

## Richiesta

Il corpo è `multipart/form-data`, il file può essere lungo al massimo 1 MiB.

| Parte | Tipo | Obbligatoria | Descrizione |
|---|---|---|---|
| `kind` | string | sì | `logo`, `favicon` o `background_image`. |
| `file` | file | sì | L'immagine. Al massimo 1 MiB e 8192 pixel per lato. |

Con un `Idempotency-Key`, un tentativo ripetuto deve inviare esattamente gli stessi byte, incluso il boundary multipart.

## Risposta

`201 Created` per una nuova risorsa, `200 OK` quando la stessa immagine era già stata caricata per lo stesso campo.

```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` è la dimensione di tutti i PNG memorizzati della risorsa e conta ai fini della quota.

## Errori

| HTTP | code | Quando |
|---|---|---|
| 400 | `malformed_request` | Il corpo multipart non può essere letto, oppure contiene parti diverse da un `kind` e un `file`. |
| 401 | `unauthenticated` | La credenziale manca, non è valida o è stata revocata. |
| 403 | `insufficient_permissions` | La credenziale non ha il permesso richiesto. |
| 403 | `quota_exceeded` | L'ambiente ha già 200 risorse o 50 MB. |
| 413 | `payload_too_large` | Il file supera 1 MiB. |
| 415 | `unsupported_media_type` | Il corpo non è `multipart/form-data`, oppure il file non è in un formato accettato (`unsupported_media_type`, `svg_not_allowed`, `ico_favicon_only` in `errors[]`). |
| 422 | `validation_failed` | `kind` o `file` manca o non è valido (`/kind font_upload_disabled` per i font), oppure l'immagine non può essere usata: `invalid_image`, `image_too_large`, `image_dimensions_too_large`, `image_output_too_large`, `image_processing_limit`. |
| 422 | `idempotency_key_reuse` | La stessa `Idempotency-Key` è stata usata con un corpo diverso. |
| 429 | `rate_limited` | È stato superato il limite di richieste; riprova dopo il periodo indicato in `Retry-After`. |
| 503 | `service_unavailable` | L'archiviazione delle risorse non è temporaneamente disponibile; riprova dopo il periodo indicato in `Retry-After`. |

## Esempio

```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
```

Con la CLI:

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