maesn
Für Entwickler

Fortnox anbinden: Ein Stream, und er ist kein Webhook

Fortnox ist gut genug dokumentiert, dass die Überraschungen strukturell sind und nicht kleinteilig. Es prüft eine schwedische Identität, bevor Sie eine Sandbox bekommen, es misst je Token statt je Kunde, und Änderungen kündigt es über einen Kafka-gestützten Socket an, den Sie für alle Mandanten zugleich offen halten. Das Letzte ist kein Webhook, und es für einen zu halten ist die teuerste Annahme auf diesem System.

Lennart Svensson, CTO und Mitgründer bei Maesn
Lennart Svensson
CTO und Mitgründer · · Aktualisiert
Illustration zu Fortnox anbinden: Jede Änderung zuverlässig mitbekommen
Der Kontext

Die Hürde steht vor dem Code, nicht darin

Die meisten Integrationsleitfäden fangen bei der Authentifizierung an, weil dort die Arbeit anfängt. Auf diesem System gibt es einen Schritt davor, und für Teams außerhalb Schwedens ist es der, der entscheidet, ob das Projekt überhaupt stattfindet.

Fortnox ist fest in die schwedische Wirtschaftsinfrastruktur eingebunden, BankID und behördliche Register darunter. Wenn Sie ein Entwicklerkonto oder eine Testfirma anlegen, prüft das System eine Personen- oder Organisationsnummer. Das ist kein Rate Limit, um das herum man entwerfen kann, und kein Feld, das man leer lassen darf. Entweder Sie haben eine oder nicht.

Was hinter dieser Hürde liegt, ist großzügig. Fortnox betreibt kostenlose Sandboxes, und ein Entwicklerkonto kann bis zu 30 Testfirmen halten, jede eine vollständige Firmendatenbank, in die Sie sich einloggen und die Sie durchsehen können wie jede andere. Die Sandboxes sind nicht das Problem. Die Registrierung davor ist es.

Unsere eigene Sandbox-Dokumentation nennt dieses System aus genau diesem Grund: maesn stellt Sandboxes „für alle Systeme bereit, die wir unterstützen, einschließlich derer ohne kostenloses Testkonto, wie DATEV, Fortnox und Twinfield“. Gegen eine bereitgestellte Sandbox zu bauen ist das, was die schwedische Identität aus Ihrem kritischen Pfad nimmt.

Die Identitätsprüfung und die 30 Testfirmen sind in unserem eigenen Material zu diesem System dokumentiert; der Satz zur Sandbox ist aus der Sandbox-Übersicht zitiert, geprüft am 13. August 2026. Fortnox ist eines der Systeme, die dort ohne eigenes kostenloses Testkonto geführt werden.

So funktioniert es

Zwei Token-Abläufe, und einer kommt ohne Refresh aus

Fortnox nutzt OAuth 2.0 und stellt Ihnen eine Client-ID und ein Secret aus, sobald Sie eine Integration registrieren. Das ist die vertraute Hälfte: den Benutzer mit Ihren Scopes auf eine Autorisierungs-URL schicken, einen Code zurücknehmen, ihn tauschen und danach ein Refresh-Token am Leben halten, solange die Verbindung besteht.

Die weniger vertraute Hälfte ist neuer. Für Integrationen, die gegen Dienstkonten laufen, dokumentiert Fortnox inzwischen einen Client-Credentials-Ablauf als unmittelbare Alternative. Sie fordern ein Access-Token an, wann immer Sie eines brauchen, aus drei Werten, der Client-ID, dem Client-Secret und einer Mandanten-ID, und es gibt überhaupt kein Refresh-Token zu speichern oder zu rotieren.

Eine Einzelheit in dieser Dokumentation zählt mehr als der Ablauf selbst, weil sie festlegt, wie lange die Beziehung hält: „Die Zustimmung eines Kunden gilt unbefristet, bis er sie aktiv widerruft.“ Der Wechsel zwischen den beiden Abläufen ist als ohne Zutun des Kunden möglich dokumentiert, und beide können für dieselbe Integration und denselben Kunden nebeneinander laufen.

Über maesn ist das die gewöhnliche Weiterleitung: Fortnox steht weder auf der interaktiven noch auf der Headless-Liste, Ihr Kunde autorisiert also einmal und Sie bekommen einen Account-Key. Was die zwei Abläufe gemeinsam haben, ist genau das, was Unified Authentication wegnormalisiert, nämlich dass jedes System dieselbe Idee mit anderen Substantiven ausdrückt.

