Naar de inhoud

Voor ontwikkelaars

Factuur-API: concepten aanmaken, uitgereikte facturen lezen, events ontvangen

Laatst gecontroleerd SUPPORTED WITH LIMITATIONS

Vertaling van de Engelse versie, die als eerste wordt bijgehouden. Regelgevende uitspraken verwijzen naar de genoemde bronnen en hun leesdatum.

Met de factuur-API van KRONENWERK kan uw software een factuurconcept voor een klant starten met POST /invoices/drafts, uitgereikte facturen lezen met GET /invoices en GET /invoices/{number}, en via de webhooks invoice.issued, invoice.paid en invoice.cancelled vernemen dat een factuur is uitgereikt, betaald of geannuleerd. Het uitreiken zelf wordt niet blootgesteld: het nummer, het btw-oordeel, de VIES-controle en het gevalideerde gestructureerde bestand ontstaan wanneer een persoon het concept in het product uitreikt.

Wat de factuur-API wel en niet doet

Ze maakt concepten aan en leest het archief. Een concept is een werkdocument: het kan worden gecorrigeerd, opnieuw geprijsd of weggegooid, en niemand buiten de onderneming heeft het gezien. Een uitgereikte factuur is het tegenovergestelde: er is een nummer verbruikt uit een doorlopende reeks zonder gaten, een archiefregel is bevroren, er is een bestand geproduceerd dat aan een nationale norm voldoet, en in Polen is het document mogelijk overhandigd aan een staatssysteem dat beslist of het juridisch bestaat. De API geeft u het eerste en leest alleen het tweede.

HandelingVia de APIWaar het gebeurt
Een klant aanmakenPOST /customersAPI of product
Een factuurconcept startenPOST /invoices/draftsAPI of product
Regels toevoegen, prijzen bepalen, leveringsdatum kiezenniet blootgesteldProduct
Uitreiken: nummer, btw-oordeel, VIES-controle, gestructureerd bestand, validatieniet blootgesteldProduct; gemeld door invoice.issued
Een betaling registrerenniet blootgesteldProduct (handmatig, bankimport); gemeld door invoice.paid en payment.recorded
Annuleren door volledige correctieniet blootgesteldProduct; gemeld door invoice.cancelled
Uitgereikte facturen lezenGET /invoices, GET /invoices/{number}API
Lezen wat vandaag openstaatGET /reports/outstandingAPI

De volledige lijst van endpoints, de authenticatie en de vorm van foutmeldingen staan op de pagina over de boekhoud-API en in de referentie.

Een concept aanmaken: POST /invoices/drafts

Het verzoek noemt een klant en verder niets. Wat terugkomt is een concept dat is voorbereid zoals het product er een voorbereidt: het nummeringsvoorstel van de verkoper, de vervaldatum uit de met de klant afgesproken betalingstermijn, en de betalingszin van het rechtsgebied van de verkoper in de taal waarin dat rechtsgebied documenten opstelt. Elk daarvan is een beslissing die een landmodule beheert; een verzoekveld ervoor zou een aanroeper toelaten stilzwijgend de regels van een land te overrulen dat hij niet heeft gelezen.

Drie scopes zijn vereist — invoices:write, customers:read en companies:read — omdat het concept wordt opgebouwd vanuit een klant en voor een juridische entiteit waarvan de nummering, de betalingstermijn en het rechtsgebied bepalen wat het document zegt. De header Idempotency-Key is verplicht.

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 is een voorstel in het formaat dat de landmodule van de verkoper als wettig beschouwt, met het voorvoegsel van de onderneming als dat is ingesteld; het wordt pas definitief bij de uitreiking. state is op dit vlak altijd DRAFT. Een customerId die niet bestaat of die bij een andere onderneming hoort, krijgt als antwoord 404 NICHT_GEFUNDEN — één antwoord voor beide gevallen, zodat statuscodes niet kunnen worden gebruikt om de identificatoren van iemand anders op te sommen. Een herhaling met dezelfde Idempotency-Key geeft hetzelfde concept terug; een herhaling met een andere body krijgt 409 IDEMPOTENZ_KONFLIKT. Zie idempotentie.

Na de aanroep verschijnt het concept in de factuurlijst van het product, waar een persoon regels toevoegt, het btw-nummer van de klant controleert en het concept uitreikt. Uw integratie verneemt de uitkomst via de webhook, niet door te pollen.

