maesn
Für Entwickler

Sage Active anbinden: Elf Objekte lesen, und Korrekturen entstehen als neue Belege

Sage Active beantwortet elf Objekte und nimmt fünf zurück. Ein gebuchter Beleg bleibt so stehen, wie er geschrieben wurde, wie in einem Hauptbuch, deshalb entsteht eine Korrektur als neuer Beleg statt als Änderung. Das ist die eine Entwurfsentscheidung, die früh fällt, und dieser Leitfaden behandelt sie neben dem Token, der Firmenangabe und dem Cursor.

Lennart Svensson, CTO und Mitgründer bei Maesn
Lennart Svensson
CTO und Mitgründer · · Aktualisiert
Illustration zu Sage Active anbinden: Gebuchte Belege korrigieren
Der Kontext

Ein Endpunkt, eine Firmenangabe, drei Länder

Drei strukturelle Eigenschaften entscheiden den Zuschnitt dieser Anbindung, und keine davon betrifft einen Feldnamen.

Die erste: alles läuft über einen Endpunkt. Sage Active spricht GraphQL, also Queries zum Lesen, Mutations zum Schreiben und eine Antwort in der Form, die Sie angefragt haben. Dazu gilt ein Komplexitätslimit, und Queries darüber werden abgewiesen, tief verschachtelte Daten müssen also manchmal auf mehrere Anfragen verteilt werden.

Die zweite: ein Token benennt keine Firma. Nach der Authentifizierung haben Sie Zugriff und müssen trotzdem bei jedem Aufruf sagen, wessen Bücher Sie meinen. Dieser Wert wird nach Abschluss des Ablaufs geholt und vom Nutzer gewählt, er ist damit ein Schritt nach der Verbindung in Ihrem Onboarding und keine Angabe, die Sie fest eintragen können.

Die dritte: Frankreich, Spanien und Deutschland sind drei eigene Zielsysteme und nicht ein System mit einer Ländereinstellung. Die Anwendung, die Sie in Sage Active registrieren, trägt einen Ländertyp und eine eigene Callback-URL, alle drei Märkte zu bedienen heisst also drei Registrierungen.

Verschiedene Sage-Produkte teilen keine Schnittstelle
Sage verkauft mehrere Buchhaltungsprodukte, und was Sie über eines lesen, gilt selten für ein anderes. Sage Active ist 2023 für diese drei Märkte erschienen und spricht GraphQL. Token, Header und Endpunkte, die für ein anderes Sage-Produkt dokumentiert sind, sind die Dokumentation eines anderen Systems.
So funktioniert es

Token für acht Stunden und der Refresh-Scope

Auf Seiten von Sage Active: die Authentifizierung läuft über OAuth 2.0, und das Access-Token lebt acht Stunden. Ein Refresh-Token wird nur ausgestellt, wenn die erste Autorisierung den Scope offline_access angefragt hat. Fragen Sie ihn an, dann läuft eine unbeaufsichtigte Anbindung über die acht Stunden hinaus weiter, ohne dass sich jemand erneut anmeldet.

Zwei weitere Scopes teilen den Zugriff selbst auf, einer zum Lesen und einer zum Schreiben. Nur anzufragen, was Sie brauchen, ist die gewöhnliche Sorgfalt, und hier belegt es zusätzlich Ihre Absicht gegenüber dem Kunden, genau in dem Moment, in dem er die Verbindung bestätigt.

Die Firmenangabe greift dabei an einer Stelle ein, die man kennen sollte. Die Endpunkt-Referenz hält fest: wer den interaktiven Authentifizierungsablauf nicht nutzt, muss den Query-Parameter companyId auf seinen Aufrufen füllen und holt den Wert nach dem Verbinden über einen Companies-Endpunkt. Mit diesem Ablauf fällt die Wahl stattdessen einmal während der Verbindung.

Alle drei Länder-Zielsysteme fahren diesen interaktiven Ablauf über maesn, und deshalb ist Unified Authentication der Unterschied zwischen einem Wahlschritt beim Verbinden und einer Angabe, die Ihr Request-Builder bei jedem Aufruf für jeden Mandanten richtig setzen muss.

Laufzeit des Tokens, der Refresh-Scope sowie die Lese- und Schreib-Scopes sind in maesns Material zu diesem System dokumentiert; die Bedingung zu companyId ist aus der Referenz zur Summen- und Saldenliste zitiert und der Ablauf selbst aus der Anleitung zur Authentifizierung, beide geprüft am 13. August 2026.

So funktioniert es

Elf Objekte, gelesen über einen Cursor

