# Idempotensi

Her mutating endpoint (`POST`, `PUT`, `PATCH`, `DELETE`) isteğe bağlı
bir `X-Idempotency-Key` header'ı kabul eder. Aynı anahtarı
**aynı metot, yol ve gövde ile** 24 saat içinde tekrar oynatmak, altta
yatan yan etkiyi yeniden çalıştırmadan orijinal yanıtı döndürür — ağ
hatalarında tekrar deneme yapabilecek partner faturalama hook'ları için
güvenli bir özelliktir.

Anahtar, onu gönderen kimliğe aittir: her API anahtarının, yönetici
oturumunun ve her müşteri oturumunun anahtarları ayrıdır. Aynı anahtar
başka bir kimlikle gönderilirse yeni istek olarak çalışır; ilk çağıranın
saklanan yanıtını asla almaz.

API'nin yalnız bir kez gösterdiği gizli değerler — yeni API anahtarı ya da
webhook sırrı, 2FA kurulum bilgisi ve yedek kodlar, tek kullanımlık giriş
bağlantısı, OAuth belirteçleri — saklanan yanıtta tutulmaz: `secret`,
`otpauth_uri`, `backup_codes`, `login_url`, `access_token`,
`refresh_token`, `oauth_token` ve `password` alanları `"***"` olarak
saklanır; tekrar, işlemin sonucunu gizli değer olmadan döndürür. İlk yanıt
kaybolduysa sırrı yeniden döndürün ya da yeniden oluşturun.

| Davranış | Tetikleyici |
|----------|-------------|
| İlk çağrı | Anahtar görülmedi → istek çalışır, yanıt 24 saat cache'lenir. |
| Tekrar (aynı kimlik, anahtar, metot, yol ve gövde) | Orijinal `status` + `body` + `X-Idempotent-Replay: true` header'ını döndürür. |
| Bir kez gösterilen gizli değer taşıyan yanıtın tekrarı | Aynı `status` ve gövde, gizli değer alanları `"***"`; işlem yeniden çalışmaz. |
| Tekrar (aynı kimlik ve anahtar, **farklı metot, yol ya da gövde**) | `409 IDEMPOTENCY_KEY_REUSED` — partner bug'ı olarak sunulur. |
| Aynı anahtar **başka bir kimlikten** | Yeni istek olarak çalışır; yanıtlar kimlikler arasında paylaşılmaz. |
| Geçersiz anahtar formatı | `400 IDEMPOTENCY_KEY_INVALID` (`^[A-Za-z0-9_-]{8,64}$` ile eşleşmeli). |
| İlk çağrıda 5xx | **Cache'lenmez** — istemci çakışma olmadan tekrar deneyebilir. |

**Önerilen anahtar:** UUID v4, mantıksal operasyon başına bir kez
üretilir ve o operasyonun tüm tekrar denemelerinde yeniden kullanılır.

```bash
curl -X POST \
  -H "X-WHost-Key: …"     -H "X-WHost-Timestamp: …" \
  -H "X-WHost-Nonce: …"   -H "X-WHost-Signature: …" \
  -H "X-Idempotency-Key: $(uuidgen)" \
  -d '{"username":"alice","plan_id":3}' \
  https://panel.example.com/api/v1/accounts
```

---