Waarom het uitreiken in het product blijft

Omdat het uitreiken het moment is waarop drie beslissingen definitief worden, en elk daarvan wordt getoetst aan feiten waarover de API-aanroeper niet beschikt.

Validatie van het gestructureerde bestand

Bij de uitreiking genereert KRONENWERK de gestructureerde e-factuur die het land van de verkoper verwacht — XRechnung of ZUGFeRD in Duitsland, Factur-X in Frankrijk, Peppol BIS Billing 3.0 UBL in België, FA(3)-XML in Polen — en valideert ze die voordat het nummer wordt verbruikt. Een Duits document wordt getoetst aan de KoSIT-Schematronregels en kruiselings gecontroleerd met de Mustang-bibliotheek. Een concept dat de validatie niet doorstaat, wordt niet uitgereikt; de persoon ziet welke regel faalde. Een API die rechtstreeks zou uitreiken, zou die controle ofwel moeten overslaan, ofwel een foutkanaal moeten bedenken voor een document dat de aanroeper nooit heeft gezien. Zie de pagina over de e-facturatie-API.

Het btw-oordeel

Elke factuur krijgt een btw-oordeel op basis van de feiten van de transactie — land van verkoper en koper, onderneming of consument, aard van de prestatie: normaal tarief, nultarief, vrijgesteld, verlegd, buiten toepassingsgebied, of "invoer vereist" / "vereist professionele bevestiging". Het btw-nummer van de koper wordt bij de uitreiking gecontroleerd in VIES en het oordeel wordt bij de factuur opgeslagen. Waar de feiten geen uitsluitsel geven, zegt het product dat en vraagt het een persoon; het gokt niet, en dat zou een script ook niet mogen doen.

Nummering

Factuurnummers komen uit een doorlopende reeks zonder gaten, en een verbruikt nummer kan niet ongedaan worden gemaakt; de remedie voor een verkeerde factuur is een correctiedocument, geen verwijdering. Een lus die twee keer heeft gedraaid, mag geen twee nummers kunnen verbruiken; daarom stopt de API bij het concept en is elke write die ze wel aanbiedt idempotent.

Uitgereikte facturen lezen: GET /invoices

GET /invoices geeft uitgereikte facturen terug, de nieuwste eerst, één pagina per keer, met de cijfers zoals ze bij de uitreiking werden bevroren — een klant die vorige week een nieuwe naam kreeg, verandert niets aan de naam op een factuur die vorig jaar werd uitgereikt. De filters zijn status (OPEN of PAID; een onleesbare waarde betekent geen filter), from en to (ISO-uitreikingsdatums), page en size (standaard 25, maximaal 100). GET /invoices/{number} leest één factuur op het nummer waaronder de onderneming en haar klant ze allebei 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 is een van OPEN, OVERDUE, PAID, CANCELLED of CORRECTION; overdue wordt berekend ten opzichte van vandaag. cancelled betekent dat er een correctiedocument bestaat dat deze factuur volledig tegenboekt; creditNote betekent dat dit document zelf een correctie is. In het archief wordt nooit iets verwijderd of bewerkt.

Webhooks: invoice.issued, invoice.paid, invoice.cancelled

Elk event wordt afgeleverd als een HTTPS-POST met een handtekeningheader (KRONENWERK-Signature: t=…,v1=…, HMAC-SHA256 over de tijdstempel, een punt en de ruwe body) en een stabiele event-id in KRONENWERK-Event-Id en Idempotency-Key. De aflevering is at-least-once; sla de event-id dus op en sla herhalingen over. De body is een plat JSON-object; elke waarde is een string en de sleutels zijn gesorteerd.

