maesn
Für Entwickler

Exact Online anbinden: 5.000 Aufrufe am Tag, und jedes Event, auf das Sie reagieren, kostet einen

Exact Online hat einen großen Schnittstellenumfang und ein kleines Budget, um ihn zu erreichen. Drei dokumentierte Regeln entscheiden die Architektur, bevor Sie eine Zeile schreiben: 60 Aufrufe je Minute und Firma, keine parallelen Aufrufe und ein Event, das Ihnen eine Kennung übergibt statt eines Datensatzes.

Lennart Svensson, CTO und Mitgründer bei Maesn
Lennart Svensson
CTO und Mitgründer · · Aktualisiert
Illustration zu Exact Online anbinden: 5.000 Aufrufe am Tag richtig nutzen
Der Kontext

Drei regionale Umgebungen, und in jeder eine Division

Exact Online ist der Ort, an dem ein großer Teil der niederländischen und belgischen Unternehmen seine Bücher führt, und das ist meist der Grund, warum ein Produkt am Ende daran angebunden wird. Anspruchsvoll ist daran nicht das Protokoll. Es ist REST, es übernimmt die Query-Optionen und Typnamen von OData, und einen einzelnen Datensatz zu holen ist unauffällig.

Die Schwierigkeit ist, dass es nicht ein einziges Exact Online gibt. Die Plattform läuft als getrennte regionale Umgebungen, und eine App gehört zu genau einer davon. Innerhalb einer Umgebung gehören Daten zu einer Division statt zu einem Konto, und fast jede Ressourcen-URI trägt sie mit.

Drei regionale Zielsysteme sind dokumentiert, jedes mit eigenem Callback, und nur eines davon unterstützt den interaktiven Ablauf, der die Division beim Verbinden für Sie klärt.

Eine App je Region, und eines der drei klärt die Division für Sie
ZielsystemRegionInteraktiver Authentifizierungsablauf
exact-nlNiederlandeJa. Ihr Kunde wählt auf einer Auswahlseite eine Division, und die Wahl wird mit der Verbindung gespeichert
exact-deDeutschlandNein. Die Division reist als Query-Parameter companyId bei jedem Aufruf mit, der sie braucht
exact-gbVereinigtes KönigreichNein. Die Division reist als Query-Parameter companyId bei jedem Aufruf mit, der sie braucht

Zielsysteme und Callbacks stammen aus der Exact-Online-Dokumentation von maesn, die Liste der interaktiven Abläufe aus der Authentifizierung bei maesn, in der exact-nl steht und die anderen beiden nicht. Geprüft am 7. August 2026.

Zwei Aufrufe lohnt es sich vor allem anderen zu kennen. /api/v1/current/Me?$select=CurrentDivision sagt Ihnen, in welcher Division Sie sind, und /api/v1/{division}/system/Divisions sagt Ihnen, welche davon der freigebende Benutzer Ihrer App tatsächlich geöffnet hat. Das ist eine andere Menge als die, die er selbst öffnen kann, und darum geht es im nächsten Absatz.

Im Zustimmungsdialog wählt der Benutzer, welche Divisionen Ihre App lesen darf, und Exact dokumentiert die Folge an einem durchgerechneten Beispiel. Ein Benutzer mit Rechten auf die Divisionen A, B und C gibt Ihrer App A und B frei.

Eine Anfrage auf C antwortet dann mit User division is not within division scope. Eine Anfrage auf D antwortet mit Wrong division. Zwei Fehler, zwei Ursachen: Der erste ist die Freigabe an Ihre App, der zweite der Zugang des Benutzers selbst.

Wenn Sie den Objektumfang, die Authentifizierungsoptionen und den Eintrag im App Store an einer Stelle brauchen, steht das auf der Seite zur Exact Online Schnittstelle. Was jetzt folgt, ist der Weg, gegen die Plattform zu bauen, ohne das Tagesbudget eines Kunden beim ersten Abgleich auszugeben.

Die Begrenzung auf Divisionen und beide Fehlertexte stammen aus Exacts Überblick zur OAuth2-Implementierung, Abschnitt DivisionLevelScoping, geprüft am 7. August 2026.

Das Problem

60 Aufrufe je Minute und 5.000 am Tag, je Firma

