ReferenzFehler

Fehler

Jeder Fehlercode der Certivant-API erklärt — Aufbau der Antwort, Zuordnung zu HTTP-Statuscodes, Hinweise zur Behandlung je Code und ein robuster Wiederholungs-Wrapper, den Sie in Ihre Integration übernehmen können.

Jede Fehlerantwort der Certivant-API folgt demselben Aufbau. Erstellen Sie einen einzigen Fehlerbehandler, der diesen Aufbau verarbeitet, und Sie können jeden Endpunkt einheitlich behandeln.

Aufbau der Antwort

{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Body validation failed.",
    "fields": {
      "applicant.dateOfBirth": "Invalid date format. Expected YYYY-MM-DD.",
      "applicant.nationality": "Must be a 2-character ISO 3166-1 alpha-2 code."
    }
  }
}
FeldTypHinweise
successbooleanBei Fehlern immer false
error.codestringMaschinenlesbar. Verzweigen Sie den Programmablauf anhand dieses Feldes
error.messagestringFür Menschen lesbar. Sicher zu protokollieren; nicht sicher, direkt Antragstellern angezeigt zu werden
error.fieldsobjectNur bei VALIDATION_ERROR vorhanden. Ordnet Feldpfade in Punktnotation den Fehlermeldungen je Feld zu

Die Zeichenketten message der Fehler sind über Versionen hinweg nicht garantiert stabil. Verwenden Sie code für jede Logik; behandeln Sie message als Hilfe für Protokollierung und Entwickler.

HTTP-Statuscode → Fehlercode

HTTPTypischer error.codeBedeutung
400VALIDATION_ERRORDer Anfrage-Body hat die Zod-Validierung nicht bestanden. Prüfen Sie fields
400BAD_REQUESTAllgemeine fehlerhafte Anfrage (z. B. Einreichung, bevor alle Dokumente hochgeladen wurden)
401UNAUTHORIZEDAPI-Schlüssel fehlt, ist fehlerhaft, widerrufen oder abgelaufen
402verification_unavailableDie Organisation hat kein Guthaben mehr und ist nicht so eingestellt, dass sie ohne Guthaben weitermacht
403FORBIDDENDer Schlüssel ist gültig, hat aber nicht den erforderlichen Berechtigungsbereich, kommt von einer Adresse außerhalb seiner IP-Allowlist, ist auf andere Formulare beschränkt oder die Ressource gehört zu einer anderen Organisation
404NOT_FOUNDDie Ressource (req_…, doc_… usw.) existiert nicht oder ist für die Organisation dieses Schlüssels nicht sichtbar
409CONFLICTZustandswechsel nicht erlaubt (z. B. zweimaliges Einreichen einer Anfrage) oder Verletzung einer Eindeutigkeitsbedingung (externalRef bereits in Verwendung)
413BAD_REQUESTDatei-Upload größer als 10 MB
415BAD_REQUESTContent-Type für den Endpunkt nicht unterstützt (z. B. JSON-Body an einen Multipart-Endpunkt)
429RATE_LIMITEDDas Ratenlimit pro Minute wurde überschritten. Siehe Ratenlimits
500INTERNAL_ERRORUnerwarteter Serverfehler. Wird auf unserer Seite immer protokolliert; eine Wiederholung ist unbedenklich
502BAD_GATEWAYEin vorgelagerter Dienst (Sanktionsanbieter, Zahlungsgateway, Register) ist nicht erreichbar. Nach einer Verzögerung erneut versuchen
503SERVICE_UNAVAILABLEDatenbank eingeschränkt verfügbar. Mit Backoff erneut versuchen

Katalog der Fehlercodes

UNAUTHORIZED

Der API-Schlüssel im Header Authorization fehlt, ist fehlerhaft oder wurde widerrufen.

{ "success": false, "error": { "code": "UNAUTHORIZED", "message": "Invalid or revoked API key." } }

