Changelog
Toute évolution de l'API est documentée ici dès sa publication. La version
active est annoncée dans le header Facturino-Version renvoyé sur
chaque réponse. La politique de dépréciation (préavis 12 mois minimum, aucune
suppression silencieuse) est détaillée dans
Versions de l'API.
L'API est en production. La version contractuelle courante est
2026-09-01 — le premier contrat stable, et la seule version servie.
Une date publiée ne change jamais rétroactivement : les futures versions datées
seront immuables et coexisteront. Chaque évolution est consignée ci-dessous — un
ajout rétro-compatible conserve la même version (ligne datée).
Versions
2026-09-01
1 septembre 2026- Correctif 10 septembre 2026 Contrôle de campagne : intention colorimétrique Factur-X GTS_PDFA1 et validation renforcée ; réparation des archives préparée sans écrasement des originaux. Le PATCH établissement recalcule le SIREN ; les motifs B2Brouter et les codes Iopole restent structurés et verbatim. Les routes d’encaissement B2Brouter et Seqino et la ventilation Iopole sont vérifiées localement ; cette porte ne remplace pas une qualification distante.
- Modifié 10 septembre 2026 Train préparé : app 2026.3.23, Functions 2.7.0, SDK Node, Go, Python et PHP 2.7.0. Date de contrat inchangée (2026-09-01). Les reçus des webhooks entrants sont isolés par établissement, plateforme et événement ; une échéance durable précède la première livraison sortante. Les mutations protégées conservent leur reçu d’effet après perte de la réponse ; les autres rejeux ambigus sont refusés avant réexécution.
- Modifié 10 septembre 2026 Les crons de maintenance reprennent leurs parcours depuis un curseur durable. Les écritures financières bornent les données sérialisées à 512 Kio et archivent les historiques volumineux dans des segments vérifiables. Les journaux masquent les appelants et les contenus fournisseur. Les files internes terminées de facturation sont conservées 90 jours ; les pièces légales gardent leur règle de conservation.
- Modifié 10 septembre 2026 Réception Iopole : pagination distante par recherche, avec borne documentée de 1 100 résultats pour les pages de 100. Les avis annuaire sont dédoublonnés ; un e-mail dont l’acceptation est incertaine attend une preuve signée du prestataire avant tout renvoi. Les compteurs API utilisent des blocs de 20 autorisations par minute et 10 par mois : après arrêt ou éviction du cache, chaque bloc peut laisser jusqu’à 19 ou 9 autorisations inutilisées réservées jusqu’à la fin de la fenêtre. Ces réservations peuvent se cumuler ; les en-têtes de solde sont conservateurs.
- Correctif 9 septembre 2026 Capacités des plateformes : les obligations sont vérifiées par code avant émission. Iopole (date d’encaissement non vérifiée), B2Brouter (montants et date absents) et Seqino (lecture seule) laissent le statut bloqué avec un motif précis. La page de connexion distingue couverture implémentée, preuve historique ou simulée, et obligations non couvertes.
- Correctif 9 septembre 2026 Sécurité : transport HTTPS à résolution DNS fixée, clés incohérentes refusées, journaux d’e-mail sans adresse ni sujet, secrets liés par famille de fonctions et disjoncteur isolant les erreurs de compte. La validation fiscale requise échoue fermée et conserve sa preuve ; les historiques volumineux sont archivés sans perte en sous-collection.
- Correctif 9 septembre 2026 Contrat et retours : les paiements exposent `recorded_by` (`api`, `app`, `system`) ; JSON invalide et corps trop grand répondent 400/413 avec `request_id` ; un curseur disparu répond 400 `invalid_field_value`. Les webhooks disposent de données discriminées par famille, de cinq tentatives sur 2 h 36 de délais planifiés et de 90 jours de conservation. La récupération des tâches perdues lit les échéances durables. `ereporting.submitted` est écrit avec la transition durable, REST et cron, une fois par déclaration et tentative. Les quatre SDK partagent les réponses HTTP locales de référence, y compris les champs absents et null.
- Ajouté 8 septembre 2026 SDK Node, Go, Python et PHP 2.7.0 : contrat de lecture aligné. Rejets : `rejectionCode`, `rejectionSource`, `rejectionNote`, `rejectionReason`, `rejectionCategory` (onze catégories) et `paErrorCode` dans les événements ; routage et suivi : `routingIdentifier`, `buyerReachableAt`, `directoryCheckedAt`, `submissionArtefact.routingIdentifier`, `previousSubmissions` ; paiements : `Payment.fr212` avec `state` (`awaiting_deposit` inclus), `sentAt`, `lastErrorCode`, `lastErrorReason`, `updatedAt` ; avertissements : `Customer.warnings` et `TaxDecision.warnings` (`BuyerNatureWarning`) ; avoirs et événements associés : `relatedInvoiceNumber`. Les exemples et la nullabilité sont décrits dans OpenAPI, sans changement de date du contrat. Python et PHP reprennent aussi les modèles des versions 2.5 et 2.6 et le reçu de rejeu ciblé.
- Ajouté 8 septembre 2026 Messages par langue du compte : catalogue français commun, historique structuré par `code` et `params` avec `details` conservé, notifications et e-mails cohérents. Les erreurs API gardent leurs codes, leurs messages anglais et leur `doc_url`. Aucune autre langue ni sélecteur dans cette version.
- Correctif 8 septembre 2026 Classification des rejets par code : REJ_ADR désigne une incohérence de routage ; AUTRE attend une explication en note. La source du verdict est enregistrée explicitement, les motifs et notes restent verbatim. Le renvoi archive le verdict puis efface les champs courants.
- Ajouté 8 septembre 2026 Revérification quotidienne des acheteurs absents de l’annuaire, plafonnée à 200 SIREN par établissement : dates `directoryCheckedAt` et `buyerReachableAt`, notification réglable `buyer_reachable`, sans renvoi automatique. Avertissement non bloquant `buyer_nature_suspect` sur les clients et décisions fiscales ; numéro de facture liée servi sur les avoirs et leurs événements. Le signal fr:211 est une mention d’historique seule, sans changement de statut ni webhook.
- Correctif 8 septembre 2026 Statut « Encaissée » : aucune émission sur une tentative rejetée ou sans identifiant courant. Les items attendent en `awaiting_deposit`, sans reprise par le cron, puis sont réveillés par le dépôt accepté. Un refus HTTP 4xx devient `blocked` avec son motif conservé sur l’item, le paiement et la notification ; les issues de transport et 5xx restent à rapprocher. Le travailleur requalifie les anciens items en attente d’un dépôt utilisable.
- Correctif 8 septembre 2026 Routage du dépôt : le CII porte l’adresse de réception active renvoyée par l’annuaire, en priorité pour le SIRET de l’acheteur. `einvoicing.routingIdentifier` expose l’adresse utilisée ; l’artefact régénéré la conserve aussi. Les identifiants légaux, l’original archivé et la clé d’idempotence du dépôt sont conservés. Un annuaire indéterminé laisse le dépôt inchangé.
- Ajouté Premier contrat stable de l'API Facturino : 147 endpoints REST sous `/v1/*` couvrant la facturation électronique française (Factur-X EN 16931, CIUS-FR, e-reporting, cycle de vie DGFiP).
- Ajouté Ressource immuable `POST /v1/tax-decisions` et `GET /v1/tax-decisions/:id` : la TVA, les montants de la facture et les trois obligations de transmission sont arrêtés pour tout le cycle, quel que soit le moyen de paiement. Une décision non finale ne porte aucun montant. L'en-tête `Idempotency-Key` y est obligatoire : `201` à la création, `200` au rejeu de la même clé, `409` si la même clé est réutilisée avec un corps différent.
- Ajouté Deux sources fiscales de même niveau, en union discriminée par `taxSource` : `facturino` (la TVA est déterminée par les moteurs Facturino) et `integration` (la TVA est fournie par l'intégration — `vatRate`, `vatCode`, `vatexCode` par ligne — validée en cohérence, jamais corrigée en silence). Dans les deux parcours, les montants, les mentions légales et les trois axes d'obligation sont décidés côté serveur.
- Ajouté Cycle documentaire décision-premier : les factures exigent `taxDecisionId` + `decisionLines`, les avoirs référencent les lignes originales (`creditedLines`) et héritent strictement de la source et du snapshot de la facture corrigée, les récurrences portent `taxInputs` et prennent une nouvelle décision à chaque occurrence. Une décision finale adosse exactement une facture.
- Ajouté Cycle du devis sur un seul document : `POST /v1/quotes/:id/convert` produit un brouillon commercial (`taxSource: null`, `items` vide, opération lisible dans `commercialDraft`), puis `POST /v1/invoices/:id/bind-tax-decision` adosse une décision finale à ce même brouillon avant sa finalisation. L'appel est idempotent sur la décision ; adosser une autre décision à une facture déjà adossée, ou la même décision à une seconde facture, répond `409`.
- Ajouté Les factures et avoirs exposent trois axes indépendants — `documentStatus`, `transmissionStatus`, `paymentStatus` ; le champ `status` est un résumé dérivé de ces axes, jamais une autorité propre.
- Ajouté Le dépôt PA est autorisé uniquement quand la décision figée porte `invoiceChannel: einvoicing`. Les refus portent des codes stables (`tax_decision_required`, `not_einvoicing_channel`, `tax_snapshot_inconsistent`) et un chemin de sortie — demandez une décision, puis réémettez. Le téléchargement Factur-X / XML et le dépôt manuel restent disponibles sur tous les plans.
- Ajouté Un acompte doit être **intégralement réglé** avant qu'une facture de solde puisse le déduire (BT-113/BT-115) ; l'échéancier répartit exactement le montant décidé restant dû.
- Ajouté Reprise d'une déclaration e-reporting refusée : `POST /v1/ereporting/declarations/:id/retry` crée la tentative suivante des mêmes données. La déclaration refusée est CONSERVÉE et les deux sont chaînées (`supersedesDeclarationId` / `supersededByDeclarationId`). Un refus de la plateforme répond `422 ereporting_declaration_rejected`.
- Ajouté Modèle BYOPA (Bring Your Own PA) : 4 Plateformes Agréées supportées en production + un connecteur générique AFNOR XP Z12-013.
- Ajouté 4 SDKs officiels (Node, Python, PHP, Go) avec auto-pagination, retry exponentiel et types stricts.
- Ajouté Format d'erreur stable inspiré de Stripe : `error.type`, `error.code`, `error.param`, `error.request_id`, `doc_url`, `hint`. Webhooks signés HMAC-SHA256 (tolérance 5 minutes, idempotence par `event_id`, retries exponentiels). Idempotence native via `Idempotency-Key` sur les POST. `Facturino-Version` renvoyé sur toutes les réponses.
- Ajouté Endpoints `/v1/usage` (compteurs de quota en temps réel) et `/v1/billing/subscription` (plan, renouvellement, état de l'abonnement).
- Ajouté 2 septembre 2026 Ventes B2C dans l'Union : registre annuel des seuils `/v1/eu-threshold-ledgers` (ouverture, mouvements, ajustements, corrections, revue), trace `euB2cDestination` sur la décision, `goodsMovement` sur les lignes d'intégration, registre daté des taux normaux des 27 États membres.
- Ajouté 3 septembre 2026 `error.issues` : les raisons détaillées d'un refus, `{ code, param, message }`, facultatif et additif, au plus 500 raisons, identiques entre la première réponse et son rejeu idempotent.
- Modifié 3 septembre 2026 Preuves de localisation réseau (`ip_geolocation`, `bank_details`, `sim_mobile_country`, `fixed_line`) transmises sans code postal : résolues au niveau du pays, `territoryId: null` sur la preuve, l'adresse de facturation portant le territoire fin. Une `reference` de preuve qui est une adresse IP ou un IBAN est refusée.
- Ajouté 4 septembre 2026 `POST /v1/invoices/:id/finalize` accepte un `payment` facultatif : une facture encaissée d'avance est émise acquittée dans la même transaction, son original PDF et Factur-X rendus sur la facture réglée. `dates.paidAt` porte la date réelle de règlement.
- Ajouté 6 septembre 2026 Webhooks : `data` porte désormais, en plus du saut (`status`, `previous_status`), le document tel qu'écrit : `number`, `documentStatus`, `transmissionStatus`, `transmissionDetail`, `paymentStatus` et `metadata` ; les avoirs ajoutent `relatedInvoiceId`, les devis `number` et `metadata` ; `payment.received` ajoute `total` et `amountDue`. Ajout compatible, date de contrat inchangée. Le bac à sable émet le même payload que la production (`previous_status`).
- Ajouté 6 septembre 2026 `POST /v1/events/:id/retry` accepte `{ "endpointId" }` pour rejouer un événement vers un seul endpoint, même déjà livré ; nouveau code `endpoint_not_subscribed`.
- Ajouté 6 septembre 2026 Avoirs : journal de cycle de vie (`lifecycle`) écrit à la création, à la finalisation, au dépôt et au remboursement, affiché sur la fiche ; libellés d'encaissement propres aux avoirs (« Non remboursé », « Remboursé ») ; les actions de dépôt sont masquées avec leur motif quand le document est adressé au SIREN de son émetteur ; le suivi du dépôt s'ouvre d'office sur un rejet.
- Correctif 6 septembre 2026 Renvoi d'une facture rejetée par la plateforme : `send` ouvre une nouvelle tentative sous le même numéro. Les identifiants, le statut et le motif du dépôt rejeté sont conservés dans `einvoicing.previousSubmissions`, les identifiants courants et la clé de dédoublonnage repartent à zéro, la réponse de la plateforme à la nouvelle tentative est adoptée et le premier contrôle planifié. Un événement de cycle de vie qui désigne l'ancien dépôt, ou qui ne désigne aucune tentative et date d'avant le renvoi, n'est pas appliqué : le contrôle planifié et le sondage, qui lisent la plateforme par l'identifiant courant, établissent le verdict. Un statut d'encaissement (fr:212) encore en file suit la nouvelle tentative.
- Ajouté 7 septembre 2026 Lecture des rejets : `einvoicing.rejectionCategory` (`buyer_not_in_directory`, `format_invalid`, `semantic_error`, `duplicate`, `platform_auth`, `platform_unavailable`, `refused_by_buyer`, `suspended`, `unknown`) sur les factures et les avoirs, aussi dans les tentatives closes. Les événements de facture et d'avoir portent `paErrorCode`, `rejectionReason` et `rejectionCategory` (renseignés sur `invoice.rejected`, `invoice.refused`, `credit_note.credit_refused`). L'e-mail, la notification et l'historique mènent avec cette lecture et la prochaine étape ; le motif brut reste en détail.
- Modifié 7 septembre 2026 Annuaire consulté avant tout dépôt : un acheteur absent est rejeté localement (`paErrorCode` et `rejectionCategory` `buyer_not_in_directory`), sans appel de plateforme ; un annuaire injoignable ne bloque pas. Un statut fr:211 « Paiement transmis » émis par l'acheteur ne rétrograde plus une facture encaissée : le grand livre commande l'axe de paiement.
- Ajouté 7 septembre 2026 Paiements : `fr212` (`state`, `sentAt`, `lastErrorCode`, `updatedAt`) dit où en est le statut « Encaissée » de chaque encaissement auprès de la plateforme. Un statut bloqué déclenche la notification `payment_status_blocked`.
- Modifié 6 septembre 2026 `POST /v1/credit-notes/:id/send` refuse aussi `self_invoicing_not_allowed` quand l'avoir est adressé au SIREN de son émetteur, avant tout changement d'état. Au renvoi d'une facture rejetée, un statut d'encaissement (fr:212) resté à rapprocher sur le dépôt rejeté repart en file et suit la nouvelle tentative.
- Correctif 6 septembre 2026 Un statut d'encaissement rapporté par la plateforme (fr:212) n'efface plus un remboursement enregistré : une fois `refundedTotal` renseigné, `paymentStatus` suit le grand livre (`refunded` ou `partially_refunded`), le résumé reste `paid`.
- Ajouté 5 septembre 2026 La fiche facture affiche le motif et le code de refus, ainsi que le CII corrigé préparé pour le dépôt, sans confondre sa préparation avec son acceptation. Les objets `einvoicing` et `files` sont décrits dans le schéma OpenAPI Invoice et la documentation ; le contrat conserve sa date. Le suivi e-reporting distingue les contrôles techniques (`acknowledged`), les déclarations non transmises (`skipped`), bloquées et à rapprocher. La reprise est proposée aux administrateurs uniquement.
- Correctif 5 septembre 2026 Les faits de soumission reçus tardivement ne sont pas rattachés à un dépôt dont un identifiant connu désigne une autre soumission. Les identifiants manquants du même dépôt sont toujours complétés sans changement de position ni nouvel événement.
- Correctif 5 septembre 2026 E-reporting FRR : les dates sont sérialisées sans tirets (`AAAAMMJJ`, G1.09) et la date-heure du rapport sur quatorze chiffres (`AAAAMMJJHHMMSS`, TT-3), conformément aux spécifications DGFiP v3.2. Le stockage et les dates de l’API conservent leur format ISO.
- Ajouté 5 septembre 2026 E-reporting : les lignes unitaires portent le type du document source (`documentType`, `380` facture ou `381` avoir) et, pour un avoir, la référence de la facture corrigée (`originalInvoiceNumber`, `originalInvoiceDate`), figées à l'agrégation depuis la facture liée (BT-25/BT-26, G1.32). FRR : l'avoir est un bloc typé 381 à montants positifs qui nomme la facture corrigée (TG-11) ; Seqino : `preceding_invoice_reference` et `preceding_invoice_issue_date`. Un avoir sans cette référence, ou un flux international dont l'établissement déclarant n'a pas de numéro de TVA intracommunautaire (G2.33), est refusé avant tout appel à la plateforme, avec le champ à compléter. Champs facultatifs, déclarations antérieures inchangées.
- Correctif 5 septembre 2026 La réponse immédiate au dépôt conserve ses identifiants de plateforme et sa date d'envoi même lorsqu'un statut reçu par webhook l'a devancée : la position atteinte est gardée, les identifiants absents sont rattachés dans la même transaction.
- Correctif 5 septembre 2026 Dépôt d'une facture figée avant un correctif du générateur : si l'original ne satisfait plus une règle du CIUS-FR (BR-FR-08 par exemple), le dépôt envoie un CII régénéré depuis le document figé — même numéro, mêmes montants — enregistré sous `files.correctedXmlPath` et tracé dans le cycle de vie ; l'original Factur-X archivé n'est jamais réécrit. La régénération part de l'état d'émission (encaissement à l'émission, pas les encaissements postérieurs). Nouveau code `document_not_conformant`, renvoyé par `send` quand aucune régénération ne suffit, le document étant remis en `pending`.
- Modifié 5 septembre 2026 E-reporting : les ventes B2C d'une journée sont déclarées par nature (biens `B1`, services `S1`), jamais en bloc mixte ; `status: accepted` signifie l'acceptation par l'administration, rapportée par la plateforme, et sort du suivi ; Seqino : acheteur identifié sur les factures internationales (TT-36, schémas 0223/0227), encaissements B2C déclarés par jour d'encaissement, reprise d'une transmission partielle par correction des enregistrements déjà créés, encaissements internationaux déclarés par facture et par jour d'encaissement. Le suivi des déclarations est monotone : un accusé technique reçu après l'acceptation de l'administration ne la remet jamais en cause ; les flux de cycle de vie des rapports sont lus dans leur CDAR, par fenêtres qui progressent.
- Modifié 5 septembre 2026 E-reporting : les lignes conservent la catégorie de TVA décidée (`vatCategoryCode`), son motif d'exonération (`vatexCode`, nullable) et, pour les factures unitaires, la raison sociale figée de l'acheteur (`partnerName`). Ces champs restent facultatifs pour les déclarations antérieures. Les ventilations de même taux mais de catégorie ou de motif différents restent distinctes. FRR et Seqino identifient l'acheteur selon les règles TT-36/TT-37 : TVA intracommunautaire (0223) ou code pays suivi des seize premiers caractères de la raison sociale (0227). Une identité requise absente entraîne un refus avant tout appel à la plateforme.
- Correctif 5 septembre 2026 La réponse immédiate au dépôt suit les mêmes écritures transactionnelles que les webhooks : une approbation déjà reçue ne recule pas vers `deposited`, et une acceptation tardive du fichier ne remplace pas un identifiant de plateforme déjà enregistré.
- Correctif 5 septembre 2026 Factur-X : le CII porte désormais le cadre de facturation BT-23 (`B1`/`S1`/`M1` selon la nature de l'opération, `B2`/`S2`/`M2` pour une facture émise acquittée). Sans lui, une plateforme appliquant le CIUS-FR rejetait tout dépôt (règle BR-FR-08). La validation avant dépôt le contrôle.
- Correctif 5 septembre 2026 Dépôt sur la Plateforme Agréée : `sending` est conservé tant que la plateforme n'a pas confirmé le dépôt ; `deposited` n'est plus présumé à l'acceptation du fichier. Un premier contrôle du statut a lieu une minute après l'envoi, puis toutes les quinze minutes ; la plateforme ne fait jamais reculer une facture le long de la chaîne de transmission. Une facture encaissée avant son dépôt garde `status: paid` une fois approuvée (`transmissionStatus: approved`) ; l'événement `invoice.approved` est émis même si `status` ne change pas. Les webhooks des plateformes et la récupération après incident suivent la même règle : aucun dépôt présumé, aucun recul sur la chaîne, motif de rejet complété dès qu'il est connu.
- Ajouté 5 septembre 2026 Rejet ou refus par la plateforme : `einvoicing.rejectionReason` et `einvoicing.paErrorCode` portent le motif et le code de la plateforme ; l'e-mail et la notification le reprennent. Nouveau code `self_invoicing_not_allowed` sur `POST /v1/invoices/:id/send` quand le client porte le SIREN de l'émetteur.
- Modifié 5 septembre 2026 E-reporting : l'accusé technique de la plateforme (contrôles antivirus, schéma, unicité) est distingué de l'acceptation par l'administration ; `status` reste `submitted` jusqu'à cette acceptation, `rejected` dès un refus, avec le motif. Seqino : déclarations transmises sur son API reporting native (transactions B2C par jour, factures internationales, encaissements) et suivies par ses événements de cycle de vie.
- Modifié 4 septembre 2026 La copie PDF de présentation suit les encaissements : après un paiement, une annulation ou un remboursement, `GET /v1/invoices/:id/pdf` répond 202 avec un job de rendu au lieu de servir une copie périmée. L'original Factur-X est figé à l'émission et ne change jamais.
Comment être notifié des changements
-
Surveillez le header
Facturino-Versionrenvoyé sur chaque réponse — il indique la version contractuelle utilisée pour traiter votre requête. -
Surveillez le header
Facturino-Versionrenvoyé par l'API et la page Versions de l'API : il n'existe pas d'évènement webhook de dépréciation. Toute dépréciation est annoncée dans le changelog et sur la page versioning, avec un préavis de 12 mois minimum. - Consultez régulièrement cette page : nous ne diffusons pas de notifications e-mail globales, mais chaque entrée du changelog liste précisément les endpoints et champs concernés.
Notre engagement
- Préavis 12 mois minimum sur toute dépréciation.
- Aucune suppression silencieuse : un champ ou endpoint déprécié reste fonctionnel jusqu'à sa date de retrait annoncée.
- Aucun changement cassant sans nouvelle version contractuelle annoncée (voir Versioning).
- Préservation du contrat : l'ajout d'un champ ou d'un endpoint n'est jamais un breaking change.