
# Téléverser un élément de marque

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

Téléverse une image pour la page de connexion hébergée : un logo, un favicon ou une image de fond. Le `id` de la réponse est la valeur que vous placez dans les champs de thème `logo`, `favicon` ou `background_image` (voir [Mettre à jour la marque](./update.md)) ; l'image apparaît sur la page de connexion après publication.

Chaque image est décodée dans un processus isolé puis réencodée en PNG, d'au plus 1024 × 1024 pixels, avec toutes les métadonnées supprimées. Un favicon reçoit aussi des versions de 32 px et de 180 px. Le `id` est le SHA-256 du PNG traité : téléverser à nouveau la même image pour le même champ renvoie l'élément existant avec `200 OK`.

Les formats acceptés sont PNG, JPEG et WebP, et ICO uniquement pour les favicons. SVG n'est pas accepté. Le téléversement de polices n'est pas disponible.

Un environnement peut contenir au plus 200 éléments et 50 Mo au total.

## Requête

Le corps est `multipart/form-data`, le fichier fait au plus 1 MiB.

| Partie | Type | Obligatoire | Description |
|---|---|---|---|
| `kind` | string | oui | `logo`, `favicon` ou `background_image`. |
| `file` | file | oui | L'image. Au plus 1 MiB et 8192 pixels par côté. |

Avec un `Idempotency-Key`, une nouvelle tentative doit envoyer exactement les mêmes octets, y compris la frontière multipart.

## Réponse

`201 Created` pour un nouvel élément, `200 OK` lorsque la même image a déjà été téléversée pour le même champ.

```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` est la taille de tous les PNG stockés de l'élément et compte dans le quota.

## Erreurs

| HTTP | code | Quand |
|---|---|---|
| 400 | `malformed_request` | Le corps multipart ne peut pas être lu, ou contient d'autres parties qu'un `kind` et un `file`. |
| 401 | `unauthenticated` | L'identifiant est absent, invalide ou révoqué. |
| 403 | `insufficient_permissions` | L'identifiant ne dispose pas de la permission requise. |
| 403 | `quota_exceeded` | L'environnement contient déjà 200 éléments ou 50 Mo. |
| 413 | `payload_too_large` | Le fichier dépasse 1 MiB. |
| 415 | `unsupported_media_type` | Le corps n'est pas `multipart/form-data`, ou le fichier n'est pas un format accepté (`unsupported_media_type`, `svg_not_allowed`, `ico_favicon_only` dans `errors[]`). |
| 422 | `validation_failed` | `kind` ou `file` est absent ou invalide (`/kind font_upload_disabled` pour les polices), ou l'image ne peut pas être utilisée : `invalid_image`, `image_too_large`, `image_dimensions_too_large`, `image_output_too_large`, `image_processing_limit`. |
| 422 | `idempotency_key_reuse` | La même `Idempotency-Key` a été utilisée avec un corps différent. |
| 429 | `rate_limited` | La limite de débit a été dépassée ; réessayez après la durée indiquée par `Retry-After`. |
| 503 | `service_unavailable` | Le stockage des éléments est temporairement indisponible ; réessayez après la durée indiquée par `Retry-After`. |

## Exemple

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

Avec la CLI :

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