Fejl + rate limits
Én fejlkonvolut på tværs af hvert endpoint. Standard HTTP-statuskoder + en struktureret code-streng til programmatisk matchning. Rate-limit-headers på hvert svar, så du kan afmåle tempoet, før du rammer en 429.
Fejlkonvolut
{
"detail": "Human-readable summary.",
"code": "billing.subscription_past_due",
"field_errors": {
"scheduled_for": ["Must be a future ISO 8601 timestamp."]
}
} detail— altid til stede, sikker at vise for mennesker (den er oversat, hvor sproget er tilgængeligt).code— til stede for skelnelige fejltilstande. Stabil på tværs af API-versioner; match på denne til retry-logik.field_errors— kun til stede ved 400-valideringsfejl. Map fra feltnavn → liste af beskeder.
Matrix over statuskoder
| Status | Klasse | Prøv igen? | Almindelige årsager |
|---|---|---|---|
| 400 | Validering | Nej | Manglende påkrævet felt, forkert format, brud på forretningsregel |
| 401 | Auth | Nej | Manglende / forkert / tilbagekaldt legitimation |
| 402 | Fakturering | Nej | Abonnement forfaldent, grænse for gratis plan nået |
| 403 | Tilladelse | Nej | Legitimationen mangler scope, eller ressourcen ligger i en anden organisation |
| 404 | Ikke fundet | Nej | Ressourcen findes ikke eller er ikke synlig for din legitimation |
| 409 | Konflikt | Nogle gange | Genbrug af Idempotency-Key stemmer ikke, brud på tilstandsmaskine |
| 422 | Ubehandlelig | Nej | Semantisk ugyldig kombination af gyldige felter |
| 429 | Rate-begrænset | Ja, med backoff | Throttle pr. legitimation eller pr. organisation nået |
| 500 | Serverfejl | Ja, med backoff | Uventet — opret en sag, hvis det er vedvarende |
| 502 / 503 / 504 | Forbigående | Ja, med backoff | Upstream / deploy / belastning |
Bemærkelsesværdige fejlkoder
| Kode | Status | Hvad det betyder |
|---|---|---|
billing.subscription_past_due | 402 | Organisationens Stripe-abonnement er forfaldent. Henvis administratoren til /admin/billing. |
billing.free_plan_minutes_exhausted | 402 | Gratis-/Pilot-niveauet har brugt sine 5 inspektioner. |
billing.signature_pack_exhausted | 402 | Underskriftspakkens kreditter er brugt op; betal pr. underskrift eller køb en ny pakke. |
permission_denied | 403 | Legitimationen mangler scope. Se field_errors.required_scope. |
idempotency.key_mismatch | 409 | Samme nøgle, forskellig body. Brug en ny nøgle. |
session.already_ended | 409 | Kald af end på en session, der ikke er åben (normalt sikkert — end er idempotent, dette er til grænsetilfældene). |
kyb.not_verified | 403 | QES-underskrift anmodet på en organisation, der ikke har bestået KYB. |
rate_limited | 429 | Throttle pr. legitimation (60 rpm) eller pr. organisation (600 rpm) nået. |
Rate-limit-headers
Hvert svar — succes eller fejl — bærer throttle-tilstanden:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 47
X-RateLimit-Reset: 1716461235 X-RateLimit-Limit— den grænse, der gælder for denne request.X-RateLimit-Remaining— hvor mange kald der er tilbage i det aktuelle vindue.X-RateLimit-Reset— Unix-tidsstempel, hvorRemainingnulstilles.
Ved en 429 sættes Retry-After også (i sekunder) i henhold til RFC 6585.
Throttle-scopes
| Scope | Grænse | Vindue |
|---|---|---|
| Pr. legitimation | 60 | 1 minut |
| Pr. organisation (på tværs af al legitimation) | 600 | 1 minut |
Kan bursts i det første sekund af et minut. Rammer du grænsen, får yderligere requests inden for vinduet 429.
Retry-strategi
Eksponentiel backoff med jitter for 429 / 5xx; genforsøg ikke 4xx (bortset fra 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'erne implementerer dette internt ved 429 + 5xx; vil du hellere håndtere genforsøg selv, så sæt retries: 0 i SDK-optionerne.
Fejlkorrelation
Hvert svar bærer en X-Request-Id-header (UUID). Angiv den i enhver support-sag — vi kan hente hele request-tracet ud fra det id alene.
Hvad er det næste
- Autentificering — rotation af legitimation, hvis du ser 401'ere
- Paginering + idempotens — mønstrene, der spiller sammen med genforsøg