Exact veröffentlicht zwei Rate Limits, und sie sind der Rahmen für alles andere auf dieser Seite. Eine App darf 60 API-Aufrufe je Firma und Minute machen und 5.000 je Firma und Tag. Wer eines von beiden überschreitet, bekommt 429.

Lesen Sie den Geltungsbereich genau, denn er schneidet in beide Richtungen. Exacts Seite zu den Einschränkungen hält fest, dass beide Grenzen je App und je Division gelten, und Firma und Division sind in dieser Dokumentation dasselbe. Ein Kunde mit vier Divisionen gibt Ihnen also vier getrennte Budgets, und Sie können aus dem einen nichts borgen, um einen Abgleich im anderen zu Ende zu bringen.

Die Minutengrenze ist außerdem keine Bandbreitenangabe, denn Sie dürfen sie nicht parallel ausschöpfen. Exact wörtlich: Parallele API-Aufrufe sind nicht erlaubt, alle Integrationen müssen sequenzielle API-Aufrufe verwenden. Mehrfädige Anfragen und Pipelining sind ausdrücklich als zu unterlassen benannt. Sechzig je Minute beschreibt deshalb eine Warteschlange und keinen Stoß.

Zwei Fenster, zwei Arten leerzulaufen
FensterGrenzeHeader in jeder Antwort mit Division
Minute60 Aufrufe, je App, je DivisionX-RateLimit-Minutely-Limit, X-RateLimit-Minutely-Remaining
Tag5.000 Aufrufe, je App, je Division. Bis zu 30.000 mit einer Exact-Premium-LizenzX-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset als UTC-Epochenmillisekunden

Grenzen, Header und das Premium-Kontingent stammen aus Exacts API-Limits, der Geltungsbereich je App und je Division aus den Einschränkungen der REST-Schnittstelle. Beides geprüft am 7. August 2026.

Ein kostenloser Aufruf, und er ist nützlich

Anfragen ohne Firmenkennung in der URL werden nicht gegen die Tagesgrenze gezählt. Exact nennt /api/v1/current/Me als Beispiel, der Aufruf, der Ihnen sagt, in welcher Division Sie sind, kostet Sie also nichts.

Das Problem

Zehn Fehler je Stunde sperren den Schlüssel

Das zweite Budget ist das, mit dem niemand plant. Exact erlaubt höchstens zehn Fehler je API-Schlüssel, je Benutzer, je Firma, je Endpunkt und je Stunde. Ab dem elften wird der Schlüssel für weitere Anfragen gesperrt, die Sperre hebt sich nach einer Stunde von selbst auf, und sie verlängert sich, wenn die Fehler weiter eintreffen.

Welche Antworten zählen, ist der Teil, der ändert, wie Sie Code schreiben: 400, 401, 403 und 404. Ein fehlender Datensatz ist in dieser Rechnung ein Fehler. Das Muster, erst zu fragen, ob es etwas gibt, und es sonst anzulegen, kostet deshalb mehr als den vergeudeten Aufruf: Zehn Fehlgriffe in einer Stunde sperren Sie von diesem Endpunkt aus.

Dasselbe gilt für Wiederholungen. Exact bittet darum, fehlschlagende Nachrichten nicht unbegrenzt zu wiederholen und vorübergehende Fehler von fachlichen zu trennen, denn einen fachlichen Fehler zu wiederholen ist eine Schleife, die in einer Sperre endet statt in einem Erfolg.

Backoff, Klassifizierung und der Unterschied zwischen einem abgelehnten Aufruf und einem gesperrten Client sind auf jedem System dasselbe Problem, und deshalb stecken sie in einem Fehlermodell statt in jeder einzelnen Integration.

Das Fehlerkontingent und die mitgezählten Statuscodes stammen aus den API-Limits, der Hinweis zu Wiederholungen aus den Einschränkungen der REST-Schnittstelle, geprüft am 7. August 2026.

Das Problem

60 Datensätze je Seite, oder 1.000 auf den Sync-Endpunkten

Exacts Referenzdokumentation sagt es in einer Zeile: Der größte Teil der REST-Schnittstelle hat eine Seitengröße von 60, die Bulk- und Sync-Endpunkte haben eine Seitengröße von 1000, und es wird empfohlen, die Sync-Endpunkte zu verwenden, wo immer es geht.

