Dokümanlar/API ve Webhook'lar/Hatalar ve Yanıtlar

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ı

DurumNe zaman görürsünüzNe yapmalı
200İstek başarılı oldu. Gövde kaynağı veya onay mesajını içerir.Gövdeyi işleyin.
400Hatalı 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.
401Eksik, hatalı biçimlendirilmiş, iptal edilmiş veya süresi dolmuş token.Authorization header'ını doğrulayın. İptal edildiyse token'ı döndürün.
403Token geçerli ancak gerekli kapsam yok.Kapsamı admin arayüzünden ekleyin; yanıt tam kapsam adını taşır.
404Kaynak 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.
429Bu API anahtarında hız limiti aşıldı.Retry-After'a uyun; bkz. Hız Limitleri.
5xxSunucu 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:

KodDurumAnlam
unauthorized401İstekte kullanılabilir bir bearer token yok.
insufficient_scope403Token iyi durumda, kapsam eksik. Yanıt required ve present içerir.
rate_limited429Üst sınır aşıldı. Retry-After header'ına bakın.
user_not_found404Kullanıcı ID'si yok veya kurumunuzda değil.
team_not_found404Ekip ID'si yok veya kurumunuzda değil.
assignment_not_found404Atama ID'si yok veya kurumunuzda değil.
empty_body400Gerekli olduğu halde gövdesiz POST veya PATCH gönderildi.
body_too_large400 / 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'}`);
}