# Geliştirici Portalı

WHost ile entegrasyon için **tek giriş noktası** burasıdır. Yapmak istediğinize
uyan yolu seçin:

| Yapmak istediğim… | Buradan başla |
|------------|------------|
| WHost'u herhangi bir billing platformuna entegre etmek | [Hızlı başlangıç](#h-zl-ba-lang) → [PHP SDK](sdk-php.md) → [SDK arşivindeki](https://whost.wisecp.com/developer/downloads/whost-php-sdk.zip) `examples/03-billing-integration-pattern.php` |
| Polling yapmak yerine yaşam döngüsü olaylarını almak | [Hızlı başlangıç](#h-zl-ba-lang) → [Webhook rehberi](webhooks.md) |
| REST API'yi doğrudan çağırmak (herhangi bir dil) | [Hızlı başlangıç](#h-zl-ba-lang) → [API referansı](api-reference.md) → [HMAC imzalayıcıları](#2-v2-hmac-imzas-n-hesapla) (5 dil) |
| Her endpoint'in şemasını okumak | [`api-reference-generated.md`](api-reference-generated.md) (629 operasyon) |
| Sürüm kararlılığı taahhüdünü anlamak | [`versioning-policy.md`](versioning-policy.md) |

---

## Hızlı Başlangıç

Her WHost API isteği dört HMAC header'ı gerektirir. Aşağıda kanonik payload
biçimi ve tek seferlik bir cURL probe'u yer alır — `200` döndüğünde çalışan
bir entegrasyon temeliniz olur.

API panelin kendi adresi altında sunulur:
`https://<panel-adresi>/api/v1/…`. Agent'ın kendisi yalnız `127.0.0.1:2000`
üzerinde dinler; panelin web sunucusu `/api/v1/` isteklerini ona iletir.

### 1. Kimlik bilgilerini al

Yönetici panelinde:

```
Ayarlar (üst çubuktaki dişli simgesi) → API Erişimi → API Anahtarı Oluştur
```

Genel bir entegrasyon için **Tam Erişim** kapsamını seçin — **Sadece Denetim
Okuma** kapsamlı bir anahtar yalnız `/api/v1/audit-logs`'a ulaşır. **API
Anahtarı** VE **API Gizli Anahtarı**'nı hemen kopyalayın — gizli anahtar
yalnızca **bir kez** gösterilir. Tüketen sunucunun sabit bir adresi varsa
anahtarı **İzin Verilen IP'ler** alanıyla (her satıra bir IP veya CIDR)
kısıtlayın.

### 2. v2 HMAC imzasını hesapla

Kanonik payload — her bileşen newline ile ayrılır:

```
METHOD\nPATH\nTIMESTAMP\nNONCE\nBODY
```

- `METHOD` — büyük harfli HTTP fiili (`GET`, `POST`, …)
- `PATH` — istek yolunun gönderildiği hâli, `/api/v1/...` öneki dahil:
  URL-decode edilmez; istekte sorgu dizesi varsa ardından `?` ve sorgu
  dizesi gelir (`/api/v1/accounts?limit=10`)
- `TIMESTAMP` — geçerli Unix zamanı, saniye cinsinden (string); sunucu
  saatinden en fazla 300 sn sapabilir
- `NONCE` — 16–256 karakter, **istek başına benzersiz** (örnekler 32 hex
  karakter kullanır); son 11 dakikada görülmüş bir nonce reddedilir
- `BODY` — isteğin gövde baytlarının kendisi (gövdesiz istekte boş)

`X-WHost-Signature`, bu payload'ın API gizli anahtarıyla anahtarlanmış
HMAC-SHA256 değerini küçük harfli hex olarak taşır.

Beş dilde çalışan imzalayıcılar — her biri `GET /api/v1/system/info`
isteğini imzalar:

| Dil | Dosya |
|----------|------|
| PHP | [`examples/hmac-example.php`](examples/hmac-example.php) |
| JavaScript / Node.js | [`examples/hmac-example.js`](examples/hmac-example.js) |
| Go | [`examples/hmac-example.go`](examples/hmac-example.go) |
| Ruby | [`examples/hmac-example.rb`](examples/hmac-example.rb) |
| Bash / POSIX sh | [`examples/hmac-example.sh`](examples/hmac-example.sh) |

### 3. İlk istek

```bash
# Yukarıdaki tablodaki Bash imzalayıcısını kullanarak:
export WHOST_BASE_URL="https://panel.example.com"   # panel adresi
export WHOST_API_KEY="..."
export WHOST_API_SECRET="..."
bash hmac-example.sh
# Beklenen: system/info zarfı — {"status":"success","data":{…}}
```

İstek reddedilirse yanıt gövdesindeki `error_code` hangi kontrolün
reddettiğini söyler (Bash imzalayıcı curl'ü gövdeyi gizleyen `-f` ile
çalıştırır — PHP, Node.js, Go ve Ruby imzalayıcıları durum kodunu ve gövdeyi
yazdırır):

- `401 AUTH_EXPIRED` — saat kayması (clock drift): `X-WHost-Timestamp`
  sunucu saatinden 300 sn'den fazla uzak. Çağıran host'ta
  `timedatectl status` çalıştırın.
- `401 AUTH_FAILED` — anahtar, imza veya nonce reddedildi. En yaygın
  sebepler:
  - Gövde bayt uyumsuzluğu — tam olarak gönderdiğiniz baytları imzalayın;
    sizin tarafınızda istek gövdesini yeniden sıkıştıran veya yeniden
    kodlayan bir proxy imzayı bozar.
  - Yanlış `PATH` — `/api/v1` ile başlamalı, büyük/küçük harfi ve varsa
    yüzde kodlamasını (percent-encoding) korumalı, sorgu dizesi varsa onu da
    içermelidir.
  - 16 karakterden kısa ya da daha önce kullanılmış bir nonce.
  - İmzanın büyük harfli hex olarak gönderilmesi.
- `403 IP_NOT_ALLOWED` — çağıran adres anahtarın İzin Verilen IP'ler
  listesinde değil.
- `403 SCOPE_DENIED` — anahtarın kapsamı bu yolu kapsamıyor.
- `429 AUTH_RATE_LIMITED` — tek bir adresten 5 dakika içinde 30 başarısız
  doğrulama o adresi bir saat engeller.

### 4. Idempotent hale getir

Her mutasyon yapan çağrı (`POST` / `PUT` / `PATCH` / `DELETE`) isteğe bağlı bir
`X-Idempotency-Key` header'ı kabul eder — `A–Z a–z 0–9 _ -` karakterlerinden
8–64 karakter (aksi hâlde `400 IDEMPOTENCY_KEY_INVALID`). Mantıksal
operasyon başına bir UUID v4 kullanın:

```bash
curl -X POST … \
     -H "X-Idempotency-Key: $(uuidgen)" \
     -d '{"username":"alice","password":"<hesap parolası>","domain":"alice.example.com","email":"alice@example.com","plan_id":"starter"}' \
     "$WHOST_BASE_URL/api/v1/accounts"
```

(`…`, `-H "Content-Type: application/json"` ile 2. adımdaki dört
`X-WHost-*` header'ının yerini tutar; imza gövde string'inin tam hâli
üzerinden hesaplanır.)

24 saat içinde aynı key + aynı body → saklanan yanıt tekrar oynatılır
(`X-Idempotent-Replay: true`). 2xx ve 4xx yanıtlar saklanır; 5xx yanıt
saklanmaz, bu yüzden 5xx sonrası tekrar deneme çağrıyı yeniden çalıştırır.
Aynı key + farklı metot, yol ya da body → `409 IDEMPOTENCY_KEY_REUSED`
(çağıran tarafta bug). Anahtar, onu gönderen API anahtarına (ya da oturuma)
aittir: aynı anahtarı başka bir kimlik gönderirse yeni istek çalışır ve sizin
saklanan yanıtınızı asla almaz.

Tam semantik: [`api-reference.md → Idempotensi`](api-reference.md#idempotensi).

### 5. Yaşam döngüsü olaylarına abone ol

Durum değişiklikleri için polling mi yapıyorsunuz? Yapmayın — bir webhook kaydedin:

```bash
curl -X POST … \
     -d '{
       "url": "https://your-system.example.com/whost-hook",
       "events": ["account.created","account.suspended","account.terminated","ssl.failed"],
       "description": "billing platform"
     }' \
     "$WHOST_BASE_URL/api/v1/system/webhooks"
```

Dönen `secret`'ı saklayın — gelen payload'ları HMAC ile doğrulamak için
kullanılır. Tam abone reçetesi (PHP SDK helper, imza formülü, tekrar
deneme semantiği, SSRF korumaları): [`webhooks.md`](webhooks.md).

---

## Referans dokümanlar

| Konu | Doküman |
|-------|----------|
| Kimlik doğrulama, idempotensi, sayfalama, hız sınırları, hata kataloğu | [`api-reference.md`](api-reference.md) |
| Endpoint başına tam şemalar (629 operasyon) | [`api-reference-generated.md`](api-reference-generated.md) |
| Webhook olay kataloğu (25 olay), payload, header'lar, imzalama, tekrar deneme | [`webhooks.md`](webhooks.md) |
| Sürüm kararlılığı taahhüdü (`/api/v1` içinde bozucu değişiklik yok; `/api/v2` duyurusundan v1'in kaldırılmasına en az 15 ay) | [`versioning-policy.md`](versioning-policy.md) |
| PHP SDK: indirme, kurulum, kapsadıkları | [`sdk-php.md`](sdk-php.md) |
| Python uygulama hosting (Django, Flask, FastAPI runtime pipeline) | [`python-apps.md`](python-apps.md) |
| HMAC imzalayıcı örnekleri (5 dil) | [Hızlı Başlangıç → 2. adım](#2-v2-hmac-imzas-n-hesapla) |

---

## Yaygın entegrasyon kalıpları

### Kalıp A — faturalama platformu sağlama hook'u

WISECP, WHMCS, Blesta ve özel faturalama sistemleri içindir.
Plain-PHP referansı: [SDK arşivindeki](https://whost.wisecp.com/developer/downloads/whost-php-sdk.zip) `examples/03-billing-integration-pattern.php`.

```
order_activated  → POST   /api/v1/accounts                     (idempotency key: "order-create-$id")
order_suspended  → POST   /api/v1/accounts/{u}/suspend         (key: "order-suspend-$id")
order_resumed    → POST   /api/v1/accounts/{u}/unsuspend       (key: "order-resume-$id")
order_cancelled  → DELETE /api/v1/accounts/{u}                 (key: "order-terminate-$id")
package_changed  → POST   /api/v1/accounts/{u}/change-package  (key: "pkg-change-$changeId")
```

Idempotensi anahtarları, timeout sonrası ağ tekrar denemelerinin güvenli
olması anlamına gelir — aynı mantıksal sipariş iki kez sağlama yapmaz.

### Kalıp B — bant dışı (out-of-band) faturalama mutabakatı

`account.` olaylarına abone olun (her birini adıyla yazın — `events`
filtresi joker karakter değil, tam olay adı alır); bir operatör panelden
manuel olarak askıya alma / yeniden etkinleştirme yaptığında faturalama
sisteminiz senkron kalır.

```
account.suspended         → faturalamada siparişi "suspended" olarak işaretle
account.unsuspended       → tekrar "active" duruma çevir
account.terminated        → iptali mutabık kıl
account.package_changed   → fiyatlandırmayı yeniden hesapla
account.password_changed  → yalnızca denetim logu kaydı
```

### Kalıp C — SSL sertifika olayları

```
ssl.failed   → nöbetçiyi ara + destek bileti aç
ssl.renewed  → açık bileti sustur (varsa)
ssl.issued   → yeni geçerlilik penceresini kaydet (data.extra.valid_to)
```

Bu olaylar panel ya da API üzerinden yapılan sertifika istek ve
yüklemelerinden doğar. certbot'un kendi zamanlamasıyla yaptığı
yenilemeler olay göndermez; her otomatik sertifika isteği de olay göndermez
(bkz. [olay kataloğu](webhooks.md#olay-katalo-u)). Süre bitimini izlemek için
`GET /api/v1/accounts/{username}/ssl/{domain}` (`valid_to`) çağrısını poll
edin.

### Kalıp D — yedek doğrulama

```
backup.completed → başarı + boyut + zamanlamayı kaydet (data.extra.size_mb)
backup.failed    → nöbetçiyi ara (operatörün sorumluluğu, müşterinin değil)
```

Arşivi oluşturulmuş ama uzak hedefe yüklemesi başarısız olmuş bir yedek,
`data.extra.remote_upload_error` dolu olarak `backup.completed` şeklinde
gelir.

### Kalıp E — metrikler üzerinden kapasite planlama

`/api/v1/system/info` endpoint'i CPU / bellek / disk kullanımı döndürür.
5 dakikalık aralıkla poll edin (okuma katmanı hız sınırı içinde) ve kendi
gözlemlenebilirlik yığınınızda trend takibi yapın;
`GET /api/v1/system/metrics?period=24h` (`24h`, `7d` veya `30d`) agent'ın
15 dakikada bir örneklediği geçmişi döndürür. WHost şu anda kendisi
Prometheus metrikleri yayımlamaz.

---

## Kararlılık & deprecation

`/api/v1/*` **kararlıdır** — bu önek altında bozucu değişiklik yayımlanmaz.
Geriye dönük uyumsuz çalışmalar `/api/v2/` üzerinden gider ve v1 ile
paralel sunulur: v2 duyurusu ile v1'in kaldırılması arasında en az
**15 ay** geçer (3 aylık beta artı en az 12 aylık deprecation penceresi).

Bu, bugün `v1`'e karşı yazılmış bir entegrasyonun v1 için duyurulan sunset
tarihine kadar değişmeden çalışmaya devam edeceği anlamına gelir. Tam
deprecation zaman çizelgesi, header kuralları ve v2 tanıtıldığında Sunset
header'larının nasıl görüneceği için
[`versioning-policy.md`](versioning-policy.md) dosyasını okuyun.

---

## Destek

| Kanal | Kullanım durumu |
|---------|----------|
| Destek talebi (wisecp.com müşteri paneli) | Hatalar, entegrasyon soruları, lisans sorunları, PHP SDK sorunları (SDK sürümünü `CHANGELOG.md`'den belirtin, [PHP SDK sayfası](sdk-php.md)) — ana kanal |
| `hello@wisecp.com` | Aynıları, talep açamadığınızda |
| Güvenlik açıklaması | `security@wisecp.com` — sorumlu açıklama (responsible disclosure) beklenir |

Bir entegrasyon hatasını raporlarken lütfen şunları ekleyin:
1. Tam istek (header'lar + body, secret'lar maskelenmiş)
2. Tam yanıt (status, header'lar, body)
3. Agent sürümü (`GET /api/v1/system/update/status` → `data.current_version`)
4. SDK sürümü, kullanılıyorsa