Dahinter stehen fünf API-Typen, und die meisten Objekte bieten mehrere davon an. Den richtigen zu wählen ist keine Optimierung, es ist der Unterschied zwischen einem Produkt, das in das Tagesbudget eines Kunden passt, und einem, für das er eine Premium-Lizenz kaufen muss.

Fünf Wege zum selben Objekt
API-TypSeitengrößeWofür er da ist
Regular60GET, POST, PUT und DELETE. Der einzige Typ, der schreibt
Bulk1.000Vollständige Erstbefüllung. $select ist Pflicht
Sync1.000Nur neue und geänderte Datensätze, adressiert über eine Timestamp-Zeilenversion statt über ein Änderungsdatum
Deleted1.000Löschungen, die Sync nicht meldet. Exact sagt, man solle ihn neben Sync laufen lassen und nicht an seiner Stelle
Webhooksn/aPush, weiter unten auf dieser Seite behandelt

Typen und Seitengrößen stammen aus Exacts API-Typen und der Referenz der REST-Schnittstelle, geprüft am 7. August 2026.

Ein Tag, eine Firma5.000 Aufrufe, so oder so
Regulärer Endpunkt
60Datensätze je Seite
300.000Datensätze am Tag, höchstens

Die Standardform der REST-Schnittstelle, und die einzige, die schreibt.

Bulk- oder Sync-Endpunkt
1.000Datensätze je Seite
5.000.000Datensätze am Tag, höchstens

Nur lesend, und Exact empfiehlt Sync überall dort, wo es ihn gibt.

Dasselbe Budget, rund die siebzehnfache Reichweite. Die Entscheidung ist, welchen Endpunkt Sie aufrufen, und sie rührt an keiner Ihrer Fachlogiken.

Beide Spalten geben dieselben 5.000 Aufrufe aus. Die einzige Variable ist, an welchen Endpunkttyp der Aufruf ging.
Die Rechnung, die Ihren Entwurf entscheidet

Fünftausend Aufrufe zu 60 Datensätzen erreichen an einem Tag höchstens 300.000 Datensätze. Dieselben fünftausend zu 1.000 Datensätzen erreichen fünf Millionen. Zwischen diesen beiden Zeilen ändert sich nichts an Ihrem Datenmodell, nur der Endpunkt, den Sie gewählt haben.

Beide Zahlen sind Exacts eigene, und multipliziert haben wir sie, mehr nicht. Es ist auch der Grund, warum ein erster Abgleich gegen Exact Online auf Bulk gehört, der Dauerbetrieb auf Sync plus Deleted, und die regulären Endpunkte zum Schreiben und für einzelne Datensätze da sind.

Dauerbetrieb: Sync für die Änderungen, Deleted für den RestHTTP
GET /api/v1/{division}/sync/CRM/Accounts
?$filter=Timestamp gt 1&$select=ID,Name
→ 200 { "d": { "results": [ … bis zu 1000 Datensätze, jeder
mit einem Timestamp … ] } }
 
# den höchsten gesehenen Timestamp merken, dann von dort weiter
GET /api/v1/{division}/sync/CRM/Accounts
?$filter=Timestamp gt 84213&$select=ID,Name
 
# Sync meldet nie Löschungen, das hier läuft deshalb daneben
GET /api/v1/{division}/sync/Deleted?$filter=Timestamp gt 84213

Die Form des Filters und der Startwert Timestamp gt 1 stammen aus Exacts Referenzdokumentation, Entität SyncCRMAccounts. Pfade zur Lesbarkeit gekürzt.

Zwei Einzelheiten entscheiden, ob der Cursor überlebt. Der Timestamp ist eine Zeilenversion und hat keinen Bezug zu einem Datum, lässt sich also weder mit einem vergleichen noch in eines umrechnen.

Und Exact setzt diese Werte zurück, wenn es eine Division in eine andere Datenbank verschiebt, danach muss alles erneut abgeglichen werden. Das Datum der letzten Verschiebung ist als DivisionMoveDate am Divisions-Endpunkt lesbar, Ihr Code kann das Zurücksetzen also erkennen.

