Fehler kommen immer im selben Format: ein maschinenlesbarer Code in error, eine lesbare Meldung in message und bei Bedarf Details.
HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8
{
"error": "validation_error",
"message": "Ungültige Eingabe.",
"details": [
{ "path": "lines.0.quantity", "message": "Too small: expected number to be >0" }
]
}
- Werten Sie
error aus, nicht message – der Code ist Teil der stabilen API, der Text kann sich ändern. message ist je nach Request-Header Accept-Language (de oder en) deutsch oder englisch. Ohne unterstützte Sprache antwortet die API v1 auf Englisch – für deutsche Meldungen Accept-Language: de senden.- Bei
validation_error enthält details eine Liste mit path (Punkt-Notation) und message je Feld. - Wiederholen lohnt sich bei
429, 409 idempotency_in_progress und 5xx – mit Pause und demselben Idempotency-Key. Andere 4xx-Fehler ändern sich durch Wiederholen nicht.
HTTP-Status
| Status | Bedeutung |
|---|
| 400 | Anfrage ungültig |
| 401 | nicht angemeldet bzw. Schlüssel/Token ungültig |
| 402 | Kontingent erschöpft oder Leistung nicht im Abo (z. B. Briefe) |
| 403 | keine Berechtigung |
| 404 | nicht gefunden |
| 409 | Zustand erlaubt die Aktion nicht (Konflikt) |
| 410 | Ressource nicht mehr vorhanden (z. B. Importdatei) |
| 413 / 415 | Datei zu groß bzw. Dateityp nicht erlaubt |
| 422 | fachlich nicht verarbeitbar (z. B. Pflichtangaben fehlen) |
| 429 | zu viele Anfragen |
| 500 | Fehler bei DebtFlow |
| 501 | nicht verfügbar |
| 502 | externer Dienst (E-Mail, Stripe, Briefversand) hat einen Fehler gemeldet |
| 503 | vorübergehend nicht verfügbar |
Allgemeine Fehlercodes
| Status | error | Bedeutung |
|---|
| 400 | validation_error | Pfad-, Query- oder Body-Parameter ungültig; details nennt die Felder |
| 401 | unauthorized | kein oder kein lesbarer Bearer-Token |
| 401 | invalid_api_key | API-Schlüssel unbekannt, widerrufen oder abgelaufen |
| 401 | invalid_token | OAuth-Access-Token unbekannt, abgelaufen oder Verbindung getrennt |
| 403 | forbidden | Aktion für dieses Konto nicht erlaubt |
| 403 | insufficient_scope | Schlüssel bzw. App hat die nötige Berechtigung nicht; details.missing |
| 403 | session_required | nur im Dashboard möglich (Kontoverwaltung) |
| 403 | account_not_approved | Konto ist noch nicht freigeschaltet |
| 403 | account_disabled | Konto ist gesperrt |
| 403 | mfa_required | Dashboard-Sitzung ohne abgeschlossenen zweiten Faktor |
| 403 | demo_unavailable | im öffentlichen Demo-Konto gesperrt (Versand, Kosten, KI, Uploads, Zugangsdaten) |
| 403 | plan_limit_reached | Grenze des Abos erreicht (z. B. Anzahl Kontakte) |
| 404 | not_found | Ressource existiert nicht oder gehört zu einem anderen Konto |
| 409 | conflict | Zustand erlaubt die Aktion nicht |
| 409 | idempotency_in_progress | Anfrage mit gleichem Idempotency-Key läuft noch |
| 409, 422 | idempotency_conflict | Idempotency-Key wurde für eine andere Anfrage verwendet |
| 409 | limit_reached | Höchstzahl erreicht (z. B. Webhook-Endpunkte, API-Schlüssel) |
| 413 | payload_too_large | Datei oder Anfrage zu groß |
| 415 | unsupported_media_type | Dateityp nicht erlaubt |
| 429 | rate_limited | zu viele Anfragen; Header Retry-After beachten |
| 500 | internal_error | Fehler bei DebtFlow; später erneut versuchen |
| 501 | not_implemented | Funktion ist (noch) nicht verfügbar |
| 503 | not_ready | Dienst startet bzw. ist vorübergehend nicht bereit; später erneut versuchen |
Fachliche Fehlercodes
Die Liste wird mit dem Quellcode abgeglichen (automatischer Test). Reagieren Sie im Zweifel auf den HTTP-Status: neue, spezifischere Codes können hinzukommen, ohne dass sich der Status ändert.
Rechnungen, Gutschriften, Angebote
| Status | error | Bedeutung |
|---|
| 409 | document_locked | Beleg ist festgeschrieben und unveränderbar (GoBD); Korrektur per Storno oder Gutschrift |
| 409 | number_conflict | Belegnummer bereits vergeben – Nummernmuster des Nummernkreises prüfen |
| 409 | number_range_in_use | im Zeitraum wurden schon Nummern vergeben; Startnummer nicht mehr änderbar |
| 409 | invoice_not_finalized | Aktion nur für festgeschriebene Rechnungen |
| 409 | offer_not_finalized | Aktion nur für festgeschriebene Angebote |
| 409 | has_credit_notes | Storno nicht möglich, es gibt Gutschriften – Rest per Gutschrift korrigieren |
| 409 | already_deducted | Abschlagsrechnung ist bereits in einer Schlussrechnung abgezogen |
| 409 | already_handed_over | Rechnung wurde bereits ans Mahnwesen übergeben |
| 409 | already_paid | bereits vollständig bezahlt |
| 409 | not_payable | Beleg kann nicht (mehr) bezahlt werden |
| 409 | einvoice_not_available | für diesen Beleg gibt es keine E-Rechnung |
| 422 | invoice_incomplete | Pflichtangaben (§ 14 UStG) fehlen; details listet sie |
| 422 | overpayment | Zahlung übersteigt den offenen Betrag |
| 422 | einvoice_invalid | E-Rechnung verletzt Regeln (XRechnung/ZUGFeRD); details nennt sie |
| 422 | einvoice_unreadable | Datei ist keine lesbare E-Rechnung |
| 422 | einvoice_not_found | PDF enthält keine eingebettete E-Rechnung (ZUGFeRD/Factur-X) |
| 500 | pdf_fonts_missing | PDF konnte nicht erzeugt werden (Schriften fehlen auf dem Server) |
| 502 | email_failed | E-Mail-Versand fehlgeschlagen |
Forderungen, Zahlungen, Briefe
| Status | error | Bedeutung |
|---|
| 402 | quota_exceeded | Kontingent (z. B. Briefe im Monat) ausgeschöpft |
| 402 | letters_not_available | Briefversand im Abo nicht enthalten bzw. nicht eingerichtet |
| 409 | target_not_open | Posten ist nicht (mehr) offen |
| 409 | amount_exceeds_open | Betrag übersteigt den offenen Betrag |
| 409 | payment_processing | Zahlung wird gerade verarbeitet |
| 409 | payment_unavailable | Online-Zahlung für diesen Posten nicht möglich |
| 502 | provider_failed | externer Dienst (z. B. Briefdienstleister) hat einen Fehler gemeldet |
| 400 | invalid_token | Briefdiener-Token abgelehnt (nur /integrations/briefdiener) |
| 503 | unreachable | Briefdiener ist vorübergehend nicht erreichbar |
Recherche und Gläubiger-KI
| Status | error | Bedeutung |
|---|
| 409 | inquiry_in_progress | für den Kontakt läuft bereits eine Melderegisteranfrage (keine Doppelkosten) |
| 422 | missing_contact_data | Geburtsdatum oder bekannte Anschrift des Kontakts fehlt |
| 429 | ai_rate_limited | zu viele KI-Anfragen in kurzer Zeit; details.retryAfter beachten |
| 429 | ai_quota_exhausted | tägliches KI-Kontingent erschöpft |
| 502 | ai_failed | KI-Dienst hat keinen verwertbaren Text geliefert; später erneut versuchen |
| 503 | ai_unavailable | Gläubiger-KI ist nicht eingerichtet |
Bank
| Status | error | Bedeutung |
|---|
| 400 | invalid_iban | IBAN ungültig |
| 409 | duplicate_iban | Bankkonto mit dieser IBAN existiert bereits |
| 409 | iban_mismatch | Import gehört zu einem anderen Konto |
| 409 | account_archived | Bankkonto ist archiviert |
| 409 | account_has_transactions | Bankkonto hat Umsätze und kann nicht gelöscht werden |
| 409 | already_matched | Umsatz ist bereits zugeordnet |
| 409 | not_matched | Umsatz ist keinem Posten zugeordnet |
| 409 | transaction_matched | zugeordneter Umsatz kann nicht geändert werden |
| 409 | transaction_ignored | Umsatz ist als ignoriert markiert |
| 409 | direction_mismatch | Eingänge nur offenen Posten, Ausgaben nur Belegen zuordnen |
| 409 | amount_exceeds_transaction | Zuordnungen übersteigen den Umsatzbetrag |
| 409 | possible_duplicate | Import enthält vermutlich bereits importierte Umsätze |
| 409 | import_completed | Import ist bereits abgeschlossen |
| 409 | import_has_matches | Import enthält zugeordnete Umsätze und kann nicht zurückgenommen werden |
| 409 | already_reverted | Import wurde bereits zurückgenommen |
| 410 | import_file_missing | Importdatei ist nicht mehr vorhanden – erneut hochladen |
| 422 | mapping_required | Spaltenzuordnung der CSV-Datei fehlt |
| 422 | unprocessable_file | Datei konnte nicht verarbeitet werden |
Belege und Importe
| Status | error | Bedeutung |
|---|
| 409 | already_assigned | Beleg ist bereits zugeordnet |
| 409 | in_use | Eintrag wird noch verwendet |
| 422 | file_missing | Datei fehlt |
| 422 | ocr_unreadable | Texterkennung konnte die Datei nicht lesen |
| 422 | ocr_unsupported | Dateityp wird von der Texterkennung nicht unterstützt |
| 422 | ocr_file_too_large | Datei ist für die Texterkennung zu groß |
| 400 | invalid_payload | eingehende Daten (z. B. E-Mail-Eingang) ungültig |
| 400 | invalid_signature | Signatur eines eingehenden Aufrufs ungültig |
Buchhaltung
| Status | error | Bedeutung |
|---|
| 409 | period_closed | Zeitraum ist abgeschlossen (festgeschrieben) |
| 409 | invalid_period | Zeitraum ungültig oder überschneidet sich |
| 409 | open_issues | offene Punkte verhindern den Abschluss; details listet sie |
| 409 | closing_in_progress | Abschluss läuft bereits |
| 409 | chart_locked | Kontenrahmen kann nach ersten Buchungen nicht mehr gewechselt werden |
| 409 | generated_entry | automatisch erzeugte Buchung – Quelle ändern statt Buchung |
| 409 | datev_numbers_missing | Berater-/Mandantennummer für den DATEV-Export fehlen |
Projekte und Zeiten
| Status | error | Bedeutung |
|---|
| 409 | project_has_entries | Projekt hat Zeiteinträge |
| 409 | task_has_entries | Aufgabe hat Zeiteinträge |
| 409 | time_entry_invoiced | Zeiteintrag ist bereits abgerechnet |
| 409 | time_entries_not_billable | ausgewählte Zeiten sind nicht abrechenbar |
| 409 | timer_not_running | es läuft keine Zeiterfassung |
| 409 | invoice_active | Zeiten gehören zu einer nicht stornierten Rechnung und können nicht freigegeben werden |
| 422 | nothing_to_invoice | keine abrechenbaren Zeiten im Zeitraum |
Stripe Connect und Online-Zahlungen
| Status | error | Bedeutung |
|---|
| 400 | stripe_oauth_failed | Verbindung mit Stripe fehlgeschlagen |
| 400 | invalid_state | Rückruf passt nicht zur gestarteten Verbindung |
| 409 | stripe_not_connected | kein Stripe-Konto verbunden |
| 409 | stripe_account_in_use | Stripe-Konto ist mit einem anderen DebtFlow-Konto verbunden |
| 409 | already_connected | bereits verbunden |
| 409 | not_connected | nicht verbunden |
| 409 | managed_in_stripe | Einstellung wird in Stripe verwaltet |
| 502 | stripe_checkout_failed | Stripe hat die Zahlungsseite nicht erzeugt |
| 503 | online_payments_unavailable | Online-Zahlungen sind nicht konfiguriert |
Sicherheit (Dashboard)
| Status | error | Bedeutung |
|---|
| 400 | challenge_expired | Passkey-Anfrage abgelaufen – erneut starten |
| 400 | passkey_invalid | Passkey-Antwort ungültig |
| 400 | invalid_second_factor | Code oder Passkey falsch |
| 400 | setup_expired | Einrichtung abgelaufen – erneut starten |
| 409 | passkey_exists | Passkey ist bereits registriert |
| 409 | no_factor | kein zweiter Faktor eingerichtet |
| 409 | no_passkey | kein Passkey eingerichtet |
| 409 | last_factor | der letzte zweite Faktor kann nicht entfernt werden |
| 403 | reauthentication_required | für die Einrichtung bitte erneut anmelden |
| 429 | mfa_locked | zu viele Fehlversuche – vorübergehend gesperrt |
Der OAuth-Token-Endpunkt antwortet abweichend im OAuth-Format mit error_description, siehe Authentifizierung.