Zum Inhalt springen
Dokumentation
Deutsch
App öffnen

Fehler und Limits

Fehlerformat der NovaFisko-API, HTTP-Codes, Maschinencodes, Rate-Limits pro Route und das richtige Verhalten nach einem 429.

Die API verwendet die Standard-HTTP-Codes und liefert im Fehlerfall immer einen JSON-Body.

Format eines Fehlers

{
  "message": "Le plafond de 5 dossiers de votre licence est atteint.",
  "code": "company_limit_reached",
  "errors": {
    "name": ["Le plafond de 5 dossiers de votre licence est atteint."]
  }
}
Feld Vorhanden Beschreibung
message immer Lesbarer Text, in die Sprache des Benutzers übersetzt
code bei fachlichen Fehlern Stabile Kennung auf Englisch, zur Verwendung in Ihrem Code
errors bei Validierungsfehlern Objekt Feld → Liste von Meldungen. Verschachtelte Felder verwenden die Punktnotation: lines.0.account_id

Einige Fehler fügen eigene Felder hinzu, zum Beispiel required_ability, server_version und server_data oder blocker_codes für Peppol.

Tipp

Werten Sie zuerst den HTTP-Status aus, dann code, sofern vorhanden. Analysieren Sie niemals den Text von message.

HTTP-Codes

Status Bedeutung Vorgehen
200 Erfolg
201 Ressource erstellt
202 Anfrage angenommen, sofortige oder verzögerte Verarbeitung (Webhook-Test)
204 Erfolg ohne Body (Löschung, Abmeldung)
401 Token fehlt, ist ungültig, widerrufen oder abgelaufen Neu anmelden oder das Token wechseln
403 Aktion für dieses Token oder diese Rolle nicht erlaubt code lesen
404 Unbekannte Ressource oder Mandat, auf das der Benutzer keinen Zugriff hat public_token und Rechte prüfen
409 Versionskonflikt (X-Base-Version) Neu laden, zusammenführen, erneut senden
422 Daten abgelehnt (Validierung oder Buchhaltungsregel) Anhand von errors und code korrigieren
429 Zu viele Requests Retry-After Sekunden warten
500 Interner Fehler Später mit demselben Idempotenzschlüssel erneut versuchen
503 Dienst nicht verfügbar oder Wartung, immer mit einem code Mit wachsendem Abstand erneut versuchen

Ein Mandat, das existiert, auf das Sie aber keinen Zugriff haben, antwortet mit 404 und nicht mit 403. Das ist beabsichtigt: Die API gibt die Existenz eines Mandats nicht an Unbefugte preis.

Maschinencodes

Authentifizierung und Zugriff

code Status Bedeutung
token_ability_missing 403 Dem Integrationstoken fehlt die in required_ability genannte Berechtigung
session_token_required 403 Route ist Sitzungstokens vorbehalten
token_limit_reached 422 Höchstens 50 Integrationstokens pro Benutzer
webhook_limit_reached 422 Höchstens 20 Endpunkte pro Kanzlei
webhook_url_refused 422 Webhook-URL abgelehnt (HTTPS erforderlich, privater oder nicht auflösbarer Host)
demo_mode 403 Externe Wirkung in der Demo-Kanzlei blockiert
demo_unavailable 503 Die Demo-Kanzlei ist nicht verfügbar
service_unavailable 503 Allgemeine Nichtverfügbarkeit

Lizenz und Obergrenzen

code Status Bedeutung
company_limit_reached 422 Mandatsobergrenze der Lizenz oder des Plans erreicht
user_limit_reached 422 Benutzerobergrenze der Lizenz erreicht
invalid_key 422 Unbekannter Aktivierungsschlüssel
expired_key 422 Aktivierungsschlüssel abgelaufen
exhausted_key 422 Schlüssel wurde bereits so oft verwendet wie erlaubt
key_reserved 422 Schlüssel ist einer anderen Kanzlei vorbehalten
already_active 422 Dieser Schlüssel ist in der Kanzlei bereits aktiv

Gleichzeitige Zugriffe und Verlauf

code Status Bedeutung
conflict 409 oder 422 Der Datensatz hat sich seit Ihrem Lesezugriff auf dem Server geändert
period_locked 422 Periode gesperrt oder Geschäftsjahr abgeschlossen
vat_locked 422 MwSt.-Erklärung validiert oder eingereicht
entry_immutable 422 Eine gebuchte Buchung lässt sich nicht ändern: Sie muss storniert werden
already_reverted, already_reversed 422 Das Rückgängigmachen oder die Stornierung ist bereits erfolgt
in_use, booked 422 Löschung abgelehnt: Der Datensatz wird verwendet oder ist gebucht
code_taken 422 Wiederherstellung abgelehnt: Der Code wurde inzwischen neu vergeben
not_revertible, nothing_to_revert, operation_not_found 422 oder 404 Rückgängigmachen nicht möglich
force_forbidden, read_only 403 Rolle nicht ausreichend

Synchronisierung