Auf Seiten von Sage Active: elf Objekttypen kommen zurück, und die Liste reicht weiter, als es eine Buchhaltungs-API sonst tut. Sie trägt Aufträge, Angebote und deren Positionen neben dem Hauptbuch, die Auftragsseite und die Bücher beantwortet also dieselbe Verbindung.

Wie Sie diese Daten durchlaufen, ist eine GraphQL-Konvention. Die Paginierung läuft über einen Cursor: Sie fragen eine Anzahl von Einträgen an, die Antwort trägt einen Cursor und ein Kennzeichen, ob es weitergeht, und Sie geben den Cursor zurück, um fortzufahren. Eine Seitenzahl gibt es nicht, springen können Sie also nicht.

Für einen ersten Import ändert das den Fehlerfall. Eine Synchronisation, die auf halbem Weg abbricht, kann nicht mit Seite sieben weitermachen, sie setzt an dem Cursor an, den sie gespeichert hat, das Speichern dieses Cursors wird damit Teil des Entwurfs und ist keine Optimierung. Ein Weg, zu filtern und zu paginieren macht daraus wieder dieselbe Seite und dasselbe Limit, die Sie bei Systemen benutzen, die nie von einem Cursor gehört haben.

Cursor-Paginierung, in der Form, in der das System sie zurückgibtGraphQL
query {
invoices(first: 50, after: "<endCursor>") {
pageInfo { endCursor hasNextPage }
nodes { id number totalAmount }
}
}

hasNextPage ist die Schleifenbedingung und endCursor das Lesezeichen. Keines von beiden ist eine Position, und deshalb speichert eine wiederaufsetzbare Synchronisation den Cursor.

Das Problem

Wie eine Korrektur nach Sage Active gelangt

Auf Seiten von Sage Active: fünf Objekttypen lassen sich anlegen, und ein gebuchter Beleg bleibt so stehen, wie er geschrieben wurde. Einen Änderungs- und einen Löschaufruf gibt es dafür nicht.

Das ist das Modell eines Hauptbuchs und nicht das einer Datenbank, und so behandeln Buchhaltungssysteme einen gebuchten Beleg gewöhnlich: der Nachweis dessen, was gebucht wurde, muss erhalten bleiben, eine Korrektur wird also daneben ausgestellt statt darüber geschrieben. Planen Sie den Korrekturweg vor dem ersten Schreibzugriff, kostet er nichts; entdecken Sie ihn danach, ist er ein Umbau Ihrer Schreiblogik.

Objekttypen nach OperationSage Active
Lesen
11 Objekte
Das Hauptbuch, die Auftragsseite und die Summen- und Saldenliste, in einer Verbindung.
Anlegen
5 Objekte
Konten, Kunden, Rechnungen, Artikel und Lieferanten.
Ändern
0 Objekte
Ein gebuchter Beleg bleibt stehen, schicken Sie also eine Korrektur.
Löschen
0 Objekte
Das Hauptbuch behält seine Historie, wie auf Papier.

Eine tiefe Leseseite verdeckt eine schmale Schreibseite. Elf Objekttypen antworten hier und fünf nehmen einen Schreibzugriff an, die Fläche liest sich also wie eine Datenbank, bis zur ersten Korrektur, und genau deshalb fällt die Grenze spät auf.

Was Sage Active beantwortet und was es zurücknimmt, je Objekttyp. Geprüft am 13. August 2026.
Wo die wichtigsten Objekte stehen, Lesen gegen Schreiben
ObjektLesenAnlegen
Rechnungenjaja
Kundenjaja
Lieferantenjaja
Kontenjaja
Artikeljaja
Buchungssätzejaauf Anfrage
Summen- und Saldenlistejanein
Aufträgejanein
Angebotejanein

Aus den erzeugten Coverage-Daten gezählt, geprüft am 13. August 2026. Buchungssätze sind lesbar und ihr Anlegen ist als auf Anfrage vermerkt, was zu wissen lohnt, bevor ein Buchungsablauf darauf aufgebaut wird.

Auf dem Schreibweg steht eine zweite Anforderung, die Aufrufe kostet. Referenzfelder nehmen keine lesbaren Werte an: eine Mengeneinheit muss als interne Kennung angegeben werden, die das System dafür führt, nicht als Wort. Diese Kennungen sind zwischen Mandanten nicht gleich, der Abruf und der Zwischenspeicher liegen also je Kunde.

Genau diese Schicht nimmt das Common Data Model heraus. Sie senden einen lesbaren Wert, die Auflösung geschieht hinter der Verbindung, und derselbe Schreibzugriff sieht aus wie bei einem System, das das Wort von vornherein angenommen hätte.

