Błędy + limity zapytań
Jedna koperta błędu dla każdego endpointu. Standardowe kody statusu HTTP + ustrukturyzowany ciąg code do programistycznego dopasowania. Nagłówki limitów zapytań w każdej odpowiedzi, aby dostosować tempo, zanim trafisz na 429.
Koperta błędu
{
"detail": "Human-readable summary.",
"code": "billing.subscription_past_due",
"field_errors": {
"scheduled_for": ["Must be a future ISO 8601 timestamp."]
}
} detail— zawsze obecny, bezpieczny do wyświetlenia użytkownikom (jest tłumaczony tam, gdzie dostępna jest dana lokalizacja).code— obecny dla rozróżnialnych stanów błędu. Stabilny między wersjami API; dopasowuj do niego logikę ponawiania.field_errors— obecny tylko przy błędach walidacji 400. Mapa nazwa-pola → lista komunikatów.
Macierz kodów statusu
| Status | Klasa | Ponowić? | Typowe przyczyny |
|---|---|---|---|
| 400 | Walidacja | Nie | Brak wymaganego pola, zły format, naruszenie reguły biznesowej |
| 401 | Auth | Nie | Brakujące / błędne / odwołane poświadczenie |
| 402 | Rozliczenia | Nie | Subskrypcja zaległa, osiągnięto limit planu bezpłatnego |
| 403 | Uprawnienia | Nie | Poświadczenie nie ma zakresu lub zasób należy do innej organizacji |
| 404 | Nie znaleziono | Nie | Zasób nie istnieje lub nie jest widoczny dla Twojego poświadczenia |
| 409 | Konflikt | Czasami | Niezgodność ponownego użycia Idempotency-Key, naruszenie maszyny stanów |
| 422 | Nieprzetwarzalne | Nie | Semantycznie nieprawidłowa kombinacja poprawnych pól |
| 429 | Limit zapytań | Tak, z backoffem | Osiągnięto throttle per poświadczenie lub per organizacja |
| 500 | Błąd serwera | Tak, z backoffem | Nieoczekiwany — otwórz zgłoszenie, jeśli się utrzymuje |
| 502 / 503 / 504 | Przejściowy | Tak, z backoffem | Upstream / wdrożenie / obciążenie |
Godne uwagi kody błędów
| Kod | Status | Co oznacza |
|---|---|---|
billing.subscription_past_due | 402 | Subskrypcja Stripe organizacji jest zaległa. Skieruj administratora do /admin/billing. |
billing.free_plan_minutes_exhausted | 402 | Warstwa Free / Pilot wykorzystała swoje 5 inspekcji. |
billing.signature_pack_exhausted | 402 | Kredyty pakietu podpisów wyczerpane; płać za podpis lub kup kolejny pakiet. |
permission_denied | 403 | Poświadczenie nie ma zakresu. Zobacz field_errors.required_scope. |
idempotency.key_mismatch | 409 | Ten sam klucz, inne ciało żądania. Użyj nowego klucza. |
session.already_ended | 409 | Wywołanie end na sesji, która nie jest otwarta (zwykle bezpieczne — end jest idempotentne, to dla przypadków brzegowych). |
kyb.not_verified | 403 | Zażądano podpisu QES w organizacji, która nie przeszła KYB. |
rate_limited | 429 | Osiągnięto throttle per poświadczenie (60 rpm) lub per organizacja (600 rpm). |
Nagłówki limitów zapytań
Każda odpowiedź — sukces lub błąd — niesie stan throttle:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 47
X-RateLimit-Reset: 1716461235 X-RateLimit-Limit— limit obowiązujący dla tego żądania.X-RateLimit-Remaining— ile wywołań pozostało w bieżącym oknie.X-RateLimit-Reset— znacznik czasu Unix, w którymRemainingsię resetuje.
Przy 429 ustawiany jest również Retry-After (w sekundach) zgodnie z RFC 6585.
Zakresy throttle
| Zakres | Limit | Okno |
|---|---|---|
| Per poświadczenie | 60 | 1 minuta |
| Per organizacja (dla wszystkich poświadczeń) | 600 | 1 minuta |
Możliwość bursta w pierwszej sekundzie minuty. Po osiągnięciu limitu kolejne żądania w oknie zwracają 429.
Strategia ponawiania
Wykładniczy backoff z jitterem dla 429 / 5xx; nie ponawiaj 4xx (poza 408, 425, 429):
async function withRetry<T>(fn: () => Promise<T>, max = 5): Promise<T> {
let lastErr: unknown;
for (let i = 0; i < max; i++) {
try {
return await fn();
} catch (err: any) {
const status = err?.status;
if (status >= 400 && status < 500 && ![408, 425, 429].includes(status)) {
throw err; // not retryable
}
const base = status === 429 ? (err.retryAfterMs ?? 1000) : 250 * 2 ** i;
const jitter = Math.random() * base * 0.2;
await new Promise((r) => setTimeout(r, base + jitter));
lastErr = err;
}
}
throw lastErr;
} SDK implementują to wewnętrznie przy 429 + 5xx; jeśli wolisz obsługiwać ponawianie samodzielnie, ustaw retries: 0 w opcjach SDK.
Korelacja błędów
Każda odpowiedź niesie nagłówek X-Request-Id (UUID). Podaj go w każdym zgłoszeniu do wsparcia — na jego podstawie możemy pobrać pełny ślad żądania.
Co dalej
- Uwierzytelnianie — rotacja poświadczeń, jeśli widzisz błędy 401
- Paginacja + idempotencja — wzorce, które wchodzą w interakcję z ponawianiem