> ## Documentation Index
> Fetch the complete documentation index at: https://docs.payven.com.tr/llms.txt
> Use this file to discover all available pages before exploring further.

# Yeni API Anahtarı Oluşturma

> Konsoldan veya API üzerinden OAuth Client Credentials çifti üretin.

Yeni anahtarlar konsol veya programatik olarak oluşturulabilir. İki durumda da **`client_secret` yalnızca yanıtta bir kez** döner — sonradan tekrar erişilemez.

## Konsoldan oluşturma

<Steps>
  <Step title="API Anahtarları sayfası">
    Konsol → **Ayarlar → API Anahtarları**.
  </Step>

  <Step title="Yeni Anahtar Oluştur">
    Sağ üstteki butona basın.
  </Step>

  <Step title="Bilgileri girin">
    * **Görünen ad** — hangi servis/ortam için (örn. *"Production — Ödeme Servisi"*).
    * **İletişim e-postası** — opsiyonel; alarm/uyarı için.
    * **Plan** — bu anahtara atanacak plan (rate limit + kotalar).
    * **IP whitelist** — production için zorunlu kabul edin.
    * **Geçerlilik tarihi** — opsiyonel; geçici anahtarlar için.
  </Step>

  <Step title="Secret'i kopyalayın">
    Üretilen `client_secret` değerini güvenli bir yere (vault, secret manager) kopyalayın. **Bu pencere kapatıldıktan sonra bir daha gösterilmez.**
  </Step>
</Steps>

## API ile oluşturma

```http theme={null}
POST /api/v1/tenants/me/api-keys
```

Bearer access token gerektirir + kullanıcı `tenant-admin` rolünde olmalı.

```bash theme={null}
curl -X POST https://identity.payven.com.tr/api/v1/tenants/me/api-keys \
  -H "Authorization: Bearer $PAYVEN_TOKEN" \
  -H "Idempotency-Key: api-key-prod-payments-1" \
  -H "Content-Type: application/json" \
  -d '{
    "display_name":            "Production — Ödeme Servisi",
    "contact_email":           "ops@example.com",
    "merchant_id":             "M-IST-001",
    "plan_id":                 "abc-...",
    "daily_limit_override":    null,
    "monthly_limit_override":  null,
    "rate_limit_override":     null,
    "allowed_ips":             "52.18.42.10,52.18.42.0/24",
    "expires_at":              null
  }'
```

| Alan                     | Tip      | Zorunluluk | Açıklama                                                                |
| ------------------------ | -------- | ---------- | ----------------------------------------------------------------------- |
| `display_name`           | string   | Zorunlu    | Anahtar için açıklayıcı ad                                              |
| `contact_email`          | string   | Opsiyonel  | Alarm / uyarı e-postası                                                 |
| `merchant_id`            | string   | Opsiyonel  | Default merchant external ID — access token claim'ine yansır            |
| `plan_id`                | UUID     | Opsiyonel  | Atanacak plan — boş bırakılırsa tenant default'u                        |
| `daily_limit_override`   | int      | Opsiyonel  | Plan günlük limitini override eder (kuruş)                              |
| `monthly_limit_override` | int      | Opsiyonel  | Plan aylık limit override                                               |
| `rate_limit_override`    | int      | Opsiyonel  | Plan RPS override                                                       |
| `allowed_ips`            | string   | Opsiyonel  | CSV IP / CIDR listesi (örn. `52.18.42.10,10.0.0.0/8`). Boş = tüm IP'ler |
| `expires_at`             | datetime | Opsiyonel  | Anahtarın otomatik pasifleşeceği tarih (UTC, ISO 8601)                  |

## Yanıt

`201 Created` — `CreateApiKeyResult`:

```json theme={null}
{
  "api_key": {
    "id":                       "8e3f5c12-...",
    "tenant_id":                "1a2b3c4d-...",
    "client_id":       "pvk-payven-a1b2c3",
    "display_name":             "Production — Ödeme Servisi",
    "contact_email":            "ops@example.com",
    "merchant_id":              "M-IST-001",
    "plan_id":                  "abc-...",
    "plan_code":                "standard",
    "plan_name":                "Standart Plan",
    "effective_daily_limit":    100000,
    "effective_monthly_limit":  3000000,
    "effective_rate_limit":     200,
    "allowed_ips":              "52.18.42.10,52.18.42.0/24",
    "expires_at":               null,
    "is_active":                true,
    "created":                  "2026-05-03T12:34:56.789+00:00"
  },
  "secret": "AbC123dEf456GhI789jKl012MnO345pQ"
}
```

<Warning>
  **`secret` alanı yalnızca bu yanıtta dönecek.** Liste/detay endpoint'lerinde döndürülmez.
  Hemen secret manager'ınıza (HashiCorp Vault, AWS Secrets Manager, Azure Key Vault, Doppler, vb.) kaydedin.
</Warning>

## Hemen kullanmaya başlama

Aldığınız `client_id` + `client_secret` çifti ile [Identity'den access token alın](/documentation/concepts/authentication) ve ürün servislerine gönderin.

Access token içinde `tenant_id`, `merchant_id`, `plan_code`, `daily_limit`, `monthly_limit`, `rate_limit` gibi claim'ler taşınır — ürün servisleri bunları doğrudan doğrular, ek bir kimlik akışı gerekmez.

## Hata response'ları

Hata yanıtı RFC 9457 problem+json.

| HTTP  | `code`                  | Anlam                                             |
| ----- | ----------------------- | ------------------------------------------------- |
| `403` | `forbidden`             | `tenant-admin` rolü yok                           |
| `404` | `plan_not_found`        | Belirtilen `plan_id` bulunamadı                   |
| `409` | `api_key_limit_reached` | Plan kotanız aktif anahtar sayısı için doldu      |
| `422` | `invalid_ip_format`     | `allowed_ips` formatı geçersiz (IP / CIDR olmalı) |
| `422` | `invalid_expires_at`    | Geçmiş tarih veya format hatalı                   |