Das Blättern ist von Haus aus sequenziell. Eine Antwort, die länger ist als die Seitengröße, trägt eine Eigenschaft __next mit einem $skiptoken, und die nächste Anfrage lässt sich erst bauen, wenn die vorige Antwort da ist. Da parallele Aufrufe ohnehin verboten sind, kostet die Reihenfolge hier nichts. Wie dieselbe Frage nach Blättern und Filtern über Systeme hinweg aussieht, zeigt ein Weg, zu filtern und zu paginieren.

Eine Regel schließt den Kreis: Exact erzwingt eine Pflichtfilterung auf Single- und Bulk-Endpunkten, wo es eine Sync-Schnittstelle gibt. Lassen Sie $filter weg, bekommen Sie eine 400, die die erwarteten Felder nennt. Die Plattform lenkt Sie auf den billigen Weg, und es lohnt sich, ihn zu gehen.

Wie maesn das löst

Ein Fenster von 30 Sekunden zum Erneuern, alle zehn Minuten

Exact Online authentifiziert über OAuth, und eine Zahl im Lebenszyklus des Tokens entscheidet, wie Sie das Erneuern planen. Ein Access-Token gilt 600 Sekunden. Ein neues darf erst angefordert werden, wenn seit dem letzten erfolgreichen Token-Aufruf 570 Sekunden vergangen sind. Beide Zahlen sind Exacts eigene, und sie stehen auf zwei verschiedenen Seiten seiner Dokumentation.

Zieht man sie voneinander ab, ist das erlaubte Fenster zum Erneuern 30 Sekunden breit, einmal alle zehn Minuten. Fragen Sie zu früh, bekommen Sie Rate limit exceeded: access_token not expired. Fragen Sie zu spät, ist das Token schon weg.

Ein Access-Token, 600 Sekunden30 Sekunden zum Handeln
0 s
Exact stellt das Access-Token aus.
570 s
Der früheste Zeitpunkt, an dem ein neues angefordert werden darf. Früher antwortet Rate limit exceeded: access_token not expired.
600 s
Das Token läuft ab. Jeder Aufruf danach ist eine 401.

Das Fenster ist der Abstand zwischen den letzten beiden Marken. Erneuern Sie auf einem festen Zehn-Minuten-Takt, entscheidet die Uhrdrift, ob Sie darin landen.

Zehn Minuten Token-Leben, und die letzten dreißig Sekunden davon sind der einzige Moment, in dem ein Erneuern erlaubt ist.

Die 570-Sekunden-Regel stammt aus den API-Limits, die Lebensdauer von 600 Sekunden und der Fehlertext aus den Antwortcodes und der Fehlerbehandlung. Gut zu wissen, bevor Sie den Handler schreiben: Diese Seite dokumentiert dieselbe Meldung unter 400 und unter 401. Geprüft am 7. August 2026.

Das Refresh-Token hat eigene Regeln, und jede davon endet gleich. Es ist einmal verwendbar: Wer eines erneut benutzt, bekommt 401, und gültig ist nur das zuletzt ausgestellte. Mehrere Autorisierungsanfragen parallel zu stellen entwertet die frühere Kette, was Exact als token is not allowed, because of invalid or empty chainId meldet. Und seit Juli 2021 läuft ein Refresh-Token nach 30 Tagen ab.

Das Letzte ist eher eine betriebliche als eine technische Tatsache. Eine Verbindung, die einen Monat lang niemand anfasst, wird nicht langsam schlechter, sie hört auf, und der einzige Weg zurück führt über die Bitte an Ihren Kunden, erneut zu autorisieren.

maesn verwahrt die Tokens, erneuert sie innerhalb des Fensters und hält die Verbindung am Leben, Ihr Code trägt deshalb einen Account-Key, der nicht nach Zeitplan abläuft. Die allgemeine Form davon ist Unified Authentication.

Die einmalige Verwendung, die chainId und die Gültigkeit von 30 Tagen stammen aus Exacts Überblick zur OAuth2-Implementierung und den Antwortcodes, geprüft am 7. August 2026.

Wie maesn das löst

Ein neuer Datensatz kommt als Aktualisierung an

Exact Online hat Webhooks, und sie sind der Grund, warum Sie Änderungen nicht abfragen müssen. Offen bleibt die Art der Änderung.