Ein Referenzfeld will eine Kennung, kein WortJSON
{ "unitOfMeasurementId": "KILOGRAM" } // abgewiesen
 
{ "unitOfMeasurementId": 14 } // aufgelöst
// die Kennung gilt je Mandant, die Zuordnung
// wird also je Kunde geholt und zwischengespeichert

Dasselbe Muster gilt für weitere Referenzdaten, ein Schreibweg braucht seine Abrufe also gewöhnlich warm, bevor der erste Aufruf läuft.

Das Problem

Was die Summen- und Saldenliste zuerst braucht

Auf Seiten von Sage Active: eine Summen- und Saldenliste gibt es als fertigen Bericht, und das lohnt zu wissen, weil die meisten Buchhaltungs-APIs sie aus Buchungssätzen zusammensetzen lassen. Davor steht ein Parameter, der sich beim Entwurf leichter behandeln lässt als zur Laufzeit.

Der Endpunkt verlangt den Beginn des Geschäftsjahres. Die Referenz ist eindeutig: „Der Query-Parameter fiscalYearStartDate ist erforderlich und muss ein gültiges Datum sein.“ So weit gewöhnlich, bis Sie suchen, woher dieses Datum kommt.

Geschäftsjahre sind auf diesem System kein lesbares Objekt. Weder auf Anfrage noch hinter einem Schalter: die Coverage-Zelle ist ein schlichtes Nein. Der Bericht verlangt damit einen Wert, den dasselbe System nicht herausgibt, und es bleiben nur Ihre eigene Konfiguration, Ihr Kunde oder eine Vereinbarung, die Sie einmal treffen und hinterlegen.

Ein Bericht, eine fehlende EingabeAn beiden Enden geprüft
Summen- und SaldenlisteLesbar

Sage Active gibt den Saldenstand als Bericht zurück, er muss also nicht aus Buchungssätzen zusammengesetzt werden.

fiscalYearStartDateErforderlich

Die Referenz hält fest, dass der Parameter erforderlich ist und ein gültiges Datum sein muss.

GeschäftsjahreNicht lesbar

Ein klares Nein statt auf Anfrage, das Datum lässt sich also nicht aus demselben System abrufen.

Das Datum muss von woanders kommen. Aus Ihrer eigenen Konfiguration, von Ihrem Kunden oder aus einer Vereinbarung, die Sie einmal treffen. Es ist eine kleine Einrichtung, die zu einem Support-Ticket wird, wenn niemand sie einplant.

Ein Bericht, ein Pflichtparameter und die Herkunft des Werts. Beide Enden an der Quelle geprüft.

Die Anforderung ist aus dem Sage-Active-Reiter der Referenz zur Summen- und Saldenliste zitiert, geprüft am 13. August 2026; die fehlende Verfügbarkeit stammt aus den erzeugten Coverage-Daten, wo die Zelle no lautet statt auf Anfrage. Beide wurden getrennt an der Quelle geprüft.

Fragen Sie das Geschäftsjahr beim Onboarding ab
Es ist ein Feld, und es einzusammeln, während ohnehin ein Mensch die Verbindung einrichtet, ist billiger, als es zu entdecken, wenn der erste Berichtsaufruf einen Fehler zurückgibt.
So funktioniert es

Aktualität läuft über einen Zeitplan

Kein Objekt trägt hier ein freigeschaltetes Event. Es gibt kein Abonnement anzulegen, keinen Callback zu prüfen und keine Zustellsemantik zu bedenken, Daten aktuell zu halten ist also ein geplanter Lesezugriff, und damit hat es sich.

Im Event-Modell ist das die Pull-Hälfte, die die ganze Arbeit macht. Sie hat eine Eigenschaft, die zu diesem System besonders passt: ein Pull holt auf. Weil der Durchlauf hier über einen Cursor läuft und wiederaufsetzbar ist, macht ein Worker, der einen Tag ausgefallen war, dort weiter, wo er stehen geblieben ist.

Was das kostet, ist Ihre Wahl des Intervalls, und auf einem System, das nichts ändern kann, fällt die Rechnung einfacher aus als sonst: was Sie einmal gelesen haben, ändert sich nicht mehr an Ort und Stelle. Neue Belege kommen hinzu, und ablösende stehen daneben.

Wie die Objektabdeckung vollständig aussieht, einschliesslich der als auf Anfrage vermerkten Kombinationen, steht auf der Seite Sage Active Schnittstelle.

Auf Anfrage ist kein Liefertermin
Vierundzwanzig Objekte tragen hier in der Webhook-Spalte den Vermerk auf Anfrage, und das Anlegen von Buchungssätzen trägt ihn ebenfalls. Der Vermerk heisst technisch machbar und noch nicht gebaut, er ist keine Zusage, und in genau dieser Spalte ist er am wenigsten verlässlich. Entwerfen Sie gegen das, was heute freigeschaltet ist, und sagen Sie uns, was Sie brauchen.
Wo unser Teil endet

