API-documentatie
REST/JSON-API voor Peppol BIS Billing 3.0 (UBL 2.1). Basis-URL: https://efactuur.klik-shop.nl/v1
Authenticatie en tegoed
Stuur je key mee in de header X-API-Key. Maak een gratis key aan op Gratis API-key. Elke key heeft 5 gratis documenten per kalendermaand; daarna gaat tegoed op (€9 per 1.000, €29 per 5.000, incl. btw). Een document is één succesvolle /v1/ubl- of /v1/validate-call. Invoerfouten (422) bij /v1/ubl en ongeldige requests (400/413) tellen niet. Max. 60 requests per minuut per key.
Taal van meldingen: ?lang=nl of ?lang=en (anders volgens Accept-Language).
Privacy: documenten worden alleen in het werkgeheugen verwerkt en niet opgeslagen of gelogd. Elk antwoord bevat "stored": false.
POST /v1/ubl
JSON erin, UBL 2.1 Peppol BIS Billing 3.0 eruit. Berekent regeltotalen, btw per tarief en eindtotalen (afronding op 2 decimalen). Met ?format=xml krijg je direct het XML-bestand.
curl -X POST https://efactuur.klik-shop.nl/v1/ubl -H "X-API-Key: ubl_jouw_key" -H "content-type: application/json" -d @factuur.json
{
"type": "invoice",
"number": "F2026-001",
"issue_date": "2026-11-01",
"due_date": "2026-11-15",
"buyer_reference": "PO-123",
"seller": {
"name": "Jouw Bedrijf",
"vat": "NL005310837B66",
"kvk": "98148362",
"address": { "street": "Straat 1", "city": "Leiden", "postal_code": "2315 VW", "country": "NL" },
"contact": { "email": "factuur@example.nl" }
},
"buyer": {
"name": "Voorbeeld B.V.",
"vat": "NL123456789B01",
"kvk": "12345678",
"address": { "street": "Hoofdstraat 1", "city": "Utrecht", "postal_code": "3511 AA", "country": "NL" }
},
"payment": { "iban": "NL91ABNA0417164300" },
"lines": [
{ "name": "Webshop teksten", "quantity": 3, "unit": "HUR", "price": "65.00", "vat_rate": 21 },
{ "name": "Boek", "quantity": 2, "price": "19.99", "vat_rate": 9 }
]
}
Antwoord (200, ingekort):
{
"document_type": "Invoice",
"xml": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Invoice xmlns=\"urn:oasis:names:specification:ubl:schema:xsd:Invoice-2\" xmlns:cac…",
"totals": {
"line_extension": "234.98",
"allowances": "0.00",
"charges": "0.00",
"tax_exclusive": "234.98",
"vat": "44.55",
"tax_inclusive": "279.53",
"prepaid": "0.00",
"payable": "279.53",
"currency": "EUR",
"vat_breakdown": [
{
"category": "S",
"rate": "21",
"taxable": "195.00",
"vat": "40.95"
},
{
"category": "S",
"rate": "9",
"taxable": "39.98",
"vat": "3.60"
}
]
},
"warnings": [
{
"field": "seller.endpoint",
"code": "DERIVED",
"message": "seller Peppol address derived: 0106:98148362. Check that this is the address the party is registered with in Peppol."
},
{
"field": "buyer.endpoint",
"code": "DERIVED",
"message": "buyer Peppol address derived: 0106:12345678. Check that this is the address the party is registered with in Peppol."
}
],
"self_check": {
"valid": true,
"errors": 0,
"warnings": 0,
"scope": "subset",
"issues": []
},
"stored": false
}
| Veld | Uitleg |
|---|---|
type | invoice (standaard) of credit_note |
number, issue_date | Factuurnummer en datum (JJJJ-MM-DD). Verplicht. |
due_date, payment_terms | Vervaldatum en/of betalingsvoorwaarden. |
buyer_reference / order_reference | Peppol eist één van beide (BT-10 of BT-13). Overheden geven een referentie op. |
currency | ISO 4217, standaard EUR. |
seller, buyer | name, vat, kvk (NL), kbo (BE), legal_id {id, scheme}, endpoint {id, scheme}, address {street, additional, city, postal_code, region, country}, contact {name, phone, email}, trading_name. Zonder endpoint leiden we het Peppol-ID af (KvK → 0106, KBO → 0208, anders btw-nummer) en melden dat als waarschuwing. |
payment | iban, bic, account_name, reference, means_code (standaard 58 SEPA-overboeking, of 30), mandate_id |
lines[] | name, quantity, unit (UN/ECE Rec 20, standaard C62), price (excl. btw), vat_rate, vat_category (S, Z, E, AE, K, G, O, L, M), optioneel description, base_quantity, allowance/charge {amount, reason}, sku, gtin, period, note. |
allowances[], charges[] | Korting/toeslag op documentniveau: amount of percent + base_amount, reason, vat_rate/vat_category. |
prepaid, rounding | Vooruitbetaald bedrag en afrondingsbedrag. |
preceding_invoice | {number, date}: verwijzing naar de oorspronkelijke factuur (bij creditnota). |
exemption_reasons | Bijv. {"E": "Vrijgesteld o.g.v. art. 11 Wet OB"}. Voor AE/K/G/O vullen we een standaardtekst en VATEX-code in. |
note, invoice_period, delivery, contract_reference, project_reference | Optioneel. |
Bij invoerfouten krijg je 422 met per veld een melding in het Nederlands en Engels, bijv. {"field": "lines[0].price", "code": "INVALID_NUMBER", "message": "…"}.
POST /v1/validate
Stuur de UBL-XML als body (Content-Type: application/xml) of als JSON {"xml": "…"}. Max. 2 MB.
curl -X POST "https://efactuur.klik-shop.nl/v1/validate?lang=nl" -H "X-API-Key: ubl_jouw_key" -H "content-type: application/xml" --data-binary @factuur.xml
Antwoord (ingekort):
{
"valid": false,
"document_type": "Invoice",
"errors": 4,
"warnings": 0,
"issues": [
{
"layer": "en16931",
"severity": "error",
"rule": "BR-CO-15",
"location": "/Invoice/cac:LegalMonetaryTotal/cbc:TaxInclusiveAmount",
"line": 97,
"message": "Invoice total amount with VAT (BT-112) = Invoice total amount without VAT (BT-109) + Invoice total VAT amount (BT-110).",
"value": "272.35 ≠ 277.35",
"explanation": "Totaal incl. btw (BT-112) moet gelijk zijn aan totaal excl. btw + btw. Oplossing: Herbereken TaxInclusiveAmount.",
"explanation_nl": "Totaal incl. btw (BT-112) moet gelijk zijn aan totaal excl. btw + btw.",
"fix_nl": "Herbereken TaxInclusiveAmount.",
"fix_en": "Recalculate TaxInclusiveAmount = TaxExclusiveAmount + VAT."
},
"…"
],
"scope": "subset",
"scope_note": "Server-side check: … This is NOT the complete official Schematron …",
"full_validator": "https://efactuur.klik-shop.nl/valideren",
"stored": false
}
De API controleert server-side: goed gevormde XML, de UBL 2.1-structuur (elementnamen, volgorde, aantallen, datatypes, codelijsten) en ca. 120 van de meest voorkomende regels uit EN16931, Peppol BIS 3.0 en de Nederlandse NL-R-regels, in code nagebouwd. Dat is niet de volledige officiële Schematron (de officiële regels zijn te zwaar voor onze serverless hosting). Landenregels van andere landen (DE, DK, NO, SE, …) zitten niet in de API. Voor de complete officiële controle gebruik je de gratis browser-validator. Het antwoord bevat altijd
"scope": "subset".Elke melding heeft layer (xml, xsd, en16931, peppol, nl), severity (error/warning), rule (officiële regel-ID waar mogelijk; eigen controles beginnen met KS-), location, line, message (Engelse regeltekst) en explanation/fix_nl/fix_en.
GET /v1/account
curl https://efactuur.klik-shop.nl/v1/account -H "X-API-Key: ubl_jouw_key"
Statuscodes
200 | OK |
400 | ongeldige body (gratis) |
401 | key ontbreekt of onbekend |
402 | gratis documenten op en geen tegoed |
413 | te groot |
422 | invoerfouten bij /v1/ubl (gratis) |
429 | te veel requests (zie Retry-After) |
Headers: X-Quota-Remaining, X-Validation-Valid.
Beperkingen
- Klik&Shop is geen Peppol Access Point: de API maakt en controleert bestanden, maar verstuurt niets.
- Ondersteund: Peppol BIS Billing 3.0 (UBL Invoice en CreditNote). Niet: XRechnung-CIUS, Factur-X/ZUGFeRD, bijlagen meesturen via de generator.
- De generator controleert zijn eigen uitvoer met de API-subset (
self_check). We hebben de generator getest tegen de volledige officiële regels; laat bij twijfel je bestand nog door de browser-validator gaan.