Exacts eigenes Tutorial ist gleich zweimal deutlich: Anlegen, Aktualisieren und Löschen eines Datensatzes erzeugen alle eine Benachrichtigung, und die Aktion ist entweder UPDATE oder DELETE, und wenn das vollständige Konto gelöscht wird, ist die Aktion DELETE, in allen anderen Fällen ist die Aktion UPDATE.

Drei Dinge passieren, zwei Wörter kommen zurück
Was passiert istGesendete AktionWas das Event Ihnen sagt
Ein Kunde wird angelegtUPDATEDass dieser Datensatz existiert und sich zu holen lohnt. Nicht, dass er neu ist
Ein Kunde wird bearbeitetUPDATEDass sich etwas an ihm geändert hat. Nicht, welches Feld
Ein Kunde wird gelöschtDELETEDass er weg ist

Die Bedeutung der Aktionen und der Auslöser der Benachrichtigung stammen aus Exacts Einstieg in Webhooks, geprüft am 7. August 2026. Behandeln Sie ein UPDATE als Upsert, dann spielt die Unterscheidung keine Rolle mehr.

Das Zweite, was man wissen sollte, ist der Inhalt der Benachrichtigung, denn er entscheidet, was ein Event Sie kostet. Exact sendet ein Content-Objekt mit dem Topic, der Aktion, der Division, dem Key des Datensatzes und einem ExactOnlineEndpoint, von dem er zu holen ist, dazu einen HashCode zur Prüfung. Den Datensatz selbst sendet es nicht.

Jedes Event, auf das Sie reagieren, ist also ein Aufruf gegen das Budget von weiter oben auf dieser Seite. Die Benachrichtigung selbst ist kostenlos, denn die Grenzen zählen die Aufrufe Ihrer App, und Exact nennt Webhooks als einen Weg, darunter zu bleiben. Was kostet, ist der Abruf danach, und eine Integration, die bei einem regen Kunden auf jede Benachrichtigung hin abruft, kann das Kontingent eines Arbeitstages für Nachfassaufrufe ausgeben.

Dazu kommt eine Bedingung, die unauffällig entscheidet, wo das Abonnement liegt. Exact verlangt, dass die Callback-URL die URL und die Domain der Redirect-URI teilt, mit der die App registriert wurde, über HTTPS, und prüft sie mit einem leeren POST, der mit 200 oder 201 antworten muss.

Die Redirect-URI Ihrer App zeigt auf maesn, das Abonnement wird deshalb hier registriert, und was zu Ihrem Dienst weiterläuft, ist das normalisierte Event.

Für einen Kunden abonnieren, danach eine Form behandelnJS
await axios.post(url, {
callbackUrl,
resource: "CONTACT" // die Ressource abonnieren, kein Paar
}, { headers: { "X-API-KEY": apiKey, "X-ACCOUNT-KEY": accountKey } });
 
// was an callbackUrl ankommt
{
"eventType": "UPDATED",
"filterDate": null, // von Exact Online nicht unterstützt
"resource": "CUSTOMER", // CONTACT kommt zweigeteilt zurück
"resourceId": "1605408d-ed88-4228-8a12-ab857a2972d8",
"userId": null // von Exact Online nicht unterstützt
}

Anfrage und Nutzlast wörtlich aus der Exact-Online-Dokumentation von maesn. Der Parameter companyId ist Pflicht, sofern der interaktive Ablauf die Division nicht bereits gespeichert hat.

Drei Einzelheiten in dieser Nutzlast zählen. Das Abonnement wird je Kunde angelegt, jedes verbundene Konto ist also seine eigene Registrierung. Sie abonnieren CONTACT und bekommen CUSTOMER oder SUPPLIER, weil Exact die beiden auf dem Weg nach draußen trennt. Und filterDate und userId kommen leer an, weil Exact sie nicht sendet.

Diese zwei leeren Felder sind der ehrliche Teil der Vereinheitlichung. Derselbe Umschlag trägt ein Xero-Event mit gefülltem userId und ein Lexware-Office-Event, bei dem beide leer sind, genau wie hier.

