API-Rate-Limits und Best Practices
Überblick
Damit die API für alle zuverlässig bleibt, begrenzt Kyvento die Anfragerate je Account. Dieser Artikel erklärt die Limits, die zugehörigen HTTP-Header und die Muster, mit denen Ihre Integration effizient und wiederholungssicher arbeitet.
Das Rate-Limit
Für API-Token-Zugriffe gilt ein Kontingent pro Account und Minute, gestaffelt nach Ihrem Tarif:
- Starter: 30 Anfragen pro Minute
- Growth: 100 Anfragen pro Minute
- Pro: 280 Anfragen pro Minute
- Scale: 600 Anfragen pro Minute
In der Testphase gilt das Starter-Kontingent (30 Anfragen pro Minute). Jede Antwort trägt drei Header, mit denen Ihre Anwendung ihr Budget kennt:
X-RateLimit-Limit– das Minutenkontingent Ihres TarifsX-RateLimit-Remaining– verbleibende Anfragen im aktuellen MinutenfensterX-RateLimit-Reset– Zeitpunkt (Unix-Timestamp), zu dem wieder das volle Kontingent bereitsteht
Diese Header sind die verbindliche Auskunft über Ihr aktuelles Kontingent: Lesen Sie X-RateLimit-Limit zur Laufzeit aus, statt die Zahl fest in Ihre Integration zu schreiben – so bleibt Ihre Anwendung korrekt, wenn sich Ihr Tarif ändert oder die Limits angepasst werden.
Ist das Kontingent erschöpft, antwortet Kyvento mit HTTP 429, dem Fehlercode RATE_LIMITED und einem Retry-After-Header. Behandeln Sie 429 nie als Fehler Ihrer Logik, sondern warten Sie die angegebene Zeit und wiederholen Sie die Anfrage – idealerweise mit zusätzlichem Zufallsversatz, wenn mehrere Prozesse parallel arbeiten.
Zusätzliche Mengenlimits für schwere Vorgänge
Das Minutenkontingent begrenzt, wie oft Sie anfragen – nicht, wie viel ein einzelner Aufruf erzeugt. Drei besonders aufwendige Vorgänge tragen deshalb ein eigenes Kontingent, das zusätzlich zum Tarif-Limit gilt:
POST /exports/bulk-pdf– 5 pro Stunde. Der teuerste Vorgang: ein ZIP über bis zu 500 PDF-Dokumente.POST /exportsundPOST /exports/datev– 20 pro Stunde, gemeinsames Kontingent für die Export-Erzeugung.GET /search– 120 pro Minute, je Benutzer.
Welche der beiden Grenzen zuerst greift, hängt von Ihrem Tarif ab: Bei der Suche liegt das Minutenkontingent von Starter (30) und Growth (100) unter den 120 – dort bremst also weiterhin das Tarif-Limit. Und anders als dieses, das für den ganzen Account zählt, misst die Suche je Benutzer: maßgeblich ist der angemeldete Benutzer beziehungsweise der Eigentümer des verwendeten Tokens. Mehrere Tokens desselben Benutzers teilen sich das Kontingent – so kann ein Zugang die Suche seiner Kollegen nicht lahmlegen.
Die Kontingente zählen getrennt voneinander und getrennt vom Tarif-Limit; ein erschöpftes Bulk-PDF-Kontingent blockiert also weder die Suche noch den übrigen API-Verkehr. Das Abrufen bereits erzeugter Exporte – Liste, Detailansicht und Download – ist nicht gedrosselt: Ein Client, der auf die Fertigstellung pollt, läuft damit nicht gegen die Erzeugungsgrenze. Wird ein Kontingent überschritten, antwortet Kyvento wie sonst auch mit 429 und einem Retry-After-Header.
Sichere Wiederholungen: der Idempotency-Key
Bricht eine schreibende Anfrage ab (Timeout, Netzfehler), wissen Sie nicht, ob sie serverseitig durchkam. Senden Sie deshalb bei kritischen POST-Anfragen den Header Idempotency-Key mit einem selbst erzeugten, eindeutigen Wert (empfohlen: UUID). Kyvento merkt sich das Ergebnis 24 Stunden: Eine Wiederholung mit demselben Key liefert die ursprüngliche Antwort, statt die Operation erneut auszuführen. Derselbe Key mit verändertem Anfrage-Inhalt wird abgelehnt – das schützt vor Programmierfehlern.
Geldbeträge in der API
Jeder Geldbetrag verlässt die API als Dezimalstring in Euro – etwa "19.90", nicht 1990 und nicht 19.9 als Zahl. Der Grund ist Genauigkeit: Produkt- und Einzelpreise erlauben mehr als zwei Nachkommastellen, die weder in Cent-Ganzzahlen noch in Gleitkommazahlen verlustfrei aufgehen. Lesen Sie die Werte deshalb in einen Dezimaltyp ein (etwa decimal.Decimal oder BigDecimal) und nicht in ein float.
Das gilt einheitlich für die v1-API, das Kundenportal und den Checkout. Eine Ausnahme beim Schreiben: Der Mindestbestellwert eines Gutscheins (minimum_order_amount) wird beim Anlegen und Ändern weiterhin als Ganzzahl in Cent erwartet, während er in der Antwort als Dezimalstring erscheint. Übernehmen Sie den gelesenen Wert also nicht unverändert in ein Schreib-Payload.
Pagination richtig nutzen
- Listen liefern
dataplusmetamitper_page,has_moreund Folgeseiten-Informationen. per_pageakzeptiert bis zu 1000 Einträge – für Massenabgleiche große Seiten wählen, das spart Anfragen aufs Kontingent.- Für große, sich ändernde Bestände empfiehlt sich die Cursor-Pagination (
?pagination=cursor): Sie blättern übermeta.next_cursorstabil weiter, auch wenn parallel Datensätze entstehen oder verschwinden.
Best Practices für sparsame Integrationen
- Webhooks statt Polling: Lassen Sie sich Änderungen per Webhook melden, statt Listen im Minutentakt abzufragen – das ist schneller und verbraucht praktisch kein Kontingent (siehe Webhooks konfigurieren).
- Budget beobachten: Loggen Sie
X-RateLimit-Remainingund drosseln Sie Batch-Jobs, bevor das Limit greift. - Exponentiell zurückweichen: Bei 429 und 5xx mit wachsenden Abständen wiederholen – nie in einer engen Schleife.
- Fehler maschinenlesbar auswerten: Verzweigen Sie auf den
error_codeder Antwort, nicht auf Meldungstexte. - Massenabgleiche entzerren: Große Synchronisationen über die Zeit verteilen, statt das Minutenkontingent in kurzen Spitzen auszuschöpfen – so bleibt Budget fürs parallele Tagesgeschäft frei.
Nächste Schritte
- Alle Endpunkte und Konventionen – siehe API-Dokumentation und Beispiele
- Push-Benachrichtigungen einrichten – siehe Webhooks konfigurieren