Diese Codes erscheinen im Ergebnis jeder Mutation von sync/push, nicht als HTTP-Status.

code Bedeutung
locked Buchhaltungsdaten auf dem Server gebucht oder gesperrt
validation Daten abgelehnt, Einzelheiten in errors
not_supported_offline Dieser Vorgang läuft nicht über sync/push
not_found, forbidden, invalid_mutation, unknown_temp_id, unprocessable Mutation endgültig abgelehnt
server_error Vorübergehender Fehler, retryable: true
conflict_already_resolved, conflict_choice_unavailable Konfliktlösung abgelehnt (422)

Peppol

Peppol-Ablehnungen liefern blocker_codes, eine Liste aus: provider_not_configured, vat_number_missing, address_missing, email_missing, already_registered, managed_by_novadesko, registered_elsewhere, not_registered, provider_error.

{
  "message": "Le dossier ne peut pas être inscrit sur Peppol.",
  "errors": {"peppol": ["Le dossier ne peut pas être inscrit sur Peppol."]},
  "blockers": ["L'adresse e-mail de contact est manquante."],
  "blocker_codes": ["email_missing"],
  "state": {"status": "none", "can_register": false}
}
Hinweis

Nicht alle 422-Fehler tragen einen code. Ein einfacher Validierungsfehler enthält nur message und errors. Berücksichtigen Sie diesen Fall.

Validierungsfehler

{
  "message": "Le champ entry date est obligatoire. (et 1 erreur supplémentaire)",
  "errors": {
    "entry_date": ["Le champ entry date est obligatoire."],
    "lines.1.account_id": ["Le champ lines.1.account_id est obligatoire quand lines.1.account n'est pas présent."]
  }
}

Rate-Limits

Die Limits gelten pro Minute. Sie werden bei authentifizierten Routen pro Benutzer und bei öffentlichen Routen pro IP-Adresse gezählt. Routen, die in dieser Tabelle nicht aufgeführt sind, haben kein eigenes Limit.

Route Limit pro Minute
POST auth/login 20
POST auth/demo 10
POST auth/tokens 20
POST firms/{firm}/webhooks/{id}/test 12
GET pricing, GET pricing/simulate 120
POST firms/{firm}/licence/activate 10
POST firms/{firm}/sync 6
GET lookup/search, lookup/companies/{identifier}, lookup/vat 60
GET lookup/cities, lookup/streets 120
POST companies/{company}/apply-sheet, third-parties/{id}/apply-sheet 30
POST document-imports 30
POST document-imports/{id}/process, .../validate 120
POST document-imports/{id}/retry 60
POST documents/book-all 5
POST bank-transactions/match 10
POST bank-transactions/book-matched 5
POST payments/sepa 20
GET vies, POST third-parties/{id}/vies 30
POST sync/novadesko 10
POST integrations/{id}/test, .../sync 12
POST peppol/register 6
POST peppol/refresh 12
GET peppol/lookup 30
GET third-parties/{id}/peppol 60
POST third-parties/peppol/check-all 6
GET exports/{type} 30
GET exports/{type}/preview-url 60
GET exports/full-dossier/{fiscalYear} 10
POST fiscal-years/{id}/year-end 5
GET history/export 30

Jede Antwort einer begrenzten Route gibt Ihren Verbrauch an:

HTTP/1.1 200 OK
X-RateLimit-Limit: 30
X-RateLimit-Remaining: 27

Antwort 429

HTTP/1.1 429 Too Many Requests
Retry-After: 41
X-RateLimit-Limit: 30
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1791188421
Content-Type: application/json

{"message": "Too Many Attempts."}

Warten Sie die in Retry-After angegebene Anzahl Sekunden, bevor Sie es erneut versuchen. X-RateLimit-Reset gibt den Zeitpunkt der Rücksetzung in Unix-Sekunden an.

import time
import requests

def call(method, url, **kwargs):
    for attempt in range(5):
        response = requests.request(method, url, timeout=60, **kwargs)
        if response.status_code == 429:
            # Honour the server delay, never hammer the API
            time.sleep(int(response.headers.get("Retry-After", "5")) + 1)
            continue
        if response.status_code in (500, 503):
            time.sleep(2 ** attempt)
            continue
        return response
    raise RuntimeError("NovaFisko API unavailable")
Achtung

Wenn Sie einen Schreibzugriff nach einem Netzwerkfehler, einem 500 oder einem 503 wiederholen, senden Sie dieselbe X-Client-Mutation-Id erneut. Andernfalls riskieren Sie ein Duplikat. Siehe Idempotenz.

Weitere Limits

Limit Wert
Dateien pro Upload im Importer 20
Größe einer hochgeladenen Datei 25 MB
Aus einem ZIP-Archiv extrahierte Dateien 50
Mutationen pro Aufruf von sync/push 200
Änderungen pro Aufruf von sync/pull standardmäßig 500, höchstens 1000
Elemente pro Seite standardmäßig 50, höchstens 200 (500 für Bankbewegungen)
Gültigkeit einer signierten URL für die Exportvorschau 15 Minuten

Siehe auch