Der Client-Credentials-Ablauf, die drei Pflichtwerte und die Dauer der Zustimmung stammen aus Fortnox' Entwickler-Blog, geprüft am 13. August 2026. Welche Abläufe maesn für Sie nutzt, beschreibt der Connect-Guide.

Das Problem

Eine Liste gibt Ihnen einen Ausschnitt, und einen Filter auf einmal

Zwei dokumentierte Verhaltensweisen formen jeden Lesezugriff, den Sie hier schreiben, und sie verstärken einander.

Die erste ist, dass eine Liste eine Zusammenfassung ist. Wer nach Kunden fragt, bekommt Kennungen, Namen und eine Handvoll Felder zurück, alles, was eine Adresse oder einen Kontakt braucht, verlangt also einen zweiten Aufruf gegen diese einzelne Ressource. Eine Seite mit 100 Treffern ist damit eine Seite mit bis zu 100 Folgeanfragen.

Die zweite ist, wie eng eine Abfrage sein darf. Fortnox sagt es klar: „Es kann nur ein ressourcenspezifischer Filter auf einmal verwendet werden. Sie können einen ressourcenspezifischen Parameter mit einem globalen Parameter wie ‚lastmodified‘ kombinieren.“ Sie bekommen also eine Dimension Ihrer Wahl plus einen Zeitstempel, und jede weitere Einschränkung passiert in Ihrem eigenen Code, nachdem die Daten die Leitung schon überquert haben.

Zusammen machen diese beiden aus einem scheinbar einfachen Abgleich eine Rechenaufgabe, denn das, was sich nicht eingrenzen lässt, ist genau das, was Sie danach Datensatz für Datensatz ausweiten müssen. Diese Rechnung ist Ihre, und sie ist die Zahl, die Sie gegen die Grenze je Token halten. Was nicht ebenfalls Ihre wird, ist die Form: Das Common Data Model sorgt dafür, dass Zusammenfassung und Detail in derselben Form ankommen, und ein Weg, zu filtern und zu paginieren hält die Form der Abfrage gleich, wenn das nächste System seine Parameter anders schreibt.

Ein Ressourcenfilter, ein globaler Parameter und danach die DetailaufrufeHTTP
GET /3/invoices?customername=Testing
&lastmodified=2026-08-01 06:00
 
# ein Ressourcenfilter ist das Maximum.
# die Liste ist eine Zusammenfassung, jeder
# Datensatz mit Detailbedarf kostet einen Aufruf:
GET /3/invoices/{DocumentNumber}

lastmodified ist der globale Parameter, der alles seit einem Zeitstempel Geänderte zurückgibt, und damit der, um den herum man einen Delta-Abgleich baut.

Die Filterregel, die Tabelle der globalen Parameter und das Suchverhalten stammen aus Fortnox' Leitfaden zu den Parametern, geprüft am 13. August 2026. Der zweistufige Lesezugriff ist in unserem eigenen Material zu diesem System dokumentiert.

Das Problem

25 Anfragen alle fünf Sekunden, je Token

Fortnox veröffentlicht eine Zahl und veröffentlicht sie genau: „Die Grenze je Access-Token liegt bei 25 Anfragen je 5 Sekunden. Das entspricht 300 Anfragen je Minute.“

Die Einheit ist der Teil, den man zweimal lesen sollte. Weil das Budget am Access-Token hängt und ein Token zu einem verbundenen Kunden gehört, folgt die Obergrenze jedem Kunden. Ihr tausendster Mandant bremst Ihren ersten nicht aus, und das ist das Gegenteil davon, wie sich ein Kontingent je Anwendung verhält.

Das Fünf-Sekunden-Fenster zählt genauso viel wie die Zahl je Minute. Dreihundert in der Minute klingt nach Platz für einen Schwall; 25 je fünf Sekunden sagt, dass es keinen gibt. Ein Nachladen, das einen Listenaufruf und danach 100 Detailaufrufe so schnell wie möglich absetzt, trifft das Fenster in der ersten Sekunde und bleibt darin.