error.reason zeigt Ihnen, welcher Fall vorliegt: missing_api_key, invalid_api_key, api_key_revoked, api_key_expired oder api_key_rotated (der Schlüssel wurde rotiert und sein Überlappungszeitraum ist beendet). Die vollständige Liste finden Sie unter Authentifizierung.

So gehen Sie vor: Prüfen Sie, dass der Header Authorization: Bearer ck_live_… lautet (oder ck_test_…; ältere Schlüssel beginnen mit kyk_). Prüfen Sie den Status des Schlüssels im Dashboard. Wird er als widerrufen oder abgelaufen angezeigt, erstellen Sie einen neuen Schlüssel oder rotieren den bestehenden.

FORBIDDEN

Der Schlüssel ist gültig, hat aber nicht den erforderlichen Berechtigungsbereich, oder die Ressource gehört zu einer anderen Organisation als der des Schlüssels.

{ "success": false, "error": { "code": "FORBIDDEN", "message": "This API key does not include the kyc:manage scope required for this endpoint." } }

error.reason ist insufficient_scope (dem Schlüssel fehlt ein Berechtigungsbereich), ip_not_allowed (die Adresse des Aufrufers steht nicht auf der IP-Allowlist des Schlüssels) oder form_not_allowed (der Schlüssel ist auf andere Formulare beschränkt).

So gehen Sie vor: Prüfen Sie die Berechtigungsbereiche und Beschränkungen Ihres Schlüssels im Dashboard (KYC → Entwickler, das Stiftsymbol). Sie können die Berechtigungen eines Schlüssels, die Formular- und Workflow-Beschränkungen, die IP-Allowlist und das Ablaufdatum bearbeiten, ohne das Geheimnis zu ändern; das Geheimnis und die Umgebung (Live oder Test) lassen sich nicht ändern.

verification_unavailable (HTTP 402)

Ihre Organisation hat kein Guthaben mehr und ist nicht so eingestellt, dass sie ohne Guthaben weitermacht. Daher kann Certivant keine neue Verifizierung annehmen. Die Antwort verwendet den Code verification_unavailable:

{ "success": false, "error": { "code": "verification_unavailable", "message": "This organization is temporarily unable to accept new verifications. Please contact them to continue." } }

So gehen Sie vor: Laden Sie das Guthaben unter Einstellungen → Guthaben & Nutzung auf (Inhaber und Administratoren erhalten außerdem eine Benachrichtigung und eine E-Mail, höchstens einmal täglich). Antragsteller, die in einem Formular oder einer gehosteten Seite auf dieselbe Situation stoßen, sehen eine Seite, die sie auffordert, sich mit Ihrer Organisation in Verbindung zu setzen; die Seite erwähnt niemals Guthaben oder Geld. Siehe Abrechnung & Guthaben.

NOT_FOUND

{ "success": false, "error": { "code": "NOT_FOUND", "message": "Request not found." } }

So gehen Sie vor: Prüfen Sie die Ressourcen-ID. Eine häufige Ursache ist eine ID aus einer anderen Umgebung — Staging-IDs existieren nicht in der Produktion und umgekehrt.

VALIDATION_ERROR

Der Anfrage-Body hat die Schemavalidierung nicht bestanden. Die Zuordnung fields listet jedes fehlerhafte Feld mit einer Meldung je Feld.

{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Body validation failed.",
    "fields": {
      "type": "Required",
      "applicant.email": "Invalid email format"
    }
  }
}

So gehen Sie vor: Zeigen Sie fields neben Ihren Formulareingaben an. Feldpfade verwenden Punktnotation für verschachtelte Felder und [N] für Array-Indizes (directors[0].dateOfBirth).

BAD_REQUEST

Allgemein fehlerhafte Anfrage, die in keine der anderen Kategorien passt.

{ "success": false, "error": { "code": "BAD_REQUEST", "message": "Cannot submit a request with pending documents. Upload the remaining documents first." } }

So gehen Sie vor: Lesen Sie die message. Dies deutet meist auf ein Reihenfolgeproblem hin — rufen Sie zuerst den Vorbedingungs-Endpunkt auf.