Eine vereinheitlichte Nutzlast erfindet keine Daten, die die Quelle nie gesendet hat, und das ist der Sinn eines Common Data Model und der Grund, ein null als Tatsache zu lesen statt als Lücke. Die Mechanik des Abonnements ist auf jedem System derselbe Aufruf, und das ist das Event-Modell.

Und planen Sie zuletzt für fehlgeschlagene Zustellungen. Exact wiederholt eine Benachrichtigung zehnmal mit einer Verzögerung von zwei hoch Versuchsnummer, in Minuten. Der Abstand zwischen dem neunten und dem zehnten Versuch beträgt 1.024 Minuten, und die ganze Leiter spannt sich über 34 Stunden.

Das ist großzügig, und es hat eine zweite Wirkung, für die zu entwerfen sich lohnt: Ein Callback, der den ganzen Vormittag weg war, bekommt danach einen Schwall, und der Schwall muss weiterhin in 60 Aufrufe je Minute passen.

Eine 500, die bedeutet, dass es funktioniert hat

Abonniert ein zweiter Benutzer desselben Kunden eine Ressource, für die es bereits ein Abonnement gibt, antwortet Exact mit 500 und der Meldung Data already exists. Das liest sich wie ein Plattformfehler und ist ein Duplikat, prüfen Sie also die Meldung, bevor Sie jemanden alarmieren.

Nutzlast, Callback-Regeln, das doppelte Abonnement und die Wiederholungsleiter stammen aus Exacts Webhook-Dokumentation, geprüft am 7. August 2026.

Was Sie bekommen

Ein fehlendes Recht antwortet mit 200 und einer leeren Liste

Für diesen Fehlerfall baut man zuerst, denn er sieht nicht wie einer aus. Exacts Tabelle der Antwortcodes sagt es klar: Wenn ein Client ein GET ausführt, aber keine Rechte hat, diese Information abzurufen, wird Status 200 mit einer leeren Liste von Datensätzen zurückgegeben.

Nichts an dieser Antwort trennt sie von einem Kunden, der tatsächlich keine Rechnungen hat. Ein Abgleich, der still nichts zurückgibt, sieht auf jedem Dashboard gesund aus, und der Erste, dem es auffällt, ist der Kunde, Wochen später, mit der Frage, warum seine Daten nie angekommen sind.

Die Absicherung ist billig, und es lohnt sich, sie am ersten Tag einzubauen. Kommt ein Lesezugriff für ein Objekt leer zurück, das gefüllt sein sollte, prüfen Sie mit /api/v1/{division}/system/Divisions, was der Benutzer tatsächlich freigegeben hat, bevor Sie auf eine leere Firma schließen, und zeigen Sie den Unterschied dem Kunden statt Ihrem Protokoll.

Der lautere Verwandte ist 403, und der deckt acht verschiedene Zustände ab. Sie als einen Status zu lesen ist der Weg, auf dem ein Rechteproblem als Ausfall einsortiert wird.

Acht Gründe für einen Statuscode
Was Exact meldetWas es tatsächlich bedeutet
Insufficient user rightsDem verknüpften Benutzer fehlt das Recht innerhalb von Exact Online
Application scope violatedIhre App fragt außerhalb des Umfangs, der in der Daten- und Sicherheitsprüfung vereinbart wurde
Wrong divisionDer verknüpfte Benutzer hat überhaupt keinen Zugang zu dieser Division
User division not within division scopeDer Benutzer hat Zugang, hat ihn aber im Zustimmungsdialog nicht an Ihre App freigegeben
Inactive userDas Konto, das die Verbindung autorisiert hat, trägt ein Enddatum
Division blockedEine Sicherung läuft, oder Exact verschiebt die Division in eine andere Datenbank. Beides ist vorübergehend, und das Zweite setzt außerdem Ihre Sync-Zeitstempel zurück
The division is archivedNichts liest daraus, bis ein Buchhalter sie wieder öffnet
Incompatible EOL functionalityDer Endpunkt gehört nicht zum Paket des Kunden, und darum geht es im nächsten Abschnitt

Alle acht stammen aus Exacts Antwortcodes und Fehlerbehandlung, geprüft am 7. August 2026. Denken Sie daran, dass jeder davon auch gegen die zehn Fehler je Stunde zählt.

