Die API ist das Produkt.
Fünf Schritte von der leeren Organisation bis zur ersten konformen Rechnung. Ein Datenmodell für Finance, Engineering und Ops: dokumentiert, versioniert, replay-sicher.
Fünf Schritte bis zur ersten Rechnung.
Kein Einrichtungsassistent, keine Klickstrecken. Alles, was Kontier kann, ist ein API-Aufruf. Jeder Schritt zeigt den zentralen Aufruf, die Folgeaufrufe stehen als Kommentar darunter.
-
customer.createdKunde anlegen
customer_type steuert die Steuerbehandlung. Ein Geschäftskunde in einem anderen EU-Land braucht eine Kennung wie die UID; die VIES-Prüfung läuft danach automatisch an, sofern sie im Workspace aktiv ist.
terminalcurl -X POST https://api.kontier.eu/v1/customers \ -H "Authorization: Bearer sk_test_…" \ -H "Idempotency-Key: 7f3c9a1e-4b2d-4c8e-9f10-2a6b8d3e5c71" \ -d '{"name":"Zehetbauer IT-Services GmbH","email":"billing@example.com", "customer_type":"BUSINESS", "billing_address":{"line1":"Hauptstrasse 1","city":"Wien","postal_code":"1010","country":"AT"}, "identifiers":[{"kind":"AT_UID","value":"ATU12345678"}]}'→ 201 · customer.created
-
product.createdProdukt definieren
Die abrechenbare Einheit. pricing_model bestimmt, wie eine Staffel rechnet: VOLUME, STAIRCASE oder PACKAGE. Preis, Zähler und Veröffentlichung hängen Sie mit je einem Aufruf an.
terminalcurl -X POST https://api.kontier.eu/v1/products \ -H "Idempotency-Key: 2b81d4f0-6e3a-4f5b-8c2d-9a1e7b4c6d20" \ -d '{"name":"API Platform","pricing_model":"STAIRCASE", "quantity_source":"METERED","unit_label":"call"}'# dann: POST /v1/prices, POST /v1/meters, POST /v1/changes→ 201 · product.created · status: draft
-
plan.createdPlan versionieren
Der Plan bündelt Produkte mit ihren Inklusivmengen. Jede Veröffentlichung ist eine neue Version, und jede Abo-Position bleibt an ihrer Version gepinnt, bis Sie etwas anderes festlegen.
terminalcurl -X POST https://api.kontier.eu/v1/plans \ -H "Idempotency-Key: 9c02aa17-3d5e-4a7b-b1c4-6e8f0a2d4b93" \ -d '{"name":"Pro","price_cadence_unit":"month"}'# dann: POST /v1/plans/{id}/products {"included_quantity":"10000"}→ 201 · plan.created
-
subscription.activatedSubscription starten
Das Abo entsteht als Entwurf. Revision 1 beschreibt Phasen wie Trial und Laufzeit, /activate setzt sie in Kraft. Jede spätere Änderung ist eine neue Revision, keine Überschreibung.
terminalcurl -X POST https://api.kontier.eu/v1/subscriptions \ -H "Idempotency-Key: e51f7b93-8a2c-4d6e-a0b3-5c7d9e1f3a48" \ -d '{"customer_id":"0f8fad5b-d9cb-469f-a165-70867728950e","currency":"EUR"}'# dann: PUT …/revisions/draft, POST …/activate→ 201 · status: DRAFT → 200 · subscription.activated
-
invoice.draftedUsage senden, Rechnung entsteht
quantity ist ein String, damit Dezimalstellen den Transport überleben. Der idempotency_key im Body macht den Retry nach einem Timeout ungefährlich: derselbe Key zählt einmal.
terminal Beispieldatencurl -X POST https://api.kontier.eu/v1/usage-events \ -H "Idempotency-Key: 4d9e2f61-7b3a-4c58-9e0d-1f6a8b2c7e35" \ -d '{"customer_id":"0f8fad5b-…","product_id":"3f2a8c1e-…", "subscription_id":"5d0b6a0e-…","metric_key":"api_calls", "quantity":"18402","idempotency_key":"sub-5d0b-api_calls-2026-11"}'→ 201 · recorded→ Periodenende · invoice.drafted · 33,61 € + 6,39 € USt = 40,00 €
Was die API garantiert.
Zusagen statt Feature-Liste: Das hält jede Antwort, jeder Fehler und jeder Webhook verbindlich ein.
Signiert, at-least-once, replay-fähig.
HMAC-SHA256 über Zeitstempel und rohen Body, Secret mit whsec_-Präfix. Prüfen Sie X-Webhook-Signature-V1 und verwerfen Sie Zeitstempel außerhalb von ±5 Minuten, dann ist ein mitgeschnittener Aufruf nicht wiederholbar. Sechs Zustellversuche (sofort, 1m, 5m, 30m, 2h, 12h), Deduplizierung über idempotency_key. Ohne Signing-Secret wird nicht zugestellt.
RFC 9457 Problem Details.
Jeder Fehler ist maschinenlesbar: type, title, status, detail, code, dazu request_id für den Support. Kein Raten, kein Regex auf Fehlertexte.
Pflicht, nicht Option.
Idempotency-Key ist auf jedem POST erforderlich. Der Key ist an den SHA-256 des Bodys gebunden: derselbe Key mit anderem Body ergibt 409. 5xx werden nie gecacht, ein Retry führt also wirklich aus.
Cursor statt Offset.
Keyset über (created_at, id), Cursor als opakes Token. Stabil bei parallelen Inserts; has_more ist das verbindliche Signal, nicht total_count.
Geschlossen, wo Geld fließt.
Fällt der Idempotenz-Speicher kurz aus, laufen Vorgänge, die Geld bewegen oder belegen (Gutschriften, Belastungen, Erstattungen, Rechnungskorrekturen), nicht ohne Deduplizierung: Sie erhalten 503 mit Retry-After. Lieber ein Retry als eine Doppelbuchung.
Die Plan-Version ist gepinnt.
Jede Abo-Position trägt ihre Plan-Version und bleibt standardmäßig gepinnt. Eine Veröffentlichung verändert keine ausgestellte Rechnung, und ein Wechsel ist eine neue Revision, kein Nebeneffekt. Was eine Veröffentlichung auslösen würde, zeigt publish-impact vorher.
Die Spezifikation ist der Vertrag.
OpenAPI 3.1, direkt aus dem Code generiert, nicht nebenher gepflegt. Über 550 Pfade, über 750 Operationen und 144 Webhook-Events, jedes mit eigenem Payload-Schema. Daraus generieren Sie Ihren Client selbst.
Die Rechnung, die die Prüfung besteht.
XRechnung und ZUGFeRD entstehen aus derselben Rechnung, die Sie ohnehin erzeugen. Kein zweiter Datenpfad, kein Export nach Excel, keine Bibliothek, die Sie selbst gegen die KoSIT-Regeln halten müssen.
Vom Aufruf zum gültigen XML
Dokument erzeugen: Profil wählen, Rechnung referenzieren.
POST /v1/e-invoicing/documents{ "invoice_id": "ad796aee-…", "profile": "XRECHNUNG_3_0_UBL", "jurisdiction": "DE" }→ 201 · "quarantined": true · 1 finding
Rohes XML abholen: das, was beim Empfänger ankommt.
GET /v1/e-invoicing/documents/{id}/raw→ 200 · application/xml · sha256 ae717a6e…
Befunde lesen: jede verletzte Regel mit ID und XPath, nicht „ungültig“.
GET /v1/e-invoicing/documents/{id}/findings→ [ { "rule_id": "BR-DE-15", "severity": "ERROR", … } ]
Was validiert wird
Eigene Regel-Engine
EN 16931, KoSIT BR-DE und PEPPOL BIS laufen als Regelwerk im Dienst. Kein externer Schematron-Service, der ausfallen kann.
Die Regeln, die KoSIT wirklich prüft
Die BR-DE-Regeln sind Satz für Satz aus dem KoSIT-Schematron übernommen. BR-DE-15 verlangt eine Käuferreferenz (BT-10) und lässt ihren Inhalt offen: Leitweg-ID oder Bestellnummer bestehen beide. Ein so geprüfter Befund sieht aus wie dieser:
/Invoice/BuyerReference Käuferreferenz (BT-10) fehlt. Nachtragen am Entwurf mit PATCH /v1/invoices/{id} „buyer_reference“, dann neu erzeugen:
0 Befunde · zustellbarQuarantäne statt stiller Fehler
Befunde werden pro Dokument gespeichert. Ein Dokument, das die Regeln verletzt, geht in Quarantäne, statt unbemerkt an eine Behörde zu gehen.
19 Profile im Katalog
- XRECHNUNG_3_0_UBL
- XRECHNUNG_3_0_CII
- EN16931_UBL_2_1
- EN16931_CII_D16B
- PEPPOL_BIS_BILLING_3_UBL
- ZUGFERD_2_COMFORT
- FACTURX_EN16931
- ZUGFERD_2_XRECHNUNG
- +11
Grün markiert: reine XML-Profile, die der Dienst selbst erzeugt. Die elf hybriden PDF/A-3-Profile (Factur-X, ZUGFeRD) brauchen zusätzlich einen konfigurierten Mustang-Server.
Artefakte werden mit Bytes und Hash-Kette archiviert. Die GoBD-Frage „Ist das noch dieselbe Rechnung?“ ist damit beantwortbar.
Der Rest steht in der Referenz.
Vollständige Endpunkte, Schemas, Webhook-Kataloge und Beispiele, ohne Anmeldung lesbar, mit Sandbox-Keys sofort ausprobierbar. Und überall auf der Website zeigt die Taste Umschalt + I zu jedem Artefakt den API-Pfad, auch hier.