Was maesn abdeckt, und was bei Ihnen bleibt

Was wir Ihnen abnehmen:

  • Die Abfragesprache. Queries, Mutations, die Konventionen des Frameworks und das Komplexitätslimit bleiben hinter der Verbindung, und Ihre Seite macht gewöhnliche REST-Aufrufe.
  • Die Wahl der Firma. Der interaktive Ablauf sammelt sie einmal ein, und die Kennung wird bei jedem späteren Aufruf mitgegeben, ohne dass Ihr Request-Builder davon weiss.
  • Den Cursor und die Kennungen. Aus dem Cursor-Durchlauf werden Seite und Limit, und Referenzfelder nehmen lesbare Werte statt Zahlen je Mandant.

Was bei Ihnen bleibt, und das erste davon ist eine Produktentscheidung und keine Aufgabe:

  • Was eine Korrektur in Ihrem Modell bedeutet. Ohne Ändern und ohne Löschen ist das Ablösen eines Belegs ein Begriff, den Ihr Produkt tragen muss. Wir können den Schreibzugriff so aussehen lassen wie bei jedem anderen System; änderbar machen können wir dieses hier nicht.
  • Der Beginn des Geschäftsjahres. Der Bericht braucht ihn und das System gibt ihn nicht her, er kommt also aus Ihrer Konfiguration oder von Ihrem Kunden.
  • Drei Registrierungen für drei Märkte. Jedes Land ist eine eigene Anwendung mit eigenem Callback, und das einzurichten ist Ihre Sache.
FAQ

Häufige Fragen

Ist Sage Active dasselbe wie Sage Accounting oder Sage 100?

Nein. Sage verkauft mehrere Buchhaltungsprodukte, und sie teilen keine Schnittstelle. Sage Active ist 2023 für Frankreich, Spanien und Deutschland erschienen und spricht GraphQL. Was Sie über Token, Header oder Endpunkte eines anderen Sage-Produkts lesen, gilt für dieses nicht.

Kann ich einen Datensatz in Sage Active ändern?

Heute über kein Objekt. Elf Objekttypen sind lesbar und fünf lassen sich anlegen, Ändern und Löschen stehen durchgehend nicht zur Verfügung. In der Praxis wird aus einer Korrektur ein neuer Beleg, Ihr Modell muss also mitführen, welcher Datensatz welchen ablöst.

Warum scheitert der Aufruf der Summen- und Saldenliste ohne Datum des Geschäftsjahres?

Weil der Parameter verpflichtend ist. Die Referenz hält fest, dass fiscalYearStartDate erforderlich ist und ein gültiges Datum sein muss. Dahinter steht, dass Geschäftsjahre hier kein lesbares Objekt sind, das Datum muss also aus Ihrer eigenen Konfiguration kommen und nicht aus einem Abruf.

Wie lange lebt ein Token von Sage Active?

Acht Stunden, und ein Refresh-Token wird nur ausgestellt, wenn die erste Autorisierung den Scope offline_access angefragt hat. Ohne ihn steht eine Anbindung still, bis sich jemand erneut anmeldet, und deshalb ist dieser Scope für alles Unbeaufsichtigte praktisch verpflichtend.

Warum braucht jeder Aufruf eine Firmenkennung?

Weil das Token allein nicht sagt, wessen Bücher Sie lesen. Die Firma muss nach der Authentifizierung gewählt und dann bei jedem Aufruf mitgegeben werden. Über den interaktiven Ablauf von maesn fällt diese Wahl einmal beim Verbinden, und der Wert wird für Sie mitgegeben.

Kann ich zu einer bestimmten Seite der Sage-Active-Ergebnisse springen?

Nein. Die Paginierung läuft über einen Cursor, Sie fragen also eine Anzahl von Einträgen an und folgen dem zurückgegebenen Cursor zum nächsten Satz. Eine Stelle tief im Datenbestand zu erreichen heisst, alles davor zu durchlaufen, und das macht eine wiederaufsetzbare Synchronisation wertvoller als einen wahlfreien Zugriff.

Einmal bauen, auf der Unified API.

Sage Active ändert nichts, Fortnox deckelt bei 25 Anfragen alle fünf Sekunden, und SnelStart prüft, bevor es einen Produktivschlüssel ausgibt. Bauen Sie gegen eine Schnittstelle, und jedes davon wird eine Zeile in einer Tabelle statt eines Projekts.