
# Markalama taslağını yayımla

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

Bütün taslakların (ortam, uygulamalar, organizasyonlar, metinler) anlık görüntüsünü alır ve barındırılan sayfalar için canlı sürüm yapar. Yayından önce her kapsamın etkin teması denetlenir: zorunlu jetonlar, değer aralıkları ve her renk çiftinin WCAG kontrastı. Herhangi bir sorun yayının tamamını `422 branding_validation_failed` ile reddeder; `issues[]` listesi değişmesi gereken her jetonu gösterir (kontrastta ölçülen `ratio`, `threshold` ve eşiği sağlayan en yakın `suggestion`). Son 50 sürüm saklanır. `Idempotency-Key` isteğe bağlıdır.

Taslakta özel CSS varsa yayından önce barındırılan ekranlarda çizilerek de denetlenir (25 saniyeye kadar sürebilen çizim denetimi; istemci zaman aşımını en az 30 saniye tutun). Korumalı bir öğeyi bozan ya da sayfada CSS'siz olmayan bir erişilebilirlik ihlali getiren CSS yayını `422 branding_validation_failed` ve `render_violations[]` listesiyle reddeder. Taslak denetim sırasında değişirse hiçbir şey yayımlanmaz ve `409 conflict` döner; yeniden yayımlayın.

## İstek

Bu işlem yol, sorgu ya da gövde alanı almaz. Ortam kimlik bilgisinden gelir.

## Yanıt

`200 OK`; yeni sürümün üst verisi (anlık görüntünün kendisi dönmez).

```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"}
  ]
}
```

Çizim denetimi reddi her bulguyu listeler: `screen` (ör. `password`), `locale` (`en`, `ar` ya da `ja`), `width` (CSS pikseli olarak görünüm genişliği, 320 ya da 1280), `rule` (`protected_no_area`, `protected_not_visible`, `protected_transparent`, `protected_covered`, `protected_contrast` ya da `color-contrast` gibi bir axe-core kural kimliği) ve `target` (korumalı öğenin adı ya da axe-core CSS seçicisi). CSS değeri yanıtta yer almaz. En çok 100 bulgu döner; daha fazlası varsa `render_violations_truncated` `true` olur.

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

## Hatalar

| HTTP | code | Ne zaman |
|---|---|---|
| 403 | `plan_feature_unavailable` | Taslakta özel CSS ya da sayfa şablonu var ve plan bunu içermiyor (`feature` hangisi olduğunu söyler). |
| 422 | `branding_validation_failed` | Taslak yayımlanamaz; `issues[]` listesine bakın. Taslaktaki özel CSS yayında yeniden arındırılır; geçmezse ihlaller `violations[]` uzantısındadır (bkz. `PUT /v1/branding/css`). Özel CSS çizim denetiminden geçmezse bulgular `render_violations[]` ve `render_violations_truncated` uzantılarındadır. |
| 409 | `conflict` | Özel CSS denetlenirken taslak değişti; hiçbir şey yayımlanmadı. Yeniden yayımlayın. |
| 401 | `unauthenticated` | Kimlik bilgisi yok, geçersiz ya da iptal edilmiş. |
| 403 | `insufficient_permissions` | Kimlik bilgisinde gerekli izin yok. |
| 429 | `rate_limited` | Hız sınırı aşıldı; `Retry-After` süresinden sonra yeniden deneyin. |
| 503 | `service_unavailable` | Bir bağımlılık (özel CSS'li taslağın çizim denetimi dahil) geçici olarak kullanılamıyor; `Retry-After` süresinden sonra yeniden deneyin. |

## Örnek

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