{
  "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 bevat dezelfde velden plus paidOn; het wordt uitgestuurd waar de betaling de vordering daadwerkelijk vereffent, langs welke weg dan ook — een betalingsscherm, een bankimport, de telefoon. invoice.cancelled voegt cancelledByInvoiceId, cancelledByNumber en reason toe en noemt het correctiedocument, zodat een ontvanger het juiste record kan ongeldig maken en de creditnota kan afstemmen. Een afzonderlijk event payment.recorded meldt geld dat in een van beide richtingen beweegt, met direction, amountMinor, method, reference, targetKind en targetId. De verificatiestappen staan op de webhookpagina.

Een typische volgorde

  1. Uw app maakt de klant één keer aan met POST /customers (naam, straat, postcode en plaats zijn verplicht; land, btw-nummer en valuta zijn optioneel) en slaat de teruggegeven id op.
  2. Wanneer zich een factureerbare gebeurtenis voordoet, roept uw app POST /invoices/drafts aan met die customerId en een Idempotency-Key die is afgeleid van uw eigen record, bijvoorbeeld het contract- of ordernummer.
  3. Een persoon in de onderneming vult het concept aan en reikt het uit. KRONENWERK berekent het btw-oordeel, controleert het btw-nummer in VIES, valideert het gestructureerde bestand en verbruikt het nummer.
  4. Uw webhook-endpoint ontvangt invoice.issued, verifieert de handtekening, ontdubbelt op id en slaat number en invoiceId op bij uw record.
  5. Wanneer de factuur is vereffend, komt invoice.paid binnen. Als de persoon ze annuleert, komt invoice.cancelled binnen met het nummer van de correctie.
  6. Voor de afstemming geeft GET /reports/outstanding de vandaag openstaande vorderingen en schulden terug in de valuta van de boekhouding, op basis van dezelfde cijfers die het dashboard van de eigenaar toont.

Het patroon wordt voor een abonnementsbedrijf uitgewerkt in een SaaS-product koppelen aan de boekhouding.

Hoe KRONENWERK hiermee omgaat

ONDERSTEUND MET BEPERKINGEN Het aanmaken van concepten, het lezen van facturen en de drie factuurevents werken zoals beschreven, in het Enterprise-plan (prijzen). De beperking is bewust en permanent in het huidige ontwerp: de API voegt geen regels toe aan een concept, reikt niet uit, registreert geen betalingen en annuleert niet. Als uw integratie een volledig geautomatiseerde flow nodig heeft waarbij zonder tussenkomst van een persoon wordt uitgereikt, dan is de API van KRONENWERK dat vandaag niet, en deze pagina zegt dat liever dan het tegendeel te suggereren.

Wat het product bij de uitreiking doet, staat beschreven op facturen en e-facturatie: XRechnung en ZUGFeRD voor Duitsland, Factur-X voor Frankrijk, Peppol BIS UBL voor België, FA(3) voor Polen, en pdf-facturen met nationale belastingregels voor Canada en de Verenigde Staten. Verzending via Peppol verloopt via een geaccrediteerde toegangspuntaanbieder (Storecove) zodra de onderneming is aangesloten in Instellingen → Verzending; de Poolse KSeF-verzending is nog niet productieklaar. Beide worden behandeld op Peppol-integratie en KSeF-integratie.

Veelgestelde vragen

Kan ik de factuurregels of het totaal via de API instellen?

Nee. POST /invoices/drafts aanvaardt alleen customerId. Regels, prijzen en de leveringsdatum worden in het product ingevoerd voordat een persoon het concept uitreikt.

Kan de API een factuur uitreiken?

Nee, met geen enkele scope. Uitreiken verbruikt een nummer en geeft een juridisch document vrij; dat blijft in het product, en de webhook invoice.issued meldt het.

Hoe kom ik te weten dat een factuur betaald is?

Abonneer u op invoice.paid (en op payment.recorded voor de betaling zelf), of poll GET /invoices?status=PAID met een from-datum. De webhook is de bedoelde weg.

Waarom heeft het concept-endpoint companies:read nodig?

Het concept wordt opgebouwd voor de uitreikende juridische entiteit: haar nummering, betalingstermijn en rechtsgebied bepalen wat het document zegt. Het lezen van die instellingen maakt deel uit van het aanmaken van het concept, dus wordt de scope uitdrukkelijk gedeclareerd in plaats van stilzwijgend vereist.

Is het factuurnummer in het concept definitief?

Nee. Het is het voorstel van de landmodule voor het volgende wettige nummer en wordt pas bevestigd wanneer de factuur wordt uitgereikt.

Bronnen

  1. KRONENWERK developer documentation geraadpleegd op
  2. Directive 2006/112/EC on the common system of value added tax, Title XI Chapter 3 (invoicing) geraadpleegd op
  3. European Commission — VIES VAT number validation geraadpleegd op

Begin met integreren

Lees de snelstart Referentie

Lees verder