
# Pubblicare la bozza di branding

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

Crea uno snapshot di tutte le bozze (ambiente, applicazioni, organizzazioni, testi) e lo rende la versione attiva delle pagine ospitate. Prima della pubblicazione viene verificato il tema effettivo di ogni ambito: token obbligatori, intervalli di valori e contrasto WCAG di ogni coppia di colori. Qualsiasi problema rifiuta l'intera pubblicazione con `422 branding_validation_failed` e un elenco `issues[]` che indica ogni token da modificare (per il contrasto con il `ratio` misurato, la `threshold` e la `suggestion` conforme più vicina). Vengono conservate le ultime 50 versioni. `Idempotency-Key` è facoltativo.

Se la bozza contiene CSS personalizzato, viene anche visualizzato sulle schermate ospitate prima di qualsiasi pubblicazione (un controllo di rendering che può richiedere fino a 25 secondi; usare un timeout client di almeno 30 secondi). Il CSS che rompe un elemento protetto o aggiunge una violazione di accessibilità che la pagina non ha senza di esso rifiuta la pubblicazione con `422 branding_validation_failed` e un elenco `render_violations[]`. Se la bozza cambia durante il controllo, non viene pubblicato nulla e si riceve `409 conflict`; pubblicare di nuovo.

## Richiesta

Questa operazione non accetta campi di percorso, query o corpo. L'ambiente deriva dalla credenziale.

## Risposta

`200 OK` con i metadati della nuova versione (lo snapshot non viene restituito).

```json
{
  "version": 4,
  "snapshot_sha256": "3f1c…",
  "source": "publish",
  "rolled_back_from": null,
  "actor_type": "api_key",
  "actor_id": "key_01jb…",
  "published_at": "2026-10-05T09:31:00Z"
}
```

```json
{
  "type": "https://docs.keenauth.com/problems/branding_validation_failed",
  "status": 422,
  "code": "branding_validation_failed",
  "issues": [
    {"scope_type": "environment", "code": "brand_contrast_insufficient", "field": "light.color.primary_contrast",
     "variant": "light", "pair": "primary_contrast_on_primary", "ratio": 2.1, "threshold": 4.5, "suggestion": "#ffffff"}
  ]
}
```

Un rifiuto del controllo di rendering elenca ogni riscontro: `screen` (ad esempio `password`), `locale` (`en`, `ar` o `ja`), `width` (larghezza della viewport in pixel CSS, 320 o 1280), `rule` (`protected_no_area`, `protected_not_visible`, `protected_transparent`, `protected_covered`, `protected_contrast` oppure un ID di regola axe-core come `color-contrast`) e `target` (il nome dell'elemento protetto o un selettore CSS axe-core). I valori CSS non vengono mai restituiti. Vengono restituiti al massimo 100 riscontri; `render_violations_truncated` è `true` se ce n'erano di più.

```json
{
  "type": "https://docs.keenauth.com/errors/branding_validation_failed",
  "status": 422,
  "code": "branding_validation_failed",
  "render_violations": [
    {"screen": "recovery", "locale": "ar", "width": 320, "rule": "protected_covered", "target": "recovery_codes_hint"}
  ],
  "render_violations_truncated": false
}
```

## Errori

| HTTP | code | Quando |
|---|---|---|
| 403 | `plan_feature_unavailable` | La bozza contiene CSS personalizzato o un modello di pagina non incluso nel piano (`feature` indica quale). |
| 422 | `branding_validation_failed` | La bozza non può essere pubblicata; vedere `issues[]`. Il CSS personalizzato della bozza viene sanificato di nuovo alla pubblicazione; se non lo supera, le violazioni sono nell'estensione `violations[]` (vedere `PUT /v1/branding/css`). Se il CSS personalizzato non supera il controllo di rendering, i riscontri sono in `render_violations[]` e `render_violations_truncated`. |
| 409 | `conflict` | La bozza è cambiata mentre il suo CSS personalizzato veniva controllato; non è stato pubblicato nulla. Pubblicare di nuovo. |
| 401 | `unauthenticated` | La credenziale manca, non è valida o è stata revocata. |
| 403 | `insufficient_permissions` | La credenziale non ha il permesso richiesto. |
| 429 | `rate_limited` | Il limite di frequenza è stato superato; riprovare dopo il periodo `Retry-After`. |
| 503 | `service_unavailable` | Una dipendenza è temporaneamente non disponibile (incluso il controllo di rendering di una bozza con CSS personalizzato); riprovare dopo il periodo `Retry-After`. |

## Esempio

```bash
curl -X POST https://api.eu.keenauth.com/v1/branding:publish \
  -H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
  -H "Idempotency-Key: $(uuidgen)"
```