Die zwei Einschränkungen multiplizieren sich
Eine zusammenfassende Liste plus ein Detailaufruf je Datensatz, gegen ein Fünf-Sekunden-Fenster, ist die Dimensionierungsfrage für jeden ersten Import auf diesem System. Rechnen Sie die Zahl der Datensätze aus, bevor Sie einen Termin zusagen.
So funktioniert es

Fortnox sendet über einen Socket, nicht an Ihren Endpunkt

Hier ordnen die meisten Beschreibungen von Fortnox die Kategorie falsch ein, eine eigene eingeschlossen. Fortnox kündigt Änderungen durchaus an, und der Mechanismus ist kein Webhook. Es gibt keine URL, die Sie registrieren, und keinen Callback zu bestätigen.

Was es gibt, ist ein Stream: „Die Schnittstelle besteht aus einem einzelnen Duplex-Websocket-Stream mit verschiedenen Topics, z. B. ‚invoices‘ und ‚supplier-invoices‘.“ Sie verbinden sich einmal, fügen Ihre Mandanten dieser Verbindung hinzu und abonnieren Topics. Fortnox ist deutlich, welche Form es will: „Für unsere Skalierbarkeit ist es wichtig, dass Sie nicht eine Verbindung je Kunde halten.“

Darunter liegt Apache Kafka, und das Vokabular von Kafka ist der nützliche Teil. Jedes Event trägt einen Offset innerhalb seines Topics, die Reihenfolge ist garantiert, und die Zustellung erfolgt mindestens einmal, Duplikate sind also ein Fall, den Sie behandeln, und kein Fehler, den Sie melden.

Was der Hersteller dokumentiertEin Socket, kein Callback
wss://ws.fortnox.se/topics-v1
Eine Verbindung
Alle Mandanten
Mandanten werden demselben Stream hinzugefügt. Der Hersteller bittet ausdrücklich um eine Verbindung über alle hinweg.
Reihenfolge
Garantiert
Jedes Event hat einen Offset innerhalb seines Topics, und die Zustellung erfolgt mindestens einmal, Duplikate sind also zu erwarten.
Replay-Fenster
14 Tage
Mit einem Offset erneut verbinden, und Events werden wiederholt. Ein Offset, der älter ist als das Fenster, rückt auf den frühesten, ohne Fehler.
Nutzlast
Minimal
Das Event sagt, was passiert ist, und nicht, was sich geändert hat, auf fast jedes folgt also ein Lesezugriff.

Ein Stream ist Infrastruktur, ein Webhook ist eine Route. Den einen halten Sie offen, überwachen ihn und setzen ab einem Offset wieder auf. Der andere kommt an einer URL an. Für den zweiten zu planen, wenn der erste das ist, was existiert, ist hier der teure Fehler.

Die vier Eigenschaften, die einen Stream von einem Callback trennen, alle aus Fortnox' Websocket-Leitfaden. Geprüft am 13. August 2026.

Zwei dieser Eigenschaften gehören in den Entwurf, vor jeden Code. Das Replay-Fenster heißt, dass eine verpasste Stunde wiederherstellbar ist: Verbinden Sie sich mit Ihrem letzten Offset erneut, und Events werden bis zu 14 Tage zurück wiederholt. Es scheitert außerdem still, denn ein Offset, der älter ist als das Fenster, wird auf den frühesten verfügbaren verschoben, und der Aufruf gelingt trotzdem.

Und die Nutzlast ist bewusst dünn. „Minimale Events – sagen, was passiert ist, enthalten aber nicht alle Daten. Wenn Sie ein Event erhalten, kann es nötig sein, die API aufzurufen, um die aktualisierte Entität abzurufen und zu sehen, was sich geändert hat.“ Der Stream sagt Ihnen also, wo Sie nachsehen müssen, und der Lesezugriff danach unterliegt allem aus den zwei Abschnitten darüber.

Fortnox hält außerdem fest, dass die Abdeckung unvollständig ist: „Wir haben in diesem Modus noch nicht alles ergänzt, melden Sie sich, wenn Ihnen Events fehlen.“ Gut zu wissen, bevor eine Architektur annimmt, dass jede Änderung sich selbst ankündigt.

Eine Auswahl der Topics und was jedes ankündigt
TopicEventsBeispiel
invoices7invoicepayment-bookkeep-v1
customers3customer-updated-v2
supplier-invoices4supplier-invoice-bookkeep-v1
vouchers3voucher-created-v1
financial-years6account-created-v1
suppliers3supplier-deleted-v1

