LIVE · AUDIT-KÆDE · EU-HOSTET
SYSTEM · 99,99 % OPPETID
v 1.0 ↗ FREMSTILLET I EU

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

StatusKlassePrøv igen?Almindelige årsager
400ValideringNejManglende påkrævet felt, forkert format, brud på forretningsregel
401AuthNejManglende / forkert / tilbagekaldt legitimation
402FaktureringNejAbonnement forfaldent, grænse for gratis plan nået
403TilladelseNejLegitimationen mangler scope, eller ressourcen ligger i en anden organisation
404Ikke fundetNejRessourcen findes ikke eller er ikke synlig for din legitimation
409KonfliktNogle gangeGenbrug af Idempotency-Key stemmer ikke, brud på tilstandsmaskine
422UbehandleligNejSemantisk ugyldig kombination af gyldige felter
429Rate-begrænsetJa, med backoffThrottle pr. legitimation eller pr. organisation nået
500ServerfejlJa, med backoffUventet — opret en sag, hvis det er vedvarende
502 / 503 / 504ForbigåendeJa, med backoffUpstream / deploy / belastning

Bemærkelsesværdige fejlkoder

KodeStatusHvad det betyder
billing.subscription_past_due402Organisationens Stripe-abonnement er forfaldent. Henvis administratoren til /admin/billing.
billing.free_plan_minutes_exhausted402Gratis-/Pilot-niveauet har brugt sine 5 inspektioner.
billing.signature_pack_exhausted402Underskriftspakkens kreditter er brugt op; betal pr. underskrift eller køb en ny pakke.
permission_denied403Legitimationen mangler scope. Se field_errors.required_scope.
idempotency.key_mismatch409Samme nøgle, forskellig body. Brug en ny nøgle.
session.already_ended409Kald af end på en session, der ikke er åben (normalt sikkert — end er idempotent, dette er til grænsetilfældene).
kyb.not_verified403QES-underskrift anmodet på en organisation, der ikke har bestået KYB.
rate_limited429Throttle 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, hvor Remaining nulstilles.

Ved en 429 sættes Retry-After også (i sekunder) i henhold til RFC 6585.

Throttle-scopes

ScopeGrænseVindue
Pr. legitimation601 minut
Pr. organisation (på tværs af al legitimation)6001 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