Une API comptable pour l'Europe doit réussir huit choses qu'une API mono-pays peut ignorer : une TVA qui dépend du pays et du statut des deux parties, l'autoliquidation et sa mention sur la facture, la vérification du numéro de TVA dans VIES, des factures électroniques structurées au format national, les obligations du RGPD sur les données clients, des écritures idempotentes avec des webhooks signés, un véritable grand livre en partie double et une comptabilité multidevise. Ce guide explique chaque exigence et montre comment l'API de KRONENWERK s'y rapporte — y compris là où l'API s'arrête : elle crée des clients, des brouillons et des transactions et lit les livres ; elle n'émet pas de factures, ne passe pas d'écritures et ne dépose pas de déclarations.
La TVA multi-pays est une fonction de faits, pas un champ « taux »
Dans l'UE, le traitement TVA d'une vente découle du pays du vendeur, du pays de l'acheteur, du statut de l'acheteur (professionnel ou consommateur) et de la nature de l'opération (biens ou services). La directive 2006/112/CE fixe le cadre : pour les services B2B, le lieu de la prestation est celui où le preneur est établi (article 44) ; lorsque le prestataire n'y est pas établi, le preneur est redevable de la TVA par autoliquidation (article 196) ; les livraisons intracommunautaires de biens à un assujetti identifié dans un autre État membre sont exonérées lorsque les conditions sont remplies (article 138) ; et l'article 226 énumère les mentions obligatoires d'une facture, dont la mention « Autoliquidation » lorsqu'elle s'applique. Les taux, seuils et exonérations sont nationaux.
La conséquence pour la conception d'une API est qu'on ne doit jamais demander à l'appelant un taux de TVA isolé. Une API européenne bien conçue prend les faits et renvoie un verdict — taux normal, taux zéro, exonéré, autoliquidation, hors champ — avec le taux et la mention de facture qui en découlent, et refuse de deviner lorsqu'un fait manque.
KRONENWERK : chaque facture porte un verdict fiscal dérivé des faits de la transaction (pays du vendeur, pays de l'acheteur, professionnel ou consommateur, nature de l'opération). Le verdict est l'un de : taux normal, taux zéro, exonéré, autoliquidation, hors champ, ou « saisie requise » / « confirmation professionnelle requise » lorsque les faits ne tranchent pas. Il est stocké avec la facture et jamais déduit après coup des données de base. Par l'API, le verdict n'est pas un champ que vous définissez : un brouillon créé avec POST /invoices/drafts hérite de la juridiction du vendeur, et le verdict est fixé lorsqu'une personne émet la facture dans le produit. Savoir si une opération donnée bénéficie d'une exonération est une question pour un professionnel, et le produit le dit plutôt que de décider.
L'autoliquidation exige les deux numéros de TVA et la bonne mention
Une facture en autoliquidation diffère d'une facture domestique en trois points : aucune TVA n'est facturée, l'identifiant TVA de l'acheteur doit figurer à côté de celui du vendeur, et le document doit indiquer que l'acheteur est redevable de la taxe. En termes EN 16931, la catégorie de TVA est AE, un motif d'exonération est obligatoire, et les règles BR-AE-01 à BR-AE-10 imposent la ventilation et les identifiants. Une facture électronique structurée avec la mauvaise catégorie est rejetée par le validateur du destinataire ; un PDF avec la mauvaise mention est un problème de conformité pour les deux parties.
KRONENWERK : lorsque le verdict est l'autoliquidation, la facture est émise avec 0 % de TVA, la catégorie AE dans le document structuré, le numéro de TVA de l'acheteur et la mention légale dans la langue du document. L'API lit le résultat via GET /invoices/{number}, où tax vaut zéro et net égale gross. Il n'existe pas de paramètre d'API pour forcer l'autoliquidation ; elle découle du pays et du numéro de TVA du client, que vous pouvez fournir avec POST /customers :
POST https://kronenwerk.org/api/extern/v1/customers
Authorization: Bearer greif_test_XXXXXXXXXXXXXXXX
Idempotency-Key: 6f1c2f4e-3c0a-4b8f-9d61-2a7c1c2e9b10
Content-Type: application/json
{
"name": "Atelier Dupont SARL",
"email": "compta@example.fr",
"street": "12 rue de la Paix",
"postalCode": "75002",
"city": "Paris",
"country": "FR",
"vatId": "FR12345678901",
"currency": "EUR"
}
La vérification VIES, au bon moment
VIES est le système d'échange d'informations en matière de TVA de la Commission. Son service web checkVat prend un code pays et un numéro et renvoie si le numéro est valide à la date de la requête, ainsi que le nom et l'adresse lorsque l'État membre les divulgue ; checkVatApprox compare en plus les coordonnées de l'opérateur et renvoie un requestIdentifier — le numéro de consultation qui documente le contrôle. La Commission propose aussi une interface REST avec la même sémantique. Les back-ends des États membres sont parfois indisponibles, auquel cas le service renvoie un statut tel que MS_UNAVAILABLE plutôt qu'une validité. Le service existe pour les opérations intracommunautaires en vertu du règlement (CE) n° 904/2010 du Conseil.
Deux règles de conception en découlent. Contrôlez au moment où la décision en dépend — l'émission — et pas seulement à la création du client, car les immatriculations expirent. Et stockez le résultat avec le document, parce que la question qui se posera plus tard est « était-il valide quand nous avons facturé », pas « est-il valide aujourd'hui ».
KRONENWERK : le numéro de TVA de l'acheteur est vérifié dans VIES à l'émission et le résultat est stocké avec la facture, avec le verdict. Si VIES ou le back-end de l'État membre ne répond pas, le contrôle est enregistré sur la facture comme non joignable et affiché comme avertissement à l'émission ; une indisponibilité n'est jamais traitée comme un résultat valide et n'est pas mise en cache, tandis qu'un résultat réel est mémorisé un jour pour ne pas interroger le registre à chaque frappe. Le vérificateur de numéro de TVA gratuit exécute le même contrôle sur un numéro isolé sans le stocker. L'API n'expose pas d'endpoint VIES propre ; elle expose le résultat stocké sur la facture émise.
Les factures électroniques structurées sont nationales, pas européennes
La directive européenne sur la facturation électronique (2014/55/UE) oblige les organismes publics à recevoir des factures EN 16931 ; les obligations B2B sont nationales et diffèrent par le format, le réseau et le calendrier. L'Allemagne impose aux entreprises de recevoir des factures structurées et échelonne l'émission (XRechnung ou ZUGFeRD) ; la Belgique impose Peppol BIS Billing 3.0 via le réseau Peppol pour le B2B depuis le 1er janvier 2026 ; la Pologne fait transiter les factures par le KSeF au format FA(3) ; la France fonctionne avec des plateformes agréées, Factur-X étant l'un des formats acceptés. Le Canada et les États-Unis n'ont pas d'obligation de format structuré. Voir le calendrier et les formats.
Pour une API, cela signifie que le format est une propriété du pays du vendeur et du canal de l'acheteur, décidée à l'émission, et que le document doit être validé avec les artefacts nationaux (le Schematron du CEN plus les règles du profil) avant d'exister. Une API qui accepterait du XML arbitraire de la part des appelants devrait de toute façon le valider et repousserait la partie la plus difficile du problème vers chaque appelant.
KRONENWERK : le fichier structuré est généré et validé à l'émission pour le pays du vendeur — XRechnung et ZUGFeRD (Schematron KoSIT, contre-vérifié avec Mustang), Factur-X, Peppol BIS UBL, FA(3). L'API crée le brouillon ; le format, la validation et l'envoi relèvent du produit. C'est le plus grand écart, dit honnêtement, pour les développeurs qui s'attendaient à POSTer une facture et recevoir du XML : il n'y a pas d'endpoint « émettre » et pas de XML dans l'API. La page API de facturation électronique détaille exactement ce qui est disponible, et le guide développeur EN 16931 couvre les règles si vous générez vous-même les documents.
RGPD : les données clients sont des données personnelles
Le nom, l'adresse, l'e-mail et le numéro de TVA d'un entrepreneur individuel sont des données personnelles, si bien qu'une intégration comptable est une activité de traitement. Le RGPD exige un contrat entre responsable du traitement et sous-traitant fixant l'objet, la durée, la nature, la finalité et les catégories de données (article 28, paragraphe 3) ; un registre des traitements (article 30) ; une sécurité adaptée au risque, y compris le chiffrement le cas échéant (article 32) ; et, pour les transferts hors UE/EEE, un mécanisme de transfert valide (chapitre V, à partir de l'article 44). Ce qu'un développeur attend d'un fournisseur comptable est donc concret : un accord de traitement des données, une indication du lieu de stockage des données et des sous-traitants ultérieurs utilisés, et un moyen de supprimer ou d'exporter les enregistrements d'une personne concernée.
KRONENWERK : les conditions de traitement et les modalités d'hébergement sont exposées sur la page de confidentialité et la page de sécurité ; lisez celles-ci plutôt que ce guide pour l'engagement contraignant. KRONENWERK ne détient aucune certification de sécurité et ne revendique aucune « certification RGPD », car une telle certification n'existe pas. Par l'API, les clés sont limitées par portée, de sorte qu'une intégration qui n'a besoin que de reports:read ne reçoit jamais de fiches clients, et chaque clé est liée à une seule entreprise.
Idempotence et webhooks
Les pannes réseau rendent chaque écriture ambiguë : un POST expiré peut avoir créé l'enregistrement ou non. La réponse standard est une clé d'idempotence — une valeur unique choisie par le client pour chaque opération logique, que le serveur stocke avec le résultat, de sorte qu'une nouvelle tentative avec la même clé renvoie le même résultat au lieu d'un doublon. Côté sortant, les webhooks doivent être signés pour que le destinataire puisse vérifier l'origine, porter un identifiant d'événement pour que les doublons puissent être écartés, et être réémis en cas d'échec.
KRONENWERK : chaque POST exige un en-tête Idempotency-Key ; une répétition avec la même clé et le même corps renvoie le résultat d'origine, et une répétition avec un corps différent répond 409 IDEMPOTENZ_KONFLIKT. Les erreurs sont en JSON avec un code machine et une phrase : UNAUTHENTICATED, ANFRAGE, PLAN_ERFORDERLICH, KEINE_BERECHTIGUNG, NICHT_GEFUNDEN, IDEMPOTENZ_KONFLIKT, FALSCHER_ZUSTAND, ABGELEHNT, ZU_VIELE_ANFRAGEN. La limite de débit est un budget de 240 requêtes par clé se rechargeant en continu à environ deux par seconde, avec réponse 429 et Retry-After. Les webhooks sortants sont signés (KRONENWERK-Signature) et portent KRONENWERK-Event-Id, KRONENWERK-Event, KRONENWERK-Delivery, KRONENWERK-Attempt et une Idempotency-Key ; les événements sont invoice.issued, invoice.paid, invoice.cancelled, purchase.recorded et payment.recorded ; la livraison se fait en HTTPS uniquement, avec nouvelles tentatives, et ne suit jamais les redirections. Détails : idempotence, webhooks, erreurs, limites.
Le grand livre est en partie double, et l'API le lit
Un système comptable n'est pas une liste de factures. Chaque facture, paiement et dépense produit des écritures équilibrées — débit clients, crédit ventes et TVA collectée ; débit banque, crédit clients — et les rapports sont des sommes sur des comptes, pas sur des documents. Une API construite sur un tel grand livre peut promettre que les « créances en cours » se rapprochent du compte collectif clients, et qu'un résultat n'est définitif que lorsque les périodes qui le composent sont clôturées. Une API construite sur une liste de documents ne le peut pas.
KRONENWERK : le grand livre est en partie double avec des périodes qui se clôturent. L'API REST lit les postes ouverts avec GET /reports/outstanding ; le serveur MCP expose en plus get_profit_and_loss, get_balance_sheet, list_receivables et list_payables depuis le même grand livre, avec un indicateur is_final sur le compte de résultat. Rien dans l'API ne passe d'écriture ; les écritures naissent d'actes qu'une personne accomplit dans le produit — émettre, enregistrer un paiement, approuver une facture fournisseur. Une réponse du rapport des postes ouverts, abrégée :
{
"asOf": "2026-09-03",
"currency": "EUR",
"booksOpen": true,
"receivables": { "outstanding": { "minor": 1284050, "currency": "EUR" },
"due": { "minor": 412000, "currency": "EUR" },
"overdue": { "minor": 105910, "currency": "EUR" },
"count": 9 },
"payables": { "outstanding": { "minor": 336000, "currency": "EUR" },
"due": { "minor": 0, "currency": "EUR" },
"overdue": { "minor": 0, "currency": "EUR" },
"count": 3 }
}
Devises : unités mineures, une devise de tenue des livres, taux stockés
Les montants en nombres à virgule flottante perdent des centimes ; les montants en chaînes formatées sont ambigus d'une locale à l'autre (« 1.059,10 » contre « 1,059.10 »). La représentation robuste est un nombre entier d'unités mineures avec un code ISO 4217. Une entreprise multidevise facture dans la devise du client, tient ses livres dans une seule devise de tenue, et doit stocker le taux utilisé sur chaque document pour que les rapports ultérieurs ne dérivent pas avec le taux du jour.
KRONENWERK : chaque montant sur l'API est {"minor": 105910, "currency": "EUR"}, jamais un décimal ni une chaîne. Une entreprise a une seule devise de tenue des livres ; les clients peuvent avoir une devise de facturation préférée ; les chiffres figés sur une facture émise sont ceux que l'API renvoie, pas les données de base du jour. Les configurations multi-entreprises utilisent une clé par entreprise. Voir plusieurs entreprises, plusieurs devises et la page produit multi-entreprises.
Comment KRONENWERK gère cela
Pris en charge avec des limitations L'API publique à https://kronenwerk.org/api/extern/v1 couvre GET /me, les clients (GET, GET /{id}, POST), les factures (GET, GET /{number}, POST /invoices/drafts), les transactions (GET, POST) et GET /reports/outstanding, avec des clés à portées, une idempotence obligatoire sur les écritures, un budget de débit par clé, des erreurs JSON avec codes machine, des webhooks signés et un serveur MCP sur la même clé. Les limitations sont délibérées et doivent être anticipées : l'API crée uniquement des brouillons et des transactions — elle n'émet pas de factures, ne produit ni n'accepte de XML structuré, ne passe pas d'écritures, n'enregistre pas de paiements, n'exécute pas de contrôles VIES à la demande, et ne dépose ni ne règle aucune taxe. Ces actes se font dans le produit, où les modules pays les valident, et l'API et les webhooks en rapportent les résultats. Tout cela fait partie du plan Enterprise ; voir les tarifs, la vue d'ensemble de l'API comptable, le démarrage rapide et le guide de connexion SaaS.
Questions fréquentes
Puis-je définir le taux de TVA d'une facture par l'API ?
Pas sur l'API REST : un brouillon hérite de la juridiction du vendeur et le verdict est fixé à l'émission à partir des faits. Par le serveur MCP, create_invoice_draft accepte un tax_rate_percent par ligne pour le brouillon ; une personne le relit et l'émet quand même. Une ligne qui porte plusieurs taxes à la fois — TPS et TVQ au Québec, TPS et TVP en Colombie-Britannique, État, comté et ville aux États-Unis — ou une taxe nommée qui ne facture rien, comme une exportation détaxée, est indiquée à la place par taxes sur la ligne : une entrée par taxe avec son name, son rate_percent et, lorsque rien n'est facturé, le reason propre au vendeur. Chaque taxe s'applique au net de la ligne et est imprimée et totalisée sous son propre nom ; KRONENWERK ne fournit aucun taux et ne décide d'aucun nexus. create_quote_draft prend la même liste sur une ligne de devis, et l'API REST la porte comme steuern sur la ligne d'un devis comme d'une facture ; la facture issue du devis la reprend telle quelle. Le schéma de l'outil, renvoyé par le serveur MCP, fait référence pour ces champs.
L'API émet-elle des factures juridiquement valables ?
Non. Elle crée des brouillons. L'émission — numérotation, validation en tant que facture électronique structurée, envoi — est effectuée dans le produit, et le webhook invoice.issued la rapporte.
Comment vérifier le numéro de TVA d'un client avant de facturer ?
KRONENWERK le contrôle dans VIES à l'émission et stocke le résultat. Pour un contrôle ponctuel, utilisez le vérificateur de numéro de TVA ; il n'y a pas d'endpoint VIES sur l'API.
Existe-t-il un bac à sable ?
Une clé greif_test_ fonctionne sur le même hôte en mode test pour l'entreprise qui l'a créée. Il n'existe pas d'hôte sandbox distinct.
Où mes données sont-elles stockées, et existe-t-il un accord de traitement des données ?
Les réponses contraignantes se trouvent sur la page de confidentialité et la page de sécurité. KRONENWERK ne détient aucune certification de sécurité et ne revendique aucune « certification RGPD ».
Quels pays l'API couvre-t-elle ?
Les mêmes que le produit : Allemagne, France, Belgique, Pologne (limitée — la transmission KSeF n'est pas encore éprouvée en production), Canada et États-Unis.
Sources
- Council Directive 2006/112/EC on the common system of VAT (consolidated) — consulté le
- European Commission — VIES checkVat web service (WSDL) — consulté le
- Regulation (EU) 2016/679 (GDPR) — consulté le
- ConnectingEurope — eInvoicing-EN16931 validation artefacts — consulté le
- KRONENWERK developer documentation — consulté le