Topics, Eventnamen und Anzahlen stammen aus der Tabelle in Fortnox' Websocket-Leitfaden, geprüft am 13. August 2026, der insgesamt 18 Topics führt. Eventtypen sind versioniert, und customer-updated-v2 zeigt, dass die Versionen sich bewegen.

So funktioniert es

Was heute läuft, ist ein Delta-Abruf auf einem Zeitstempel

Alles oben beschreibt, was der Hersteller veröffentlicht. Was Ihre Verbindung über maesn heute tut, ist eine eigene Frage, und die Antwort fällt kleiner aus: Kein Objekt trägt einen freigeschalteten Webhook, Aktualität kommt also aus einem Lesezugriff nach Zeitplan.

Beide Tatsachen gehören in denselben Absatz, weil ein Plan, der auf einer allein aufbaut, schiefgeht. Den Stream gibt es, ob diese Verbindung ihn nutzt oder nicht, und was heute abgeschaltet ist, kann später eingeschaltet werden. Das Event-Modell ist die Stelle, an der diese Unterscheidung wohnt, und auf diesem System ist die Abruf-Hälfte derzeit das Ganze davon.

Zwei Schichten, beide wahrGemessen, nicht abgeleitet
Was Fortnox veröffentlicht
Ein Event-Stream
Topics für Rechnungen, Kunden, Lieferanten, Belege und mehr, mit Offsets und einem Replay-Fenster.
Was heute über maesn freigeschaltet ist
Kein Webhook
Keines der 37 Objekte trägt ein freigeschaltetes Event, Aktualität kommt also aus einem Lesezugriff nach Zeitplan.
Worauf Ihr Abgleich tatsächlich läuft
lastmodified
Ein globaler Parameter, der alles seit einem Zeitstempel Geänderte zurückgibt, kombinierbar mit einem Ressourcenfilter.

Beide Zeilen lohnt es sich vor dem Entwurf zu kennen. Ein System, das einen Stream veröffentlicht, kann später einen bekommen, und ein Abgleich, der auf einem Zeitstempel aufbaut, läuft so oder so weiter. Worauf er nicht aufbauen sollte, ist ein Event, das es noch nicht gibt.

Zwei Schichten, beide gemessen: was der Hersteller veröffentlicht, was heute freigeschaltet ist und worauf Ihr Abgleich tatsächlich läuft.

Die gute Nachricht ist, dass der Abruf einen tragfähigen Filter hat, auf dem er stehen kann. lastmodified gibt alles zurück, was sich seit einem Zeitstempel geändert hat, und lässt sich mit einem Ressourcenfilter kombinieren, und das ist genau die Form, die ein Delta-Abgleich braucht. Sie fragen, was sich seit dem letzten Lauf bewegt hat, blättern hindurch und holen das Detail für die Datensätze, die es brauchen.

Ein Abruf holt außerdem auf, was ein Stream nur innerhalb seines Replay-Fensters tut und ein Callback gar nicht. Fällt Ihr Worker einen Tag aus, stellt der nächste Lauf dieselbe Frage und bekommt eine vollständige Antwort, ohne dass ein Offset hätte aufbewahrt werden müssen.

Wie der Objektumfang im Einzelnen aussieht, einschließlich der 28 Kombinationen mit der Markierung auf Anfrage, steht auf der Seite zur Fortnox-Schnittstelle.

Auf Anfrage ist kein Liefertermin
Achtundzwanzig Objekte tragen hier in der Webhook-Spalte die Markierung auf Anfrage. Auf Anfrage heißt technisch machbar und noch nicht gebaut, es markiert also ein Gespräch, das zu eröffnen ist, und die Webhook-Spalte ist die Stelle, an der diese Unterscheidung am meisten zählt. Entwerfen Sie gegen das, was heute freigeschaltet ist.
Wo unser Teil endet

Was maesn abdeckt, und was bei Ihnen bleibt

Was wir davon abnehmen:

  • Die schwedische Identität, fürs Entwickeln. Die Sandbox kommt von uns, und das ist der Unterschied zwischen diesen Monat anfangen und gar nicht anfangen.
  • Den zweistufigen Lesezugriff. Die zusammenfassende Liste und der Detailaufruf je Datensatz kommen im gemeinsamen Modell als ein Objekt an, das N+1 erreicht Ihren Code also nicht.
  • Den Token-Ablauf. Auf welchem Weg Fortnox den Zugang auch ausstellt und erneuert, Ihre Seite hält einen Account-Key.

