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

# Kimlik doğrulama hataları

> OAuth protokol hatalarını ve API'nin 401 ile 403 yanıtlarını ayırt etmeyi ve çözmeyi anlatır.

Kimlik doğrulama sırasında iki farklı sunucu hata döndürür. Kimlik sunucusu (`/oauth/authorize`, `/oauth/token`) OAuth protokol hatalarını verir. API (`/api/v1/...`) ise kendi hata zarfıyla `401`, `403` ve klinik başlığıyla ilgili hataları verir. Yanıtın biçimine bakarak hangi katmanda takıldığınızı hemen anlarsınız.

| Katman | Yanıt gövdesi | Hata alanı |
| - | - | - |
| Kimlik sunucusu | `{"error": "...", "error_description": "...", "hint": "..."}` | `error` |
| API | `{"success": false, "error_code": "...", "message": "..."}` | `error_code` |

API genel hata zarfı ve tüm hata kodları için [Hata kodları](/api/istekler/hata-kodlari) sayfasına bakın.

## OAuth hata yanıtları

Kimlik sunucusu hatayı iki yoldan bildirir:

* **JSON yanıt:** `error`, `error_description` ve çoğu zaman `hint` alanları ve bir HTTP durum kodu. Yanıtta `message` alanı yoktur.
* **Yönlendirme:** Geçerli bir `redirect_uri` biliniyorsa sunucu `302` ile bu adrese döner. Aynı alanlar (ve `state`) sorgu dizesinde gelir. Yetkilendirme adımındaki hatalar genellikle bu yoldan gelir.

`hint` alanı sorunun tam yerini söyler. Örneğin ``Check the `client_secret` parameter``. Hata ayıklarken önce `hint` değerini okuyun.

| `error` | HTTP | Ne zaman |
| - | - | - |
| `invalid_request` | 400 | Zorunlu parametre eksik (`client_id`, `code`, `refresh_token`, `code_verifier`, `redirect_uri`). Gizli (confidential) istemcide `client_secret` yok. PKCE değerleri biçime uymuyor. Kod başka bir istemciye verilmiş. Token isteğindeki `redirect_uri` yetkilendirmedekiyle aynı değil. |
| `invalid_client` | 401 | İstemci bilinmiyor veya erişimi kaldırılmış. `client_secret` yanlış. Ayrıntı aşağıda. |
| `unauthorized_client` | 400 | İstemcinin `grant_types` listesinde istenen grant yok. Örnek: API ile oluşturulan bir uygulamada `client_credentials`. |
| `invalid_grant` | 400 | Kod veya refresh token geçersiz. Ayrıntı aşağıda. |
| `invalid_scope` | 400 veya yönlendirme | İstenen scope geçersiz. Ayrıntı aşağıda. |
| `unsupported_grant_type` | 400 | Desteklenmeyen grant veya `response_type`: `password`, `response_type=token` ya da yazım hatası. |
| `access_denied` | yönlendirme | Kullanıcı onay ekranında **İptal Et**'e bastı. |
| `login_required` | yönlendirme | `prompt=none` gönderdiniz ama kullanıcının oturumu yok. |
| `consent_required` | yönlendirme | `prompt=none` gönderdiniz ama kullanıcının onayı gerekiyor. |

Token uç noktası dakikada, IP başına 60 istekle sınırlıdır. Aşarsanız `429` alırsınız. Sınırlar için [Oran sınırları](/api/istekler/oran-sinirlari) sayfasına bakın.

<Note>
  `unsupported_grant_type` yanıtı, uygulamanızın `authorization_code` ve `refresh_token` dışında bir akış denediğini gösterir. Desteklenen akış için [Yetkilendirme kodu ve PKCE](/api/kimlik-dogrulama/yetkilendirme-kodu-ve-pkce) sayfasına bakın.
</Note>

## `invalid_scope`

Sunucu istenen scope'u şu durumlarda reddeder:

* Scope katalogda yok veya pasif.
* Scope, uygulamanız için izin verilenler arasında değil.
* Yenileme (`refresh_token`) isteğinde, ilk yetkilendirmede verilenden **fazla** scope istediniz.

Yetkilendirme adımında tek bir geçersiz scope tüm isteği düşürür. Sunucu geçerli olanları sessizce ayıklamaz. Hata, `error=invalid_scope` olarak `redirect_uri` adresine döner ve `hint` alanında sorunlu scope'u (``Check the `customers:write` scope``) bildirir.

Sorun nasıl çözülür:

<Steps>
  <Step title="hint alanını okuyun">
    Reddedilen scope'un adı `hint` içinde yazar.
  </Step>

  <Step title="Scope'un adını doğrulayın">
    Geçerli scope adlarını [Scope'lar](/api/kimlik-dogrulama/scopelar) sayfasından kontrol edin.
  </Step>

  <Step title="Uygulamanızın scope listesini kontrol edin">
    Scope uygulamanıza tanımlı değilse uygulamanın scope listesini güncelleyin. Bkz. [Uygulama oluşturma](/api/kimlik-dogrulama/uygulama-olusturma).
  </Step>

  <Step title="Yenileme isteğinde scope'u daraltın">
    `refresh_token` isteğine `scope` eklerseniz yalnızca ilk yetkilendirmedeki scope'ların alt kümesini isteyin. Yeni bir scope için kullanıcının yeniden yetkilendirmesi gerekir.
  </Step>
</Steps>

Uygulamanın scope listesini API ile güncellerken geçersiz bir scope gönderirseniz API `422 OAUTH_SCOPE_INVALID` döndürür. `data.invalid_scopes` alanı reddedilen scope'ları listeler.

## `invalid_client` ve `invalid_grant`

Bu iki hata sık karıştırılır. `invalid_client` istemci kimliğiyle ilgilidir. `invalid_grant` ise elinizdeki kod veya token ile ilgilidir.

### `invalid_client` (401)

Açıklama her zaman `Client authentication failed` metnidir. Olası nedenler:

* `client_id` bilinmiyor.
* Uygulamanın erişimi kaldırılmış (revoke edilmiş).
* `client_secret` yanlış. Secret yalnızca oluşturulurken bir kez gösterilir. Kaybettiyseniz yenisini üretin.
* Yetkilendirme isteğindeki `redirect_uri` kayıtlı adreslerle birebir aynı değil. Bu durumda sunucu yönlendirme yapmaz, JSON döner.
* Uygulamada birden fazla `redirect_uri` kayıtlı olduğu halde isteğe `redirect_uri` eklemediniz.

İstemci kimlik doğrulamasında HTTP Basic kullandıysanız yanıtta `WWW-Authenticate: Basic realm="OAuth"` başlığı gelir.

<Tip>
  Gizli istemcide `client_secret` hiç gönderilmezse hata `invalid_request` olur. `client_secret` gönderilip yanlışsa `invalid_client` olur.
</Tip>

### `invalid_grant` (400)

Hata `hint` değerine göre iki gruba ayrılır:

| `hint` | Anlamı | Çözüm |
| - | - | - |
| `Authorization code has expired` | Yetkilendirme kodunun süresi doldu. Kod 10 dakika geçerlidir. | Kullanıcıyı yeniden yetkilendirmeye yönlendirin. |
| `Authorization code has been revoked` | Kod daha önce kullanılmış. Kod tek kullanımlıktır. | Kodu yalnızca bir kez değiştirin, yeni kod alın. |
| `Failed to verify code_verifier.` | `code_verifier`, `code_challenge` ile eşleşmiyor. | Aynı yetkilendirme isteğinde ürettiğiniz verifier'ı gönderin. |
| `Token has expired` | Refresh token'ın süresi doldu. Refresh token 7 gün geçerlidir. | Kullanıcıyı yeniden yetkilendirin. |
| `Token has been revoked` | Refresh token daha önce kullanıldı veya iptal edildi. | Yeni yetkilendirme başlatın. |
| `Token is not linked to client` | Refresh token başka bir istemciye ait. | Token'ı verildiği istemciyle kullanın. |

<Warning>
  Her yenileme işlemi kullandığınız refresh token'ı iptal eder ve yeni bir çift döndürür. Yeni refresh token'ı hemen saklayın. Eskisini tekrar kullanırsanız `invalid_grant` alırsınız. Ayrıntılar için [Tokenlar](/api/kimlik-dogrulama/tokenlar) sayfasına bakın.
</Warning>

## 401 ve 403 farkı

Token'ınızla API'ye geldiğinizde karşılaşacağınız iki durum şunlardır.

| Durum | HTTP | `error_code` | Anlamı |
| - | - | - | - |
| Kimlik doğrulanamadı | 401 | `UNAUTHENTICATED` | API token'ı kabul etmedi. |
| Scope eksik | 403 | `FORBIDDEN` | Token geçerli, ama bu uç nokta için gereken scope'a sahip değil. |
| İzin eksik | 403 | `FORBIDDEN` | Token geçerli, scope var, ama kullanıcının bu klinikte gereken izni yok. |

**401 `UNAUTHENTICATED`** yanıtı `Kimlik doğrulaması gerekli.` mesajını taşır. Nedenleri:

* `Authorization` başlığı yok veya token bozuk.
* Access token'ın süresi doldu. Access token 5 dakika geçerlidir.
* Token iptal edildi veya uygulamanın erişimi kaldırıldı.
* Kullanıcı silinmiş.
* Token `client_credentials` ile alındı. Bu token'lar `/api/v1` için kullanılamaz.

Çözüm: refresh token ile yeni access token alın. Refresh de başarısızsa kullanıcıyı yeniden yetkilendirin.

**403 `FORBIDDEN`** iki farklı mesajla gelir. `error_code` aynı olduğu için ayırt edici olan `message` metnidir.

| `message` | Neden | Çözüm |
| - | - | - |
| `Invalid scope(s) provided.` | Token'da uç noktanın gerektirdiği scope yok. Bu mesaj Türkçeye çevrilmemiştir. | Scope'u uygulamanıza ekleyin ve kullanıcıdan yeniden yetkilendirmesini isteyin. Mevcut token'a scope eklenemez. |
| `Bu işlem için yetkiniz yok.` | Kullanıcının seçili klinikte bu işlem için izni yok. | Kullanıcının rolüne gerekli izni verdirin. Bkz. [İzinler ve görünürlük](/api/izinler-ve-gorunurluk). |

Bir isteğin etkin yetkisi üç şeyin kesişimidir: token'daki scope, kullanıcının o klinikteki izinleri ve kullanıcının klinik üyeliği. Scope tek başına yetmez.

<Info>
  Bazı 403 yanıtları `FORBIDDEN` yerine kendi kodunu taşır. Örnek: kullanıcıya atanmamış bir lead için `LEAD_NOT_ASSIGNED`, atanmamış bir sohbet için `CONVERSATION_NOT_ASSIGNED`. Bunlar scope veya rol sorunu değildir, kayıt görünürlüğü kuralıdır. Bkz. [İzinler ve görünürlük](/api/izinler-ve-gorunurluk).
</Info>

### Kontrol sırası

Klinik gerektiren bir uç noktada API denetimleri sırayla yapar. İlk başarısız denetimin hatası döner:

1. `401` token
2. `429` oran sınırı
3. `400` veya `404` `X-Tenant` başlığı
4. `402` abonelik ve ödeme kilidi
5. `428` kurulum kilidi
6. `403` scope (`Invalid scope(s) provided.`)
7. `403` izin (`Bu işlem için yetkiniz yok.`)
8. `404` veya `422` kaynak

Bu sıra size bir hata aldığınızda hangi denetimleri geçtiğinizi söyler. Örneğin `403` scope hatası alıyorsanız `X-Tenant` ve klinik kilitleri sorun değildir.

## Klinik başlığı hataları

Klinik gerektiren her uç noktada `X-Tenant: <tenant_id>` başlığı zorunludur. Değer kliniğin sayısal `id` değeridir, slug değildir. Bu denetim token (`401`) ve oran sınırı (`429`) denetiminden sonra yapılır.

| `error_code` | HTTP | Mesaj | Ne zaman |
| - | - | - | - |
| `TENANT_HEADER_REQUIRED` | 400 | `X-Tenant başlığı zorunludur.` | Başlık yok veya boş. |
| `TENANT_NOT_FOUND` | 404 | `Klinik bulunamadı.` | Değer sayı değil, klinik yok, silinmiş ya da kullanıcı o kliniğin üyesi değil. |

<Note>
  Üye olmadığınız bir klinik için `403` değil `404 TENANT_NOT_FOUND` alırsınız. API, başka kliniklerin var olup olmadığını açığa çıkarmaz. Yanlış `X-Tenant` değeri gönderdiğinizden şüpheleniyorsanız önce `GET /api/v1/account/tenants` ile kullanıcının kliniklerini listeleyin.
</Note>

`/oauth/*` uç noktaları (`/api/v1/oauth/clients` ve `/api/v1/oauth/scopes`) da `X-Tenant` ister. Başlık olmadan `400 TENANT_HEADER_REQUIRED` alırsınız. İzin, yalnızca başlıkta gönderdiğiniz klinikte kontrol edilir.

Klinik seçimini ve `X-Tenant` kurallarını [Klinikler ve X-Tenant](/api/klinikler-ve-x-tenant) sayfasında bulabilirsiniz.

### Abonelik ve kurulum kilitleri

Klinik başlığı doğru olsa bile kliniğin durumu isteği durdurabilir.

| `error_code` | HTTP | Mesaj |
| - | - | - |
| `SUBSCRIPTION_REQUIRED` | 402 | `Devam etmek için ücretli plan seçin veya aboneliğinizi yenileyin.` |
| `ACCESS_RESTRICTED_BY_OVERDUE_PAYMENT` | 402 | `Gecikmiş ödeme tamamlanana kadar erişim kısıtlanmıştır.` |
| `SETUP_REQUIRED` | 428 | `Devam etmek için gerekli kurulum adımlarını tamamlayın.` |

`ACCESS_RESTRICTED_BY_OVERDUE_PAYMENT` yanıtında `data.proforma_invoice_id` ve `data.due_date` bulunur. `SETUP_REQUIRED` yanıtında `data.next_step` bulunur. Bu kilitlerin ayrıntısı ve çözümü için [Erişim kilitleri](/api/istekler/erisim-kilitleri) sayfasına bakın.

## İlgili sayfalar

<CardGroup cols={2}>
  <Card title="Tokenlar" icon="key-round" href="/api/kimlik-dogrulama/tokenlar">
    Access ve refresh token ömürleri, yenileme.
  </Card>

  <Card title="Scope'lar" icon="list-checks" href="/api/kimlik-dogrulama/scopelar">
    Scope listesi ve uç nokta eşleşmeleri.
  </Card>

  <Card title="Klinikler ve X-Tenant" icon="building-2" href="/api/klinikler-ve-x-tenant">
    Klinik seçimi ve başlık kuralları.
  </Card>

  <Card title="Hata kodları" icon="triangle-alert" href="/api/istekler/hata-kodlari">
    API'nin tüm hata kodları.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.