Was Sie bekommen

Welche Endpunkte das Paket eines Kunden enthält

Nicht jeder Endpunkt steht jedem Exact-Online-Kunden zur Verfügung. Die Verfügbarkeit folgt dem Paket, das er gekauft hat, und der Fehlschlag ist eine 403 mit dem Text incompatible EOL functionality, die Ihnen nichts darüber sagt, welches Modul fehlt.

Dokumentiert ist es aber, und zwar je Endpunkt statt in einer einzigen Liste. Jede Entitätsseite der Referenz trägt eine Zeile mit dem Wortlaut this endpoint is available for the following packages.

PurchaseOrders etwa ist für Manufacturing in allen Versionen verfügbar, für Professional Services nur in Plus, Professional und Premium und für Wholesale and Distribution in allen Versionen. Prüfen Sie das, während Sie Endpunkte auswählen, und nicht, während Sie bei einem Kunden einen Fehler suchen.

Dasselbe Prinzip fängt einen Fall, den man leicht der Plattform anlastet: mehrere Währungen. Ein Journal in Exact Online hat genau eine Währung, sofern für es nicht die variable Währung eingeschaltet ist, und eine Fremdwährungsbuchung in ein Journal mit einer Währung wird abgelehnt oder falsch gelesen.

Dieser Teil ist real. Von Hand einzurichten ist nicht der einzige Weg: Das Journal gibt beide Eigenschaften über die Schnittstelle heraus, und der Endpunkt für Wechselkurse nimmt auch Schreibzugriffe an.

Das Journal prüfen, bevor Sie eine Fremdwährungsbuchung sendenHTTP
GET /api/v1/{division}/financial/Journals
?$select=Code,Currency,AllowVariableCurrency
→ 200 { "Code": "70", "Currency": "EUR",
"AllowVariableCurrency": false }
 
# dokumentierte Bedeutung: steht AllowVariableCurrency auf false,
# ist Currency die einzige Währung, die dieses Journal annimmt.

Feldnamen und Bedeutung stammen aus der Referenzdokumentation, Entitäten FinancialJournals und FinancialExchangeRates, die beide GET, POST, PUT und DELETE unterstützen.

Lesen Sie es, nehmen Sie es nicht an

Ein GET gegen ein Journal macht aus einer Klasse stiller Buchungsfehler eine Vorbedingung, die Ihr Code benennen kann. Es kostet außerdem einen Aufruf von 5.000, und das ist das Billigste auf dieser Seite.

Wo unser Teil endet

Was bei Ihnen bleibt: Das Budget, die Prüfung und das Fenster

maesn nimmt die Verbindung, die Division, das Token-Fenster und das Abonnement ab. Die Regeln der Plattform sind eine andere Sache, und fünf davon bleiben bei Ihnen, was jetzt zu wissen billiger ist als nach dem ersten Kundengespräch.

  • Das Rate Limit erreicht Sie weiterhin. Nur die asynchronen Endpunkte von maesn fangen Lastspitzen ab. Alles Synchrone reicht die 429 des Zielsystems durch, Backoff für Exact Online bauen Sie also selbst. Was der asynchrone Weg abdeckt und was nicht, steht unter Asynchronous Processing.
  • Steuern berechnet maesn nicht. Wir liefern die Sätze und Strukturen so, wie das System sie veröffentlicht. Was geschuldet ist und auf welcher Grundlage, bleibt Ihr Modell.
  • Die Währungsumrechnung gehört Ihnen. Wir können Ihnen die Währung des Journals vorlesen und ob es andere annimmt. Einen Kurs zu wählen und für ihn einzustehen ist eine Entscheidung auf Ihrer Seite.
  • Die Prüfung im App Store ist Exacts Entscheidung. Sie läuft in drei Stufen, Daten und Sicherheit, Marketing und Funktion, und bis sie durch ist, kann sich nur das Konto authentifizieren, das die App registriert hat. Wir bereiten sie vor und gehen sie als offizieller Exact-Partner mit Ihnen durch, und wir erteilen sie nicht.
  • Das Wartungsfenster gehört in Ihren Scheduler. Exact dokumentiert, dass Exact Online und seine Schnittstellen täglich zwischen 4:00 und 4:30 Uhr Ortszeit nicht erreichbar sind. Ein nächtlicher Lauf, der um vier startet, sieht einmal am Tag wie ein Ausfall aus, solange ihn niemand verschiebt.