Was bei Ihnen bleibt, und zwei davon sind Entscheidungen statt Aufgaben:

  • Das Abfrageintervall und seine Rechnung. Den Zeitplan setzen Sie, und wie aktuell Ihr Produkt sein muss, gemessen gegen 25 Anfragen je fünf Sekunden je Kunde, ist eine Produktentscheidung.
  • Der Markteintritt auf Fortnox. Der Hersteller prüft eine Integration vor der Veröffentlichung und sieht sich die Landingpage, die Preise, den Support-Kontakt und die Verträge an. Das ist Ihre Einreichung.
  • Der Nettobetrag, falls Sie einen brauchen. Welche Betragsfelder zurückkommen, hängt vom Endpunkt ab, den Sie lesen, prüfen Sie also den, den Ihr Use Case benutzt, bevor Sie annehmen, dass der Beleg alle drei trägt.
  • Undokumentierte Endpunkte. Manches, was in der Fortnox-Oberfläche sichtbar ist, steht nicht in der öffentlichen Referenz. Alles Undokumentierte kann sich ohne Ankündigung ändern, und darauf zu bauen ist eine Entscheidung, die man mit offenen Augen trifft.
FAQ

Häufige Fragen

Brauche ich eine schwedische Identität, um eine Fortnox-Integration zu bauen?

Für ein Entwicklerkonto und eine Sandbox ja. Fortnox ist in schwedische Geschäftsabläufe eingebunden und prüft beim Anlegen eines Kontos oder einer Sandbox eine Personen- oder Organisationsnummer. Über maesn zu bauen nimmt diesen Schritt weg, denn die Sandbox wird bereitgestellt, statt von Ihnen registriert zu werden.

Unterstützt Fortnox Webhooks?

Für Geschäftsobjekte nicht. Änderungen werden über einen einzelnen Duplex-Websocket-Stream mit einem Topic je Domäne angekündigt, und Webhooks gibt es nur für Events zu erteilter und widerrufener Zustimmung im Entwicklerportal. Über maesn trägt heute kein Objekt einen freigeschalteten Webhook, der Abgleich ist also ein Lesezugriff nach Zeitplan.

Wie lauten die Rate Limits von Fortnox?

Fünfundzwanzig Anfragen je fünf Sekunden je Access-Token, was die Referenz als 300 je Minute angibt. Weil je Token gemessen wird und nicht je Anwendung, folgt die Obergrenze jedem verbundenen Kunden, statt über alle hinweg geteilt zu werden.

Warum lässt eine Fortnox-Listenantwort Felder weg?

Von Haus aus. Listen-Endpunkte geben eine Zusammenfassung jedes Datensatzes zurück, das volle Detail braucht also einen zweiten Aufruf gegen die einzelne Ressource. Damit wird aus einer Seite voller Treffer eine Seite voller Folgeanfragen, und das ist das Wichtigste, was man gegen eine Grenze je Token einplant.

Kann ich eine Fortnox-Abfrage auf mehr als ein Feld filtern?

Nur auf eines zur Zeit. Die Dokumentation hält fest, dass ein einzelner ressourcenspezifischer Filter verwendet werden kann und dass er sich mit einem globalen Parameter wie lastmodified kombinieren lässt. Alles Engere als das muss auf Ihrer Seite passieren, nachdem die Antwort angekommen ist.

Wie weit zurück lässt sich ein verpasstes Fortnox-Event wiederholen?

Vierzehn Tage. Jedes Event trägt einen Offset innerhalb seines Topics, und wer beim erneuten Verbinden einen älteren Offset angibt, bekommt ab dort wiederholt. Ein Offset, der älter ist als das Fenster, wird still auf den frühesten verfügbaren verschoben statt abgelehnt, eine lange Störung baut also leise ab.

Einmal bauen, auf der Unified API.

Fortnox misst 25 Anfragen alle fünf Sekunden je Token, BuchhaltungsButler erlaubt zehn Uploads je Minute und SnelStart genehmigt, bevor es einen produktiven Schlüssel ausstellt. Bauen Sie gegen eine Schnittstelle, und jedes davon wird zu einer Zeile in einer Tabelle statt zu einem Projekt.