← Dokumentation / Leitfäden
Migration von einem anderen System
Übertragen Sie die Buchhaltung eines Unternehmens mit einem einzigen Aufruf — Kontenplan, Partner, Anfangsbestände oder vollständige Historie, offene Rechnungen, Anlagevermögen und Lagerbestände.
Wenn ein Unternehmen von einem anderen Buchhaltungsprogramm zu Nordlet wechselt, beginnt seine Buchhaltung nicht bei null. Der Importer für die Buchhaltungshistorie übernimmt alle Daten aus dem alten System und schreibt sie in einem Aufruf, in einer einzigen Datenbanktransaktion: Wenn eine einzige Zeile eine Prüfung nicht besteht, wird nichts gespeichert. Dasselbe Paket kann zunächst über einen reinen Prüf-Endpunkt gesendet werden, der alle Validierungen durchführt und ein Rollback auslöst.
POST /v1/migration/books/validate # checks everything, writes nothing
POST /v1/migration/books/import # writes everything or nothing
Die Web-App verfügt über dieselben zwei Schaltflächen unter Settings → Migration (Fügen Sie die JSON ein oder laden Sie eine Datei hoch). Der API-Schlüssel benötigt ledger:write plus den Write-Scope jedes Abschnitts, den Sie einschließen (partners:write, catalog:write, sales:write, purchases:write, assets:write, inventory:write). Beide Endpunkte akzeptieren Bodys mit einer Größe von bis zu 32 MB.
Der Umstellungsstichtag
Wählen Sie den Umstellungsstichtag (cut-over date): der erste Tag, an dem das Unternehmen in Nordlet geführt wird. Alles davor verbleibt im alten System (oder wird als Historie übernommen, siehe unten); alles ab diesem Tag wird in Nordlet über die normalen Endpunkte eingegeben. Alle Beträge im Paket gelten „mit Stand des Tages vor der Umstellung“: die abschließende Summen- und Saldenliste (SuSa), die noch unbezahlten Rechnungen, der noch im Regal liegende Bestand, die noch im Verzeichnis stehenden Anlagen.
Führen Sie vor dem Import Folgendes in Nordlet durch:
- Erstellen Sie das Unternehmen und wenden Sie die Kontenplan-Vorlage an (
ledger/accounts/apply-template) — oder listen Sie die benötigten Konten im Abschnittaccountsdes Pakets auf. - Erstellen Sie mindestens ein Lager (
inventory/warehouses/create), falls Sie Lagerbestände importieren. - Lassen Sie das Paket durch
migration/books/validatelaufen, bis keine Fehler mehr gemeldet werden und Sie die Warnungen akzeptieren.
Das Paket
Jeder Abschnitt ist optional; fügen Sie die hinzu, die Sie haben. Alle Verweise zwischen den Abschnitten erfolgen über den Code (Kontocode, Partnercode, Artikelcode, Anlagengruppencode, Lagercode), und ein Code kann sich entweder auf einen Datensatz beziehen, der in Nordlet bereits existiert, oder auf einen, der durch einen früheren Abschnitt desselben Pakets erstellt wurde.
{
"cutoverDate": "2026-01-01",
"source": "Rivilė GAMA",
"accounts": [
{ "code": "6210", "name": "Advertising expenses", "type": "expense", "parentCode": "6" }
],
"partners": [
{ "code": "301111222", "name": "UAB Klientas", "vatCode": "LT100001112223", "isCustomer": true },
{ "code": "302222333", "name": "UAB Tiekėjas", "isCustomer": false, "isSupplier": true }
],
"items": [
{ "code": "SKU-1", "name": "Widget", "type": "product", "unit": "vnt", "vatRatePercent": "21" }
],
"assetGroups": [
{ "code": "TRANSP", "name": "Vehicles", "assetAccountCode": "1230", "depreciationAccountCode": "1239",
"defaultUsefulLifeMonths": 60 }
],
"openingBalances": {
"balancingAccountCode": "3410",
"entries": [
{ "accountCode": "2710", "debit": "5000.00" },
{ "accountCode": "2410", "debit": "1500.00" },
{ "accountCode": "2040", "debit": "300.00" },
{ "accountCode": "1230", "debit": "12000.00" },
{ "accountCode": "1239", "credit": "2400.00" },
{ "accountCode": "4430", "credit": "700.00" },
{ "accountCode": "3010", "credit": "10000.00" }
]
},
"openReceivables": [
{ "partnerCode": "301111222", "number": "SF-1050", "issueDate": "2025-12-10", "dueDate": "2026-01-09",
"grossTotal": "1210.00", "vatTotal": "210.00" },
{ "partnerCode": "301111222", "number": "SF-1049", "issueDate": "2025-11-20",
"grossTotal": "500.00", "outstanding": "290.00" }
],
"openPayables": [
{ "partnerCode": "302222333", "documentNumber": "T-77", "documentDate": "2025-12-15", "grossTotal": "700.00" }
],
"fixedAssets": [
{ "groupCode": "TRANSP", "code": "CAR-1", "name": "Delivery van", "acquisitionDate": "2025-01-01",
"acquisitionCost": "12000.00", "accumulatedDepreciation": "2400.00", "depreciatedMonths": 12 }
],
"stock": [
{ "itemCode": "SKU-1", "quantity": "30", "unitCost": "10" }
]
}
Beträge sind dezimale Zeichenketten, wie überall in der API. source ist ein freies Textfeld, das in der Beschreibung der Eröffnungsbilanz-Transaktion und in den Notizen der migrierten Rechnungen landet.
accounts
Kontenplan-Zeilen: code, name, type (asset, liability, equity, income, expense), optional parentCode und isPostable. Bereits existierende Codes bleiben unangetastet und werden als existing gezählt. Nutzen Sie dies, wenn der Kontenplan des alten Systems von der Vorlage abweicht, oder überspringen Sie diesen Schritt und wenden Sie zuerst die Vorlage an.
partners und items
Kunden, Lieferanten und Katalogartikel, referenziert nach code. In Litauen ist der Partnercode normalerweise die Unternehmensregisternummer; für Privatpersonen verwenden Sie einen beliebigen Code, der innerhalb des Unternehmens eindeutig ist. Vorhandene Codes werden übersprungen und nicht aktualisiert. Artikel akzeptieren type (product oder service), unit, barcode, vatRatePercent, salePriceExclVat, purchasePriceExclVat.
openingBalances
Die abschließende Summen- und Saldenliste des alten Systems, eine Zeile pro Konto: accountCode mit entweder debit (Soll) oder credit (Haben). Die Zeilen werden als eine Journalbuchung mit dem Datum openingBalances.date (standardmäßig der Umstellungsstichtag) und der Belegart migration_opening gebucht. Die Zeilen müssen auf bebuchbare Konten (postable accounts) verweisen.
Die Buchung muss ausgeglichen sein (saldieren). Wenn die Summen- und Saldenliste des alten Systems nicht ausgeglichen ist — aufgrund von Rundungsdifferenzen, einem Gewinn, der nie ins Eigenkapital abgeschlossen wurde, oder einem fehlenden Konto — geben Sie balancingAccountCode an (typischerweise der Gewinnvortrag, 3410 in der litauischen Vorlage) und die Differenz wird dorthin gebucht; die API-Antwort gibt den Betrag als balancingAmount an.
Pro Unternehmen darf nur eine Eröffnungsbilanzbuchung existieren. Ein zweiter Import mit openingBalances wird abgelehnt (409). Nachträgliche Korrekturen sind gewöhnliche manuelle Journalbuchungen (ledger/journal/transactions/create); verbuchte Transaktionen sind unveränderlich, das Original bleibt also wie importiert bestehen.
journal — vollständige Historie anstelle von, oder zusätzlich zu, Salden
Wenn Sie die Transaktionen des alten Systems in Nordlet haben möchten (damit Berichte für frühere Perioden funktionieren), senden Sie diese hier: ein Objekt pro Transaktion mit date, optionalem description und reference sowie entries bestehend aus accountCode + debit/credit. Jede Transaktion muss in sich ausgeglichen sein. Sie werden mit der Belegart migration gebucht.
Die Daten (Datum) müssen vor dem Umstellungsstichtag liegen. Wenn das Paket auch openingBalances enthält, muss die Historie auf oder nach openingBalances.date datiert sein — das übliche Vorgehen sind Salden zu Beginn des vorangegangenen Geschäftsjahres zuzüglich der Transaktionen dieses Jahres, wobei die Umstellung auf den ersten Tag des aktuellen Jahres fällt. Senden Sie nicht Salden und Historie für dieselbe Periode: Die Salden würden andernfalls doppelt gezählt.
Jeder Monat, der von den Anfangsbeständen oder der Historie berührt wird, muss eine offene Buchungsperiode sein (andernfalls Fehler 409).
openReceivables und openPayables
Rechnungen, die zum Umstellungsstichtag noch (ganz oder teilweise) unbezahlt waren. Sie werden als ausgestellte Ausgangsrechnungen und erfasste Eingangsrechnungen mit paidAmount = grossTotal − outstanding angelegt, sodass der Bankabgleich (bank/transactions/match, bank/transactions/suggest-matches), die Offene-Posten-Liste (Fälligkeitsstruktur) und Zahlungs-Webhooks für sie genauso funktionieren wie für jede andere Rechnung.
outstandingist standardmäßig dergrossTotal;vatTotalist standardmäßig0(der Nettobetrag wird abgeleitet).dueDateist standardmäßig das Belegdatum.currencyist standardmäßig die Rechnungswährung des Unternehmens. Für jede Nicht-EUR-Währung istfxRate(Wechselkurs) erforderlich — Einheiten dieser Währung pro 1 EUR, dieselbe Konvention wie in der restlichen API — und dieser wird in der Rechnung gespeichert, damit spätere Zahlungen die realisierte Wechselkursdifferenz korrekt berechnen.- Bei Ausgangsrechnungen ist die
numberdie vollständige Nummer aus dem alten System und muss im Unternehmen eindeutig sein. Eingangsrechnungen sind eindeutig pro Partner unddocumentNumber. - Die Rechnungen werden nicht erneut gebucht: Ihr offener Forderungs-/Verbindlichkeitssaldo ist bereits Teil der Anfangsbestände. Sie sind mit der Eröffnungsbilanzbuchung verknüpft, weshalb
openPayablesdas Vorhandensein vonopeningBalancesim selben Paket erfordert. - Rechnungszeilen werden nicht importiert; die Rechnung enthält nur die Gesamtbeträge. Das alte System bleibt das führende System für die Zeilendetails und für die Umsatzsteuer-Register der Zeiträume vor der Umstellung.
Wenn das alte System Kundensalden ohne offene Posten führte, erstellen Sie eine Rechnung pro Partner für den Saldo (zum Beispiel Nummer OB-301111222), damit dieser beglichen werden kann.
Die Nummernkreise werden fortgesetzt. Wenn eine importierte Ausgangsrechnungsnummer das Format PREFIX-N hat und ihr Ausstellungsdatum in das Jahr der Umstellung fällt, wird der Nummernkreis für diesen Präfix und dieses Jahr auf N + 1 gesetzt (niemals verringert). Die API-Antwort listet die resultierenden numberSeries auf; in anderen Fällen richten Sie den Nummernkreis selbst mit reference/series/create ein ({ documentType: "sale_invoice", prefix, year, startAt }).
assetGroups und fixedAssets
Anlagegüter werden mit ihrer bisherigen Abschreibung übernommen: acquisitionCost, salvageValue, accumulatedDepreciation, depreciatedMonths und usefulLifeMonths (oder dem Standardwert der Gruppe). Der Lauf für die lineare Abschreibung (assets/depreciation/post) wird ausgehend vom Restwert über die verbleibenden Monate fortgesetzt. Anlagegüter, deren kumulierte Abschreibung bereits dem abschreibungsfähigen Wert entspricht, werden als fully_depreciated erstellt. Es wird nichts gebucht — die Anschaffungskosten und die kumulierte Abschreibung sind Teil der Anfangsbestände.
Gruppen werden über den code referenziert und benötigen assetAccountCode und depreciationAccountCode (Standard-Aufwandskonto 6206).
stock
Lagerbestand pro Artikel: itemCode, quantity, unitCost (Kosten pro Einheit in EUR) und optional warehouseCode (Standard: das Standardlager), lotNumber und expiryDate für chargen- oder seriennummerngeführte Artikel. Jede Zeile wird zu einer Lagereingangsbewegung, datiert auf den Umstellungsstichtag mit der Belegart migration, und startet eine FIFO-Schicht zu diesen Kosten. Es wird nichts gebucht — der Lagerwert ist Teil der Anfangsbestände.
Prüfungen und Warnungen
Der Validierungs-Endpunkt schlägt fehl (422) bei fehlenden Konten, nicht bebuchbaren Konten, nicht ausgeglichenen Buchungen, unbekannten Partner-/Artikel-/Gruppen-/Lagercodes, doppelten Codes oder Nummern innerhalb des Pakets, offenen Beträgen, die über dem Bruttobetrag liegen, kumulierten Abschreibungen, die über dem abschreibungsfähigen Wert liegen, sowie fehlenden Wechselkursen. Nummern oder Codes, die in Nordlet bereits existieren, führen zu Fehler 409.
Darüber hinaus vergleichen beide Endpunkte die Nebenbücher (sub-ledgers) mit den Hauptbucheinträgen im selben Paket und geben die Differenzen als warnings anstatt als Fehler zurück:
- gesamte offene Beträge der
openReceivablesgegenüber dem Saldo auf dem Forderungskonto (sales.receivableBuchungsregel, standardmäßig2410); - gesamte offene Beträge der
openPayablesgegenüber dem Verbindlichkeitenkonto (purchases.payables,4430); - Gesamtkosten von
stockgegenüber dem Bestandskonto (inventory.stock,2040); - pro Anlagengruppe, die Anschaffungskosten der Anlagen gegenüber dem Anlagekonto der Gruppe und deren kumulierte Abschreibung gegenüber dem Abschreibungskonto.
Eine Warnung bedeutet, dass das Nebenbuch und das Hauptbuch (general ledger) des alten Systems nicht übereinstimmen. Korrigieren Sie das Paket (oder akzeptieren Sie die Differenz wissentlich) vor dem Importieren.
Die Antwort
{
"dryRun": false,
"cutoverDate": "2026-01-01",
"accounts": { "created": 1, "existing": 0 },
"partners": { "created": 2, "existing": 0 },
"items": { "created": 1, "existing": 0 },
"assetGroups": { "created": 1, "existing": 0 },
"openingBalances": { "journalTransactionId": "…", "date": "2026-01-01", "entries": 8,
"debitTotal": "18800.00", "creditTotal": "18800.00", "balancingAmount": "5700.00" },
"journal": { "transactions": 0, "entries": 0 },
"openReceivables": { "created": 2, "outstandingTotal": "1500.00" },
"openPayables": { "created": 1, "outstandingTotal": "700.00" },
"fixedAssets": { "created": 1, "costTotal": "12000.00", "accumulatedDepreciationTotal": "2400.00" },
"stock": { "movements": 1, "costTotal": "300.00" },
"numberSeries": [],
"warnings": []
}
dryRun: true kennzeichnet einen Validierungsdurchlauf; dort ist journalTransactionId gleich null. Ein Import wird im Audit-Protokoll als migration.imported mit derselben Zusammenfassung aufgezeichnet.
Nach dem Import
- Sperren Sie die Perioden vor dem Umstellungsstichtag (
ledger/periods/lock), damit nicht versehentlich in die migrierte Historie gebucht wird. - Vergleichen Sie die Summen- und Saldenliste sowie die Bilanz zum Umstellungsstichtag mit den Abschlussberichten des alten Systems.
- Fahren Sie mit dem normalen Ablauf fort: Schreiben Sie Rechnungen, importieren Sie Kontoauszüge, gleichen Sie Zahlungen ab — die migrierten offenen Rechnungen werden wie alle anderen Rechnungen ausgeglichen.
Was der Importer nicht abdeckt: Rechnungszeilen und Umsatzsteuer-Register vergangener Perioden (bewahren Sie diese im alten System oder in dessen Archiv auf), Historie der Lohnbuchhaltung sowie andere Belege als Rechnungen (Bestellungen, Frachtbriefe, Verträge).