Mit der KRONENWERK-Rechnungs-API kann Ihre Software mit POST /invoices/drafts einen Rechnungsentwurf für einen Kunden anlegen, mit GET /invoices und GET /invoices/{number} ausgestellte Rechnungen lesen und über die Webhooks invoice.issued, invoice.paid und invoice.cancelled von Ausstellung, Zahlung und Stornierung erfahren. Die Ausstellung selbst wird nicht freigegeben: Die Nummer, die steuerliche Beurteilung, die VIES-Prüfung und die validierte strukturierte Datei entstehen, wenn eine Person den Entwurf im Produkt ausstellt.
Was die Rechnungs-API tut und was nicht
Sie legt Entwürfe an und liest das Archiv. Ein Entwurf ist ein Arbeitsdokument: Er kann korrigiert, neu bepreist oder verworfen werden, und niemand außerhalb des Unternehmens hat ihn gesehen. Eine ausgestellte Rechnung ist das Gegenteil: Eine Nummer aus einer lückenlosen Folge wurde verbraucht, eine Archivzeile wurde eingefroren, eine Datei wurde erzeugt, die einen nationalen Standard erfüllt, und in Polen wurde das Dokument möglicherweise einem staatlichen System übergeben, das entscheidet, ob es rechtlich existiert. Die API gibt Ihnen das Erste und liest das Zweite nur.
| Vorgang | Über die API | Wo es geschieht |
|---|---|---|
| Kunden anlegen | POST /customers | API oder Produkt |
| Rechnungsentwurf anlegen | POST /invoices/drafts | API oder Produkt |
| Positionen hinzufügen, Preise setzen, Lieferdatum wählen | nicht freigegeben | Produkt |
| Ausstellen: Nummer, steuerliche Beurteilung, VIES-Prüfung, strukturierte Datei, Validierung | nicht freigegeben | Produkt; gemeldet durch invoice.issued |
| Zahlung erfassen | nicht freigegeben | Produkt (manuell, Bankimport); gemeldet durch invoice.paid und payment.recorded |
| Stornieren durch vollständige Korrektur | nicht freigegeben | Produkt; gemeldet durch invoice.cancelled |
| Ausgestellte Rechnungen lesen | GET /invoices, GET /invoices/{number} | API |
| Offene Posten von heute lesen | GET /reports/outstanding | API |
Die vollständige Endpunktliste, die Authentifizierung und das Fehlerformat stehen auf der Seite zur Buchhaltungs-API und in der Referenz.
Einen Entwurf anlegen: POST /invoices/drafts
Die Anfrage nennt einen Kunden und sonst nichts. Zurück kommt ein Entwurf, der so vorbereitet ist, wie das Produkt ihn vorbereitet: der Nummerierungsvorschlag des Verkäufers, das Fälligkeitsdatum aus den mit dem Kunden vereinbarten Zahlungstagen und der Zahlungssatz der Rechtsordnung des Verkäufers in der Sprache, in der diese Rechtsordnung Dokumente schreibt. Jede dieser Entscheidungen gehört einem Ländermodul; ein Anfragefeld dafür würde einem Aufrufer erlauben, die Regeln eines Landes, das er nicht gelesen hat, stillschweigend zu übergehen.
Drei Scopes sind erforderlich — invoices:write, customers:read und companies:read —, weil der Entwurf aus einem Kunden und für eine juristische Person gebaut wird, deren Nummerierung, Zahlungstage und Rechtsordnung bestimmen, was das Dokument sagt. Der Header Idempotency-Key ist erforderlich.
curl -X POST https://kronenwerk.org/api/extern/v1/invoices/drafts \
-H "Authorization: Bearer greif_live_…" \
-H "Idempotency-Key: contract-7731-invoice-1" \
-H "Content-Type: application/json" \
-d '{ "customerId": "3f2b…" }'
{
"id": "e41a…",
"number": "2026-0042",
"documentType": "INVOICE",
"customerId": "3f2b…",
"customer": "Beispiel GmbH",
"currency": "EUR",
"issuedOn": "2026-09-03",
"dueOn": "2026-09-17",
"state": "DRAFT",
"createdAt": "2026-09-03T08:16:05Z"
}
number ist ein Vorschlag in dem Format, das das Ländermodul des Verkäufers für rechtmäßig hält, mit dem Präfix des Unternehmens, falls eines konfiguriert ist; endgültig wird er erst bei der Ausstellung. state ist auf dieser Oberfläche immer DRAFT. Eine customerId, die nicht existiert oder zu einem anderen Unternehmen gehört, antwortet mit 404 NICHT_GEFUNDEN — eine Antwort für beides, damit Statuscodes nicht genutzt werden können, um fremde Kennungen aufzuzählen. Eine Wiederholung mit demselben Idempotency-Key liefert denselben Entwurf; eine Wiederholung mit anderem Body antwortet mit 409 IDEMPOTENZ_KONFLIKT. Siehe Idempotenz.
Nach dem Aufruf erscheint der Entwurf in der Rechnungsliste des Produkts, wo eine Person Positionen hinzufügt, die USt-IdNr. des Kunden prüft und ihn ausstellt. Ihre Integration erfährt vom Ergebnis über den Webhook, nicht durch Polling.
Warum die Ausstellung im Produkt bleibt
Weil die Ausstellung der Moment ist, in dem drei Entscheidungen dauerhaft werden, und jede davon gegen Fakten geprüft wird, die der API-Aufrufer nicht hat.
Validierung der strukturierten Datei
Bei der Ausstellung erzeugt KRONENWERK die strukturierte E-Rechnung, die das Land des Verkäufers erwartet — XRechnung oder ZUGFeRD in Deutschland, Factur-X in Frankreich, Peppol BIS Billing 3.0 UBL in Belgien, FA(3)-XML in Polen — und validiert sie, bevor die Nummer verbraucht wird. Ein deutsches Dokument wird gegen die KoSIT-Schematron-Regeln geprüft und mit der Mustang-Bibliothek gegengeprüft. Ein Entwurf, der die Validierung nicht besteht, wird nicht ausgestellt; die Person sieht, welche Regel verletzt wurde. Eine API, die direkt ausstellt, müsste diese Prüfung entweder überspringen oder einen Fehlerkanal für ein Dokument erfinden, das ihr Aufrufer nie gesehen hat. Siehe die Seite zur E-Rechnungs-API.
Die steuerliche Beurteilung
Jede Rechnung erhält aus den Fakten des Geschäftsvorfalls eine steuerliche Beurteilung — Land von Verkäufer und Käufer, Unternehmen oder Verbraucher, Art der Leistung: Regelbesteuerung, Nullsatz, steuerfrei, Reverse Charge, nicht steuerbar oder „Eingabe erforderlich“ / „erfordert fachliche Bestätigung“. Die USt-IdNr. des Käufers wird bei der Ausstellung gegen VIES geprüft, und die Beurteilung wird mit der Rechnung gespeichert. Wo die Fakten nicht entscheiden, sagt das Produkt das und fragt eine Person; es rät nicht, und ein Skript sollte das auch nicht.
Nummerierung
Rechnungsnummern stammen aus einer lückenlosen Folge, und eine verbrauchte Nummer kann nicht zurückgenommen werden; das Mittel gegen eine falsche Rechnung ist ein Korrekturdokument, keine Löschung. Eine Schleife, die zweimal lief, darf nicht zwei Nummern verbrauchen können, weshalb die API beim Entwurf haltmacht und jeder Schreibzugriff, den sie anbietet, idempotent ist.
Ausgestellte Rechnungen lesen: GET /invoices
GET /invoices liefert ausgestellte Rechnungen, neueste zuerst, seitenweise, mit den bei der Ausstellung eingefrorenen Zahlen — ein letzte Woche umbenannter Kunde ändert nicht den Namen auf einer im Vorjahr ausgestellten Rechnung. Filter sind status (OPEN oder PAID; ein unlesbarer Wert bedeutet kein Filter), from und to (ISO-Ausstellungsdaten), page und size (Standard 25, maximal 100). GET /invoices/{number} liest eine Rechnung über die Nummer, unter der das Unternehmen und sein Kunde sie beide kennen.
curl "https://kronenwerk.org/api/extern/v1/invoices?status=OPEN&from=2026-01-01&size=50" \
-H "Authorization: Bearer greif_live_…"
{
"data": [
{
"id": "7a90…",
"number": "2026-0041",
"documentType": "INVOICE",
"buyer": "Beispiel GmbH",
"currency": "EUR",
"issuedOn": "2026-08-28",
"dueOn": "2026-09-11",
"deliveredOn": "2026-08-28",
"net": { "minor": 89000, "currency": "EUR" },
"tax": { "minor": 16910, "currency": "EUR" },
"gross": { "minor": 105910, "currency": "EUR" },
"outstanding": { "minor": 105910, "currency": "EUR" },
"paymentState": "OPEN",
"overdue": false,
"cancelled": false,
"creditNote": false,
"paidOn": null,
"recordedAt": "2026-08-28T14:02:11Z"
}
],
"page": 0,
"size": 50,
"total": 1,
"more": false
}
paymentState ist eines von OPEN, OVERDUE, PAID, CANCELLED oder CORRECTION; overdue wird gegen das heutige Datum berechnet. cancelled bedeutet, dass ein Korrekturdokument existiert, das diese Rechnung vollständig aufhebt; creditNote bedeutet, dass dieses Dokument selbst eine Korrektur ist. Im Archiv wird nie etwas gelöscht oder bearbeitet.
Webhooks: invoice.issued, invoice.paid, invoice.cancelled
Jedes Ereignis wird als HTTPS-POST mit einem Signatur-Header (KRONENWERK-Signature: t=…,v1=…, HMAC-SHA256 über den Zeitstempel, einen Punkt und den rohen Body) und einer stabilen Ereignis-ID in KRONENWERK-Event-Id und Idempotency-Key zugestellt. Die Zustellung erfolgt mindestens einmal, speichern Sie also die Ereignis-ID und überspringen Sie Wiederholungen. Der Body ist ein flaches JSON-Objekt; jeder Wert ist ein String, und die Schlüssel sind sortiert.
{
"amountDueMinor": "105910",
"buyerName": "Beispiel GmbH",
"currency": "EUR",
"documentType": "INVOICE",
"dueDate": "2026-09-17",
"event": "invoice.issued",
"grossMinor": "105910",
"id": "0d3c…",
"invoiceId": "7a90…",
"issueDate": "2026-09-03",
"netMinor": "89000",
"number": "2026-0042",
"paymentState": "OPEN",
"taxMinor": "16910"
}
invoice.paid trägt dieselben Felder plus paidOn; es wird ausgelöst, wo die Zahlung die Forderung tatsächlich ausgleicht, auf welchem Weg auch immer — eine Zahlungsmaske, ein Bankimport, das Telefon. invoice.cancelled ergänzt cancelledByInvoiceId, cancelledByNumber und reason und benennt das Korrekturdokument, damit ein Empfänger den richtigen Datensatz stornieren und die Gutschrift abgleichen kann. Ein separates Ereignis payment.recorded meldet Geldbewegungen in beide Richtungen, mit direction, amountMinor, method, reference, targetKind und targetId. Die Schritte zur Verifikation stehen auf der Webhooks-Seite.
Ein typischer Ablauf
- Ihre App legt den Kunden einmalig mit
POST /customersan (Name, Straße, Postleitzahl, Ort sind erforderlich; Land, USt-IdNr. und Währung sind optional) und speichert die zurückgegebeneid. - Wenn ein abrechenbares Ereignis eintritt, ruft Ihre App
POST /invoices/draftsmit diesercustomerIdund einemIdempotency-Keyauf, der aus Ihrem eigenen Datensatz abgeleitet ist, zum Beispiel der Vertrags- oder Bestellnummer. - Eine Person im Unternehmen vervollständigt den Entwurf und stellt ihn aus. KRONENWERK berechnet die steuerliche Beurteilung, prüft die USt-IdNr. gegen VIES, validiert die strukturierte Datei und verbraucht die Nummer.
- Ihr Webhook-Endpunkt empfängt
invoice.issued, verifiziert die Signatur, dedupliziert überidund speichertnumberundinvoiceIdzu Ihrem Datensatz. - Wenn die Rechnung beglichen ist, trifft
invoice.paidein. Wenn die Person sie storniert, trifftinvoice.cancelledmit der Nummer der Korrektur ein. - Für den Abgleich liefert
GET /reports/outstandingdie heute offenen Forderungen und Verbindlichkeiten in der Buchwährung, aus denselben Zahlen, die das Dashboard des Inhabers zeigt.
Das Muster wird für ein Abonnementgeschäft unter Ein SaaS-Produkt an die Buchhaltung anbinden durchgespielt.
So geht KRONENWERK damit um
Mit Einschränkungen unterstützt Das Anlegen von Entwürfen, das Lesen von Rechnungen und die drei Rechnungsereignisse funktionieren wie beschrieben, im Enterprise-Plan (Preise). Die Einschränkung ist beabsichtigt und im aktuellen Design dauerhaft: Die API fügt einem Entwurf keine Positionen hinzu, stellt nicht aus, erfasst keine Zahlungen und storniert nicht. Wenn Ihre Integration einen vollautomatischen Ausstellungsablauf ohne Person braucht, ist die API von KRONENWERK das heute nicht, und diese Seite sagt das, statt etwas anderes anzudeuten.
Was das Produkt bei der Ausstellung tut, ist unter Rechnungen und E-Rechnung beschrieben: XRechnung und ZUGFeRD für Deutschland, Factur-X für Frankreich, Peppol BIS UBL für Belgien, FA(3) für Polen sowie PDF-Rechnungen mit nationalen Steuerregeln für Kanada und die Vereinigten Staaten. Der Versand über Peppol läuft über einen akkreditierten Access-Point-Anbieter (Storecove), sobald das Unternehmen unter Einstellungen → Zustellung verbunden ist; die polnische KSeF-Übermittlung ist noch nicht produktionsreif. Beides wird unter Peppol-Integration und KSeF-Integration behandelt.
Häufig gestellte Fragen
Kann ich die Rechnungspositionen oder die Summe über die API setzen?
Nein. POST /invoices/drafts akzeptiert nur customerId. Positionen, Preise und das Lieferdatum werden im Produkt eingegeben, bevor eine Person den Entwurf ausstellt.
Kann die API eine Rechnung ausstellen?
Nein, mit keinem Scope. Die Ausstellung verbraucht eine Nummer und gibt ein rechtliches Dokument frei; sie bleibt im Produkt, und der Webhook invoice.issued meldet sie.
Wie erfahre ich, dass eine Rechnung bezahlt wurde?
Abonnieren Sie invoice.paid (und payment.recorded für die Zahlung selbst), oder fragen Sie GET /invoices?status=PAID mit einem from-Datum ab. Der Webhook ist der vorgesehene Weg.
Warum braucht der Entwurfs-Endpunkt companies:read?
Der Entwurf wird für die ausstellende juristische Person gebaut: Ihre Nummerierung, Zahlungstage und Rechtsordnung bestimmen, was das Dokument sagt. Das Lesen dieser Einstellungen ist Teil des Anlegens, daher wird der Scope deklariert statt stillschweigend vorausgesetzt.
Ist die Rechnungsnummer im Entwurf endgültig?
Nein. Sie ist der Vorschlag des Ländermoduls für die nächste rechtmäßige Nummer und wird erst bestätigt, wenn die Rechnung ausgestellt wird.