Hatalar ve Yanıtlar
Her public API uç noktası öngörülebilir yanıt yapıları döner. Hatalar gövdede kararlı, makine tarafından okunabilir bir kod taşır; böylece İngilizce metni ayrıştırmadan bunun üzerinde dallanabilirsiniz.
Yanıt zarfı
Başarılı yanıtlar kaynağı (veya kaynak listesini) doğrudan döner. Üst seviye bir sarmalayıcı yoktur — client'lar doğrudan tipli bir modele deserialize edebilir:
GET /api/public/v1/org
{
"id": "e188fc87-…",
"name": "Acme Corp",
"plan": "growth",
…
}Başarısız yanıtlar, tek zorunlu alan olarak bir error kodu içeren küçük, tek tip bir yapı kullanır. İsteğe bağlı alanlar çağrıyı düzeltmenize yardımcı olacak bağlam sağlar:
{
"error": "insufficient_scope",
"required": "assignments:write",
"present": ["assignments:read", "users:read"]
}Durum kodu referansı
| Durum | Ne zaman görürsünüz | Ne yapmalı |
|---|---|---|
200 | İstek başarılı oldu. Gövde kaynağı veya onay mesajını içerir. | Gövdeyi işleyin. |
400 | Hatalı biçimlendirilmiş istek: eksik zorunlu alan, geçersiz enum değeri, çok büyük gövde, ayrıştırılamayan JSON. | Client isteğini düzeltin — aynı payload ile yeniden denemeyin. |
401 | Eksik, hatalı biçimlendirilmiş, iptal edilmiş veya süresi dolmuş token. | Authorization header'ını doğrulayın. İptal edildiyse token'ı döndürün. |
403 | Token geçerli ancak gerekli kapsam yok. | Kapsamı admin arayüzünden ekleyin; yanıt tam kapsam adını taşır. |
404 | Kaynak yok veya farklı bir kuruma ait. | Üst koleksiyonu yeniden çekin. Kurumlar arasında bayatlamış ID'leri takip etmeyin. |
409 | Çakışma — örn. bir e-posta zaten kullanılıyor. | İşleminiz idempotent ise başarı olarak kabul edin. |
413 | İstek gövdesi uç nokta üst sınırını aşıyor. Kestrel sert taşma için bunu döner; SARIF uç noktası ise bildirilen Content-Length 10 MB'ı aştığında 400 body_too_large olarak bunu döner. | Payload'ı küçültün. SARIF için tek bir tool'un bulgularını parça parça içeri alın. |
429 | Bu API anahtarında hız limiti aşıldı. | Retry-After'a uyun; bkz. Hız Limitleri. |
5xx | Sunucu tarafında sorun. | Üstel geri çekilme ile yeniden deneyin. X-Request-Id yanıt header'ını yakalayın ve herhangi bir destek ticket'ında alıntılayın. |
Hata kodları
error alanı sürümler arasında kararlıdır — aynı durum kodu farklı kodlar taşıyabileceğinden client kodunda HTTP durum yerine bunun üzerinde dallanın:
| Kod | Durum | Anlam |
|---|---|---|
unauthorized | 401 | İstekte kullanılabilir bir bearer token yok. |
insufficient_scope | 403 | Token iyi durumda, kapsam eksik. Yanıt required ve present içerir. |
rate_limited | 429 | Üst sınır aşıldı. Retry-After header'ına bakın. |
user_not_found | 404 | Kullanıcı ID'si yok veya kurumunuzda değil. |
team_not_found | 404 | Ekip ID'si yok veya kurumunuzda değil. |
assignment_not_found | 404 | Atama ID'si yok veya kurumunuzda değil. |
empty_body | 400 | Gerekli olduğu halde gövdesiz POST veya PATCH gönderildi. |
body_too_large | 400 / 413 | İstek gövdesi uç nokta üst sınırını aştı. SARIF bunu, bildirilen Content-Length çok büyük olduğunda gövdede maxBytes ile 400 olarak yayar; Kestrel ise gövde gerçekten taştığında çıplak bir 413 yayar. |
Request ID'ler
Her yanıt bir X-Request-Id header'ı (UUID v4) taşır. Client tarafında yakalayın ve destek taleplerine ekleyin — başarısız çağrı için tam sunucu tarafı izini çekmemize olanak verir. 5xx yanıtlarda request ID, tanıya giden en hızlı yoldur.
Doğrulama hataları
POST ve PATCH gövdelerindeki doğrulama başarısızlıkları, ilk başarısız kuralı tanımlayan düz bir error ile 400 döner. Çoklu alan doğrulama gösterimi v1 kapsamında değildir — ilk bildirilen alanı düzeltin ve yeniden deneyin. Gelecek sürümler alan başına detay ekleyebilir; üst seviye error sözleşmesi kalıcı olacaktır.
Hatalar üzerinde dallanma — örnek
const res = await fetch(url, { headers });
if (res.ok) return res.json();
const body = await res.json().catch(() => ({}));
switch (body.error) {
case 'rate_limited':
return retryWithBackoff(url);
case 'insufficient_scope':
throw new Error(`API key missing scope: ${body.required}`);
case 'unauthorized':
throw new Error('API key revoked or invalid — rotate the secret');
default:
throw new Error(`API error ${res.status}: ${body.error || 'unknown'}`);
}