Dass Lastspitzen nur asynchron abgefangen werden, stammt vom CTO von maesn, die Stufen der Prüfung und das tägliche Fenster aus Exacts Webhook-Dokumentation, geprüft am 7. August 2026.

Vor all dem brauchen Sie einen Ort, an dem etwas kaputtgehen darf

Exact bietet ein kostenloses regionales Testkonto an, und es ist zugleich der Ort, an dem Ihre App registriert wird. Dazu betreibt maesn Sandboxes für jedes unterstützte System, Exact Online eingeschlossen, auf Anfrage mit Testdaten gefüllt. Keines von beiden verkürzt die Prüfung im App Store, und die ist der Schritt, der entscheidet, wann Sie jemand anderen als sich selbst anbinden können.

FAQ

Häufige Fragen

Wie lauten die Rate Limits von Exact Online?

Sechzig API-Aufrufe je Firma und Minute und 5.000 je Firma und Tag, beides je App gezählt. Wer eines von beiden überschreitet, bekommt 429, und das verbleibende Kontingent steht in den Antwort-Headern. Parallele Aufrufe sind überhaupt nicht erlaubt, das Budget wird also der Reihe nach ausgegeben und nicht in Schüben.

Warum schlägt mein Token-Refresh mit access_token not expired fehl?

Weil er zu früh kam. Ein Access-Token von Exact gilt 600 Sekunden, und ein neues darf erst angefordert werden, wenn seit dem letzten erfolgreichen Token-Aufruf 570 Sekunden vergangen sind. Das lässt ein Fenster von 30 Sekunden. Exact dokumentiert dieselbe Meldung unter 400 und unter 401.

Sendet Exact Online ein Event, wenn ein Datensatz angelegt wird?

Es sendet eine Benachrichtigung, aber keine, die created sagt. Exacts Tutorial hält fest, dass Anlegen, Aktualisieren und Löschen alle eine Benachrichtigung erzeugen und dass die Aktion entweder UPDATE oder DELETE lautet, wobei UPDATE alles abdeckt, was keine vollständige Löschung ist. Ein neuer Datensatz kommt also als Aktualisierung gekennzeichnet an.

Warum gibt eine Exact-Online-Anfrage eine leere Liste zurück?

Es kann ein Rechteproblem sein statt einer leeren Firma. Exact dokumentiert, dass ein GET von einem Client ohne das Recht, diese Information zu lesen, mit 200 und einer leeren Liste von Datensätzen antwortet. Nichts an der Antwort unterscheidet das, prüfen Sie also den freigegebenen Division-Scope und die Rechte des Benutzers.

Welche Exact-Online-Divisionen darf meine App lesen?

Nur die, die der Benutzer im Zustimmungsdialog angehakt hat, und das können weniger sein als die, die er selbst öffnen kann. Eine Division, auf die er keinen Zugang hat, antwortet mit Wrong division, eine, auf die er Zugang hat, die er aber nicht freigegeben hat, mit User division is not within division scope. Zwei Fehler, zwei Ursachen.

Fängt maesn das Rate Limit von Exact Online ab?

Nein. Nur die asynchronen Endpunkte von maesn fangen Lastspitzen ab. Alles Synchrone reicht die 429 des Zielsystems an Sie durch, Backoff für Exact Online bleibt also Ihre Aufgabe.

Gibt es eine Sandbox für Exact Online?

Zwei Wege hinein. Exact bietet ein kostenloses regionales Testkonto an, in dem Sie auch Ihre App registrieren. maesn betreibt Sandboxes für jedes unterstützte System, Exact Online eingeschlossen, auf Anfrage mit Testdaten gefüllt. Keiner der beiden ersetzt die Prüfung im App Store, bevor Sie jemanden anbinden können.

Einmal bauen, auf der Unified API.

Aufrufbudgets, Sync-Cursor, Erneuerungsfenster und Abonnements je Kunde sind auf jedem Buchhaltungssystem dasselbe Problem. Lösen Sie sie einmal mit maesn statt einmal je Plattform.