CONFLICT

Ein Zustandswechsel, der aus dem aktuellen Zustand nicht erlaubt ist, oder eine Verletzung einer Eindeutigkeitsbedingung.

{ "success": false, "error": { "code": "CONFLICT", "message": "externalRef already in use by request req_…" } }

So gehen Sie vor: Prüfen Sie den aktuellen Zustand der Anfrage über GET /requests/:id und passen Sie Ihr Vorgehen an. Bei Verletzungen der Eindeutigkeit einer Referenz laden Sie entweder die bestehende Anfrage (über ?externalRef=… am Listen-Endpunkt) oder wählen Sie eine andere Referenz.

RATE_LIMITED

{ "success": false, "error": { "code": "RATE_LIMITED", "message": "Rate limit exceeded. Max 120 requests per 60s. Retry in 14s." } }

Die Header dieser Antwort umfassen X-RateLimit-Limit, X-RateLimit-Remaining und X-RateLimit-Reset (Sekunden bis zur Auffüllung des Kontingents). Zur Wiederholungsstrategie siehe Ratenlimits.

INTERNAL_ERROR

Auf unserer Seite ist etwas fehlgeschlagen. Certivant protokolliert jeden 500er mit vollständigem Kontext.

{ "success": false, "error": { "code": "INTERNAL_ERROR", "message": "An unexpected error occurred. Please try again." } }

So gehen Sie vor: Versuchen Sie es nach kurzer Verzögerung einmal erneut. Bleibt der Fehler bestehen, prüfen Sie die Statusseite und kontaktieren Sie den Support unter Angabe der Anfrage-ID.

BAD_GATEWAY und SERVICE_UNAVAILABLE

Eine vorgelagerte Abhängigkeit ist nicht erreichbar (Handelsregister-API, Anbieter für Sanktionsdaten, Speicher) oder die Datenbank ist eingeschränkt verfügbar.

{ "success": false, "error": { "code": "BAD_GATEWAY", "message": "Sanctions screening provider is unreachable. The request remains in PENDING state — Certivant will retry automatically." } }

So gehen Sie vor: Behandeln Sie diese Fehler als vorübergehend. Implementieren Sie exponentiellen Backoff (1 s, 2 s, 4 s, 8 s, 16 s) und brechen Sie nach etwa 5 Versuchen ab. Die Anfrage geht nicht verloren — die eigene Warteschlange von Certivant nimmt die Verarbeitung wieder auf, sobald der vorgelagerte Dienst sich erholt.

Ein robuster Fehlerbehandler

async function callCertivant<T>(
  fn: () => Promise<Response>,
  options: { maxRetries?: number } = {},
): Promise<T> {
  const maxRetries = options.maxRetries ?? 3;
  let attempt = 0;
  let delay = 500;

  while (true) {
    const res = await fn();

    if (res.ok) return (await res.json()) as T;

    const body = (await res.json().catch(() => null)) as
      | { error?: { code: string; message: string } }
      | null;
    const code = body?.error?.code ?? "INTERNAL_ERROR";

    // Retry on transient errors
    if (
      attempt < maxRetries &&
      (res.status === 429 || res.status >= 500)
    ) {
      const retryAfter =
        res.status === 429
          ? Number(res.headers.get("X-RateLimit-Reset") ?? 60) * 1000
          : delay;
      await sleep(retryAfter);
      delay *= 2;
      attempt += 1;
      continue;
    }

    // Bubble everything else up
    throw new CertivantError(code, body?.error?.message ?? "Unknown error", res.status);
  }
}

Dieses Muster behandelt jeden oben dokumentierten Fehler:

  • Antworten der Klasse 200 → parsen und zurückgeben.
  • 429 → auf X-RateLimit-Reset warten und erneut versuchen.
  • 5xx → exponentieller Backoff und erneuter Versuch.
  • 4xx → sofort einen Fehler werfen (Ihr Code ist fehlerhaft; eine Wiederholung behebt das nicht).