Aller au contenu principal

Émettre une facture de vente

Votre logiciel produit des factures de vente. Cette page suit le parcours côté API : créer la facture en brouillon depuis votre système, l'ajuster, puis la déposer - l'instant où Scribee fige le document, lui attribue son numéro définitif et enregistre le statut 200 Déposée. Vous travaillez en production : la phase de brouillon est votre espace de répétition, le dépôt est le point de non-retour.

Ce que Scribee fait pour vous​

  • Complète votre charge utile avec les données de l'annuaire (party_id) et les valeurs par défaut de l'entreprise émettrice : partie vendeur, mentions légales, coordonnées bancaires.
  • Attribue le numéro définitif au dépôt, à partir du modèle de numérotation configuré dans les réglages de facturation de l'interface Scribee. Ce remplacement n'a lieu que si le numéro porté par la facture commence par DRAFT-.
  • Génère les quatre formats livrables : pdf, ubl (UBL 2.1), cii (CII EN16931), facturx (PDF/A-3 avec XML embarqué). La génération est asynchrone et se relance à la création, à chaque PATCH et au dépôt. Le pdf fait exception quand vous avez fourni le vôtre (provided_pdf à true) ou quand la facture vient d'un import de PDF ou d'image : le fichier d'origine est conservé et n'est jamais réécrit.
  • Notifie vos webhooks : invoice.created à la création, invoice.lifecycle_event.created à chaque transition (Webhooks).

Ce que le dépôt ne fait pas​

Le dépôt n'envoie la facture ni au PPF (Portail Public de Facturation), ni au réseau Peppol, ni par email à votre client. Il enregistre le statut 200 sur la facture, régénère les formats (votre PDF fourni est conservé tel quel), remet éventuellement le document à un logiciel comptable connecté, et notifie vos webhooks.

En conséquence, l'appel de dépôt lui-même ne provoque aucun statut du destinataire. En revanche, dès lors que la facture emprunte le canal réglementaire, les statuts émis par la plateforme du destinataire (202 Reçue, 205 Approuvée, 210 Refusée, 213 Rejetée) sont appliqués par le traitement des flux entrants et inscrits dans lifecycle_events. Cet historique n'est donc pas limité à vos propres transitions et au passage automatique en 212 Encaissée (Enregistrer les paiements) : prévoyez des statuts que vous n'avez pas déclenchés.

Pour adresser le document à votre client, utilisez Envoyer par email et suivre la réception.

Le parcours​

Prérequis​

L'entreprise choisie détermine tout le reste : le vendeur, les mentions légales, les coordonnées bancaires, la séquence de numérotation, et l'annuaire dans lequel party_id est résolu. Un party_id appartenant à une autre entreprise du même workspace est refusé.

Étape 1 : créer la facture en brouillon​

Cet appel crée une facture à l'état draft (000 Brouillon) dans votre workspace. Rien n'est transmis. Le brouillon reste modifiable jusqu'au dépôt, et supprimable tant que son numéro commence par DRAFT-.

Pour que Scribee attribue le numéro définitif au dépôt, envoyez un numéro provisoire préfixé DRAFT- (unique par entreprise - suffixez-le de votre référence interne). Si vous envoyez d'emblée un numéro définitif, il est conservé tel quel au dépôt, mais le brouillon n'est alors plus supprimable via l'API.

attention

article_name, tax_category_id, article_unit_price_excluding_taxes, quantity et quantity_unit_code sont obligatoires sur chaque ligne. L'appel n'écrit ici aucune valeur de remplacement : si l'un des cinq manque sur une ligne, la création entière échoue en 422 et rien n'est enregistré - ni la ligne, ni la facture. C'est un comportement différent des quatre champs de niveau facture ci-dessous, dont l'absence laisse passer l'appel avec un statut 201.

curl -X POST https://app.scribee.tech/api/v1/workspaces/YOUR_WORKSPACE_ID/invoices \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"company_id": 317,
"invoice": {
"direction": "sales",
"invoice_number": "DRAFT-CRM-2026-0042",
"issue_date": "2026-07-31",
"due_date": "2026-08-30",
"type_code": "invoice",
"currency_code": "EUR",
"parties": [
{ "role": "buyer", "party_id": 42 }
],
"lines": [
{
"line_id": "1",
"article_name": "Prestation de conseil",
"quantity": 2.0,
"quantity_unit_code": "day",
"article_unit_price_excluding_taxes": 500.0,
"line_extension_amount": 1000.0,
"tax_category_id": "S",
"vat_rate": 20.0
}
],
"tax_subtotals": [
{ "tax_category_id": "S", "vat_rate": 20.0, "vat_amount": 200.0, "amount_without_taxes": 1000.0, "currency_code": "EUR" }
],
"total_amount_excluding_taxes": 1000.0,
"total_tax_amount": 200.0,
"tax_inclusive_amount": 1200.0,
"payable_amount": 1200.0
}
}'

Réponse 201, abrégée aux champs utiles ici :

{
"data": {
"id": 12345,
"invoice_number": "DRAFT-CRM-2026-0042",
"type_code": "invoice",
"lifecycle_state": "draft",
"lifecycle_status_code": "000",
"lifecycle_available_transitions": ["deposit"],
"tax_inclusive_amount": 1200.0,
"customization_id": null,
"upload_source": "manual",
"delivery_status": "not_delivered"
}
}

Un champ obligatoire manquant ne fait pas échouer l'appel​

C'est le comportement le plus important de cette page. Quatre champs conditionnent le dépôt : invoice_number, issue_date, type_code, currency_code. Si l'un manque, l'appel répond quand même 201 : Scribee écrit une valeur de remplacement et enregistre une erreur d'import bloquante.

Champ absentValeur écrite à sa place
invoice_numberTEMP- suivi de 8 caractères hexadécimaux
issue_datela date du jour
type_codeinvoice
currency_codeEUR

Cette erreur d'import n'est exposée par aucun champ de la réponse. Trois signaux la trahissent :

  • lifecycle_available_transitions vaut [] : deposit en est retiré tant que l'erreur est présente ;
  • aucun des quatre formats n'est généré, donc GET /api/v1/invoices/{id}/download ne renvoie rien ;
  • si invoice_number manquait, le numéro renvoyé commence par TEMP-.

Contrôlez lifecycle_available_transitions sur chaque réponse 201. S'il vaut [], la facture existe mais n'est pas déposable.

Pour la débloquer, envoyez un PATCH : il efface les erreurs d'import sans les revérifier. Le PATCH doit donc porter lui-même les quatre champs. En particulier, renvoyez un invoice_number préfixé DRAFT-. Un numéro TEMP- survit au PATCH, n'est jamais remplacé au dépôt (seul un numéro DRAFT- l'est) et rend le brouillon non supprimable : vous figeriez un original légal numéroté TEMP-A1B2C3D4.

La ventilation de TVA doit se raccorder aux totaux​

Sur une facture de vente, la ventilation tax_subtotals est confrontée aux totaux du même document avant tout enregistrement : la somme des amount_without_taxes doit égaler total_amount_excluding_taxes, et la somme des vat_amount doit égaler total_tax_amount, à 0,01 près. Un écart plus grand fait échouer l'appel en 422, à la création comme à la modification, et rien n'est enregistré (voir Erreurs et cas limites).

C'est la règle G1.53 du PPF, appliquée ici plutôt qu'au dépôt : elle refusait déjà ces factures, mais beaucoup plus tard et loin de l'appel qui les avait créées. Le contrôle ne s'applique pas quand la charge utile ne porte pas de tax_subtotals, quand le total de la moitié considérée est absent de la charge utile, quand aucune entrée de la ventilation n'énonce le montant de cette moitié, ou quand le document est une facture d'achat : cette plateforme ne dépose jamais un achat, et la règle ne le juge donc pas.

Une facture déjà payée à l'émission​

Une facture de vente déjà réglée au moment où elle est émise se déclare explicitement, par le cadre de facturation (BT-23) : envoyez invoicing_process_id valant B2 (biens), S2 (services) ou M2 (biens et services), ou la clé correspondante paid_goods_invoice, paid_services_invoice ou paid_goods_and_services_invoice. La réponse renvoie toujours la clé. Scribee ne déduit jamais ce cadre de vos montants : une facture envoyée en B1, S1 ou M1 reste dans ce cadre, même quand son prepaid_amount égale son total.

Les montants de la facture sont repris tels quels, ils doivent donc énoncer eux-mêmes le règlement :

  • prepaid_amount (BT-113) exactement égal à tax_inclusive_amount (BT-112), sans tolérance ;
  • payable_amount (BT-115) à 0 ;
  • payable_rounding_amount (BT-114) absent ou à 0 ;
  • due_date (BT-9) renseignée. Sur une facture déjà payée, elle porte la date du paiement : elle ne peut donc pas être postérieure à issue_date. À la création, un issue_date absent est comparé comme la date du jour.

Un ensemble incohérent fait échouer l'appel en 422, à la création comme à la modification, et rien n'est enregistré : Scribee ne complète pas les montants à votre place (voir Erreurs et cas limites). Sur un PATCH, un champ absent de la charge utile est lu sur la facture enregistrée : passer une facture existante en S2 sans renvoyer ses montants n'est accepté que si les montants déjà enregistrés énoncent le règlement. Le contrôle s'applique aussi quand le code arrive par profile_id : un profile_id valant B2, S2 ou M2 l'emporte sur invoicing_process_id dans le BT-23 des fichiers produits, et il est jugé de la même façon.

Le contrôle ne regarde pas type_code : un avoir déclaré déjà payé est accepté aux mêmes conditions. Il ne s'applique pas aux factures d'achat. Une facture déjà payée ne peut en revanche désigner aucune facture d'acompte par document_id dans invoice_references : elle deviendrait une facture définitive après acompte, dont le cadre B4, S4 ou M4 n'a pas de variante déjà payée, et l'appel répond 422 sans rien enregistrer.

Ce cadre décrit la facture, pas son encaissement : il n'enregistre aucun paiement et ne fait pas passer la facture à 212 Encaissée. Comme sur toute facture, une clé payment_means absente est remplie avec les coordonnées bancaires configurées (voir Les valeurs remplies par défaut) : envoyez vos propres payment_means pour décrire le moyen de paiement réellement utilisé, ou [] pour n'en déclarer aucun.

Pour un paiement par carte (type_code 48), envoyez dans l'entrée payment_means le numéro de carte card_primary_account_number (BT-87, en pratique ses derniers chiffres), le titulaire card_holder_name (BT-88) et le réseau de la carte card_network_id (BT-87-1), par exemple VISA, MASTERCARD ou CB. Le réseau est une valeur libre, sans liste de codes : il est enregistré tel quel, seuls les blancs en début et en fin sont retirés, et la réponse le renvoie dans payment_card.network_id ; payment_card vaut null quand aucun numéro de carte n'est enregistré. Le fichier UBL l'écrit dans cbc:NetworkID, que la syntaxe UBL rend obligatoire à côté du numéro de carte. Sans card_network_id, le brouillon est accepté et reste modifiable, mais le fichier UBL garde le moyen de paiement sous le code 48 sans y écrire aucune information de carte (ni numéro, ni titulaire, ni réseau). Sur une vente qui fait l'objet d'un dépôt de facture, le dépôt est en outre refusé en 422 tant que le réseau manque : renseignez card_network_id par un PATCH, puis déposez à nouveau. Scribee ne le déduit jamais du numéro de carte. Le fichier CII n'a pas d'élément équivalent et ne le porte pas.

Ce qui n'est pas rempli par défaut​

  • customization_id (BT-24, identifiant de spécification) n'est pas enregistré à votre place : il vaut null dans la réponse tant que vous ne l'envoyez pas. Les fichiers UBL, CII et Factur-X générés portent en revanche le profil EXTENDED-CTC-FR, selon lequel la facture est aussi contrôlée au dépôt (Formats et téléchargements). Envoyez la valeur attendue par votre destinataire s'il vise un autre profil. Une partie payer, une partie buyer_agent, seller_agent, invoicee ou invoicer, ainsi qu'un role_code porté par une partie payee, exigent un customization_id de profil EXTENDED-CTC-FR : sans lui, la création comme la modification sont refusées en 422 (voir plus bas), et non acceptées puis mises en échec au téléchargement. Sur un PATCH, c'est le customization_id déjà enregistré qui compte quand la charge utile ne porte pas la clé ; une clé présente l'emporte, y compris avec une chaîne vide, qui efface le profil et fait donc refuser l'appel.
  • upload_source vaut manual sur une facture créée par POST /api/v1/workspaces/{workspace_id}/invoices. Seul POST /api/v1/workspaces/{workspace_id}/invoices/upload écrit api (Importer des factures existantes). Ne vous servez pas de ce champ pour retrouver les factures créées par votre intégration.

Facturer dans une autre devise que l'euro​

currency_code (BT-5) porte la devise de la facture. C'est un code à trois lettres, et l'API n'applique aucune liste de valeurs autorisées : USD, GBP ou CHF sont acceptés comme EUR. C'est aussi le seul champ de devise que vous avez à envoyer.

Dès qu'une facture n'est pas libellée en EUR, la réforme en exige deux de plus : la devise de comptabilisation de la TVA (BT-6), qui doit valoir EUR, et le total de TVA exprimé dans cette devise (BT-111). Scribee les établit lui-même au moment du dépôt :

  • tax_currency_code est écrit à EUR. Si vous en aviez envoyé un autre à la création ou par PATCH, le dépôt le remplace : cette valeur est fixée par la plateforme, jamais reprise de votre charge utile.
  • Le total de TVA de la facture est converti en euros au taux de référence enregistré pour sa date d'émission (issue_date), arrondi au centime, puis figé avec le taux appliqué. Le montant ne bouge plus ensuite : c'est celui que porte le fichier déposé.
  • Les fichiers UBL et CII générés portent alors BT-6 et un second total de TVA en euros, à côté du total exprimé dans la devise de la facture.

De ces trois valeurs, seule tax_currency_code est restituée par l'API. Le taux appliqué et le total de TVA converti ne sont portés par aucun champ de la réponse ; vous les lisez dans les fichiers UBL, CII et Factur-X (Formats et téléchargements).

Sur une facture en EUR, rien de tout cela n'est émis, et c'est délibéré : les contrôles EN 16931 et Peppol refusent une facture dont la devise de TVA répète la devise de facture. Un tax_currency_code envoyé sur une facture en euros est donc remis à vide au dépôt.

Le taux retenu est celui publié pour la date d'émission. Quand aucun taux n'a été publié ce jour-là - week-end, jour férié - le dernier taux publié avant cette date est repris, dans la limite de dix jours pour la plupart des devises, et de trente-cinq jours pour quelques-unes dont le taux de référence paraît avec un décalage plus long. Au-delà, le dépôt est refusé et la facture reste au brouillon (voir Erreurs et cas limites).

Les parties et l'annuaire​

Pour une vente à un acheteur établi hors du territoire français de TVA et ne relevant pas du flux 1, Scribee peut compléter l'adresse électronique BT-49 avec un e-mail (schéma EM) si aucune adresse électronique ni adresse annuaire n'est renseignée. L'e-mail de contact de la facture est prioritaire ; s'il est absent sur un brouillon, le contact par défaut du client lié est utilisé. Au dépôt, cet e-mail est figé sur la facture avant les contrôles du document généré. Une adresse déjà renseignée n'est pas remplacée et ce complément ne déclenche pas d'envoi d'e-mail. BT-49 ne figure pas dans l'extrait fiscal du flux 1.

Une entrée de parties avec un party_id est remplie depuis l'annuaire de l'entreprise : raison sociale, identifiants légaux (SIREN, SIRET), numéro de TVA, adresse de facturation, contact par défaut. Ces données sont copiées sur la facture au moment de la création. Les valeurs déjà copiées ne suivent pas les modifications de la fiche annuaire ; l'e-mail absent peut toutefois être complété sur un brouillon selon la règle BT-49 ci-dessus, puis figé au dépôt. Tout attribut envoyé sur la même entrée l'emporte sur la valeur de l'annuaire ; billing_address_id choisit une adresse de facturation précise, sinon l'adresse de facturation par défaut est retenue. Six entrées acceptent un role_code (code UNCL 3035, par exemple PR) : payer (EXT-FR-FE-44), payee (EXT-FR-FE-26), buyer_agent (EXT-FR-FE-04), seller_agent (EXT-FR-FE-67), invoicee (EXT-FR-FE-90, toujours IV) et invoicer (EXT-FR-FE-113, toujours II). Porté par un autre rôle, il fait échouer l'appel en 422 ; porté par l'une de ces entrées avec une valeur absente de la liste UN/CEFACT PartyRoleCode D22A, il le fait aussi ; et sur une partie payee, il exige en plus un customization_id de profil EXTENDED-CTC-FR (voir Erreurs et cas limites). La comparaison est sensible à la casse - pr est refusé, jamais mis en majuscules à votre place - et une chaîne vide vaut absence, donc ne déclenche aucun refus.

Un SIRET déclaré comme tel est enregistré comme le SIREN de son unité légale. L'annuaire conserve l'identité de l'établissement ; le document, lui, doit porter celle de l'unité légale. Dès que la valeur retenue pour une entrée de parties déclare un legal_registration_scheme_id valant siret (ou son code 0009) et un legal_registration_id de 14 chiffres exactement, la partie créée porte ses 9 premiers chiffres et le schéma siren : la règle française BR-FR-11 exige un SIREN de 9 chiffres sur l'acheteur, et un SIRET recopié tel quel ne la satisfait pas.

La conversion vaut aussi pour le legal_registration_id que vous envoyez vous-même, avec ou sans party_id, sur POST comme sur PATCH, et quel que soit le rôle porté par l'entrée - vente comme achat. Votre valeur explicite l'emporte toujours sur celle de la fiche : c'est bien l'entité que vous nommez qui est retenue, seul le suffixe d'établissement est retiré. Relisez donc la partie dans la réponse plutôt que de tenir votre charge utile pour l'état enregistré. La partie côté entreprise que Scribee ajoute lui-même quand votre charge utile n'en porte aucune échappe à ce chemin : son schéma est résolu depuis la fiche entreprise et peut donc valoir siret (voir plus bas).

Le contrôle est étroit, et trois valeurs passent inchangées : une immatriculation déclarée sous un schéma étranger, qu'elle fasse 14 chiffres ou non - la seule forme ne prouve rien, un numéro étranger de même longueur n'est pas un SIRET ; une immatriculation déclarée sous tout autre schéma ; et une immatriculation dont aucun schéma n'est déclaré, ni par vous ni par la fiche. La fiche client ou fournisseur, elle, n'est jamais réécrite : trois établissements d'une même unité légale restent trois fiches distinctes portant leurs trois SIRET, et seules les factures convergent sur le SIREN.

Dans le CII et l'UBL exportés, le role_code n'est émis que sur les blocs payer, payee, buyer_agent, seller_agent, invoicee et invoicer. Un document reçu ou importé par un autre chemin que cet endpoint n'est soumis ni au contrôle de la liste D22A ni à celui du profil : son role_code de partie payee est émis tel qu'il a été reçu, quel que soit le profil déclaré. Sur une facture d'achat, une facture de vente auto-facturée ou un document importé depuis un fichier UBL, CII ou Factur-X, un role_code enregistré sur un rôle qui n'en porte pas (seller, buyer, tax_representative, delivery) reste stocké et continue d'être renvoyé dans le JSON, mais n'atteint jamais le XML. Il en va de même d'un code autre que IV sur un invoicee ou que II sur un invoicer, et de l'identifier ou du legal_registration_id d'un de ces quatre acteurs reçu sans schéma : aucun code ni identifiant n'est alors émis dans le bloc.

Les rôles sont seller (émet la facture), buyer (la reçoit), payee (encaisse si différent du vendeur), payer (tiers qui paie pour le compte de l'acheteur - à ne pas confondre avec payee : payee est BG-10, la partie payée ; payer est EXT-FR-FE-BG-02, la partie qui paie, et n'a de sens que sous le profil EXTENDED-CTC-FR), tax_representative (représentant fiscal du vendeur) et delivery (partie de livraison). Sur une facture de vente, buyer se résout contre les clients de l'entreprise ; payee, payer et tax_representative contre tout l'annuaire de l'entreprise. Le rôle côté entreprise - seller à la vente - est toujours dérivé de la fiche entreprise : ne lui envoyez pas de party_id, il serait rejeté en 422. Si votre charge utile ne contient pas d'entrée seller, Scribee l'ajoute depuis la fiche entreprise et son établissement siège.

Le legal_registration_scheme_id de cette partie dérivée n'est pas une recopie : Scribee le résout depuis la fiche entreprise, le pays d'immatriculation d'abord, la forme de l'identifiant ensuite. Le legal_identifier d'une entreprise est multinational - SIREN français, EIN, TIN, selon le pays qui l'a immatriculée - et sa seule forme ne prouve donc rien : un numéro étranger de 14 chiffres n'est pas un SIRET, et le déclarer comme tel poserait une fausse identité légale française sur un document que Scribee transmet en tant que Plateforme Agréée.

legal_registering_country de la fichelegal_identifier de la fichelegal_registration_scheme_id de la partie
FR, ou vide14 chiffres exactementsiret
FR, ou vide9 chiffres exactementsiren
FR, ou videtoute autre formenull
tout autre paysquelle qu'elle soitnull

Un legal_registering_country vide vaut France : le champ est facultatif, sur une plateforme française par construction. Un pays explicitement étranger n'est jamais ramené à la France ; la comparaison ignore la casse et les espaces de bord. Le legal_registration_id de la partie reste dans tous les cas le legal_identifier de la fiche, y compris quand aucun schéma n'est déclaré.

Scribee refuse à l'écriture tout legal_identifier d'entreprise française qui n'est pas un SIREN de 9 chiffres (Entreprises et établissements). La ligne siret du tableau ne concerne donc qu'une fiche enregistrée avant ce contrôle, dont ni le legal_identifier ni le legal_registering_country n'ont été modifiés depuis ; la ligne « toute autre forme », une telle fiche ou une fiche sans legal_identifier.

Ne présumez pas que la partie côté entreprise porte siren. Une entreprise française enregistrée avant le contrôle du SIREN peut encore porter un SIRET de 14 chiffres, et donc siret, et une entreprise immatriculée hors de France ne porte aucun schéma. Une intégration qui reconnaît vos entreprises au seul legal_registration_scheme_id valant siren en manque donc une partie : rapprochez sur legal_registration_id, ou acceptez les deux schémas et l'absence de schéma.

La réponse porte aussi, chacun sous sa propre clé, quatre acteurs propres au profil EXTENDED-CTC-FR : buyer_agent (agent de l'acheteur, EXT-FR-FE-BG-01), seller_agent (agent du vendeur, EXT-FR-FE-BG-03), invoicee (EXT-FR-FE-BG-04) et invoicer (tiers facturant, EXT-FR-FE-BG-05). Ils sont renseignés sur les factures reçues ou importées dont le XML UBL ou CII les porte. Vous pouvez aussi les envoyer dans parties, à la création comme à la modification, sous l'un des deux customization_id EXTENDED-CTC-FR ; sous tout autre profil, l'entrée est refusée en 422. Les fichiers ubl, cii et facturx générés les portent alors : en UBL dans cac:AgentParty (les deux agents) et cac:ServiceProviderParty (invoicee côté acheteur, invoicer côté vendeur), en CII dans ram:BuyerAgentTradeParty, ram:SalesAgentTradeParty, ram:InvoiceeTradeParty et ram:InvoicerTradeParty. L'extrait des données réglementaires (flux 1) transmis au PPF ne les porte jamais : son schéma ne les déclare pas. Une facture de vente qui nomme un invoicer n'est déposée que si l'entreprise détient, à la date d'émission, un mandat de facturation tiers facturant actif pour ce tiers, attesté par un administrateur de l'entreprise (XP Z12-014, cas 19a). Ces mandats se créent et s'attestent dans les paramètres de l'entreprise de l'interface Scribee : l'API ne permet ni de les créer, ni de les attester. Voir Erreurs et cas limites.

Quand une facture ou un avoir de vente nomme un invoicer et que l'entreprise détient, à la date d'émission (BT-2), ce mandat de facturation tiers facturant actif, Scribee ajoute aux fichiers ubl, cii et facturx, au PDF et à l'extrait du flux 1 une note de niveau facture de code sujet DCL (BT-21). Le dépôt enregistre sur la facture le mandat sous lequel elle est émise ; sur une facture ainsi déposée, la note suit ce mandat, et une résiliation ou une fin du mandat postérieure au dépôt ne la retire pas des fichiers générés de nouveau ensuite. Son texte (BT-22) déclare la facture établie par le tiers facturant au nom et pour le compte du vendeur, par exemple Facture établie par Compta Services (SIREN 732829320) au nom et pour le compte de Acme SAS (SIREN 552100554). Chaque partie y est désignée par son name, suivi de son SIREN seulement quand son legal_registration_scheme_id vaut siren (0002) et que son legal_registration_id est renseigné ; sous tout autre schéma, le nom figure seul. Le texte est tronqué à 1024 caractères. Cette note n'est pas enregistrée sur la facture : elle n'apparaît pas dans les item_notes relues avec GET /api/v1/invoices/{id}?include=item_notes, ni dans le formulaire d'édition de l'interface Scribee. Si la facture porte déjà une note de niveau facture de code declaration (code UNCL4451 DCL), Scribee n'en ajoute aucune autre. La note n'est ajoutée ni sur une facture de vente auto-facturée, ni sur une facture d'achat reçue. Son absence ne bloque jamais un dépôt : XP Z12-014 (cas 19a) la recommande sans l'exiger.

Deux limites à connaître :

  • name est obligatoire sur seller et buyer. Une entrée buyer envoyée sans party_id et sans name répond 422, avec details indexé par champ. country_code ne l'est pas : Scribee ne fabrique aucun pays, ni sur la charge utile ni en reprenant une fiche client dont l'adresse n'en porte pas, et une partie qui n'en porte aucun se relit à null dans seller.address.country_code et buyer.address.country_code. Envoyez-le quand même : le dépôt le réclame sur les ventes qui font l'objet d'un dépôt de facture, et le refuse s'il manque (voir Le cycle de vie d'une facture).
  • La réponse ne restitue que seller, buyer, payee, payer, tax_representative, buyer_agent, seller_agent, invoicee et invoicer, chacun sous sa propre clé, à null quand la facture n'en porte pas. Une partie delivery est bien enregistrée et exportée, mais n'apparaît pas dans le JSON renvoyé.

:::info Le lieu de livraison : un nom d'un côté, un identifiant de l'autre delivery_location_name porte le nom du lieu (BT-70) - « Entrepôt Paris Nord ». delivery_location_id porte un identifiant codé (BT-71) - un GLN, un SIRET - et n'est exporté que si vous envoyez aussi son schéma dans delivery_location_scheme_id (BT-71-1). La règle BR-FR-CO-10 de la réforme l'exige : un identifiant sans son schéma rend le dépôt invalide, donc Scribee préfère ne pas l'émettre plutôt que produire un fichier refusé.

Envoyez le nom dans delivery_location_name. Un nom placé dans delivery_location_id ne peut être qualifié par aucun schéma : il n'apparaîtra pas dans les fichiers ubl, cii et facturx. :::

Les valeurs remplies par défaut​

Quand la clé est absente de la charge utile, Scribee complète :

  • item_notes (ventes uniquement) : les mentions légales configurées dans l'interface Scribee.
  • payment_means : les coordonnées bancaires configurées dans l'interface Scribee. Si l'entrée buyer est envoyée par nom seul, sans party_id résoluble, aucune coordonnée bancaire n'est insérée : le statut d'affacturage du client ne peut pas être établi.
  • tax_due_date_code (BT-8, ventes uniquement) : le code 5 quand l'entreprise émettrice a opté pour la TVA sur les débits. Il est posé à la création puis figé : une valeur que vous envoyez l'emporte toujours et reste inchangée, et une facture déjà créée ne change pas de code si l'option est prise ou révoquée ensuite.

Un tableau explicitement vide ([]) vide la collection et n'est jamais re-rempli : c'est ainsi qu'un PATCH retire des mentions ou des coordonnées existantes. Seule la note d'une société membre d'un assujetti unique s'y ajoute encore (Une société membre d'un assujetti unique).

Une facture portant le code 5 sort du suivi automatique de la déclaration des paiements, qui ne couvre que les factures de vente sans code d'exigibilité ou portant 72 - ou 432, qui désigne le même point d'exigibilité sur l'autre liste UNTDID (Enregistrer des paiements). Et si la facture porte aussi tax_point_date (BT-7), les fichiers ubl, cii et facturx n'émettent que la date : les deux champs s'excluent mutuellement dans les formats normalisés, alors que la réponse de l'API restitue bien les deux.

Une société membre d'un assujetti unique​

Une vente émise par le membre d'un assujetti unique le déclare. Scribee écrit cette déclaration à votre place, depuis les paramètres d'assujetti unique de la société : ils se renseignent dans l'interface Scribee, et l'API ne les expose ni en lecture ni en écriture.

Quand ces paramètres portent le SIREN de l'assujetti unique et ses coordonnées complètes - raison sociale, numéro de TVA, adresse -, chaque facture de vente créée par POST /api/v1/workspaces/{workspace_id}/invoices reçoit, en plus de ce que vous envoyez :

  • une partie tax_representative (BG-11) qui porte la raison sociale, le numéro de TVA et l'adresse de l'assujetti unique, avec country_code à FR ;
  • une note de niveau facture dont code vaut tax_declaration et content vaut MEMBRE_ASSUJETTI_UNIQUE. Elle s'ajoute aux notes que vous envoyez, y compris quand votre tableau item_notes est vide ;
  • le SIREN de l'assujetti unique sur la partie seller, sous le schéma 0231. Le JSON ne le restitue pas : il n'apparaît que dans les fichiers ubl, cii et facturx, comme identifiant supplémentaire du vendeur (BT-29).

La réponse à la création porte donc tax_representative renseigné ; la note se relit avec include=item_notes. Une facture créée par la conversion d'un devis (POST /api/v1/quotes/{id}/convert) reçoit les trois mêmes éléments, dès lors qu'elle porte une partie seller.

{
"data": {
"tax_representative": {
"name": "Groupe TVA ACME",
"vat_identifier": "FR96552100554",
"address": { "line_1": "1 rue de la Paix", "city": "Paris", "postal_code": "75002", "country_code": "FR" }
}
}
}

Ces valeurs sont figées à la création. Un PATCH sur le brouillon les reprend telles quelles, même si les paramètres de la société ont changé depuis ou si elle a quitté l'assujetti unique. Un brouillon qui ne les porte pas les reçoit au PATCH seulement si la société déclare toujours, avec ses coordonnées complètes, le SIREN d'assujetti unique qu'elle déclarait à la création de la facture.

Ne les envoyez pas vous-même. Pour une société membre, une partie tax_representative, ou une note de niveau facture de code tax_declaration (ou son code UNCL4451 TXD), fait échouer l'appel en 422, même identique à celle que Scribee écrit. Un PATCH qui renvoie la facture telle que la restitue un GET est donc refusé : retirez-en tax_representative et la note tax_declaration avant de la renvoyer. Les notes de ligne ne sont pas concernées. À la création, l'appartenance est lue dans les paramètres actuels de la société ; sur un PATCH, c'est celle que la facture a figée à sa création. Une société qui n'est membre d'aucun assujetti unique peut envoyer sa propre partie tax_representative et ses propres notes tax_declaration, sauf une note dont le texte est MEMBRE_ASSUJETTI_UNIQUE, refusée en 422. Voir Erreurs et cas limites.

Si les paramètres de la société portent le SIREN de l'assujetti unique sans ses coordonnées complètes, la facture ne reçoit aucun des trois éléments, mais la société reste membre : les refus ci-dessus s'appliquent, et le dépôt de la facture est refusé tant que la déclaration n'est pas complète (voir Erreurs et cas limites).

Les factures d'achat ne sont pas concernées, pas plus qu'une facture importée par POST /api/v1/workspaces/{workspace_id}/invoices/upload : elles sont enregistrées telles qu'elles ont été émises.

L'unité de quantité des lignes​

quantity_unit_code, obligatoire sur chaque ligne, doit être un code accepté par le contrôle EN 16931 pour BT-130. Un code que ce contrôle rejette répond 422, dans la même forme qu'une ligne incomplète (voir Erreurs et cas limites). Quelques codes valides à titre d'exemple : C62 (unité), KGM (kilogramme), XPP (pièce).

La nature de la ligne : produit ou service​

product_type sur une ligne vaut service, good ou both. Il est optionnel : si vous ne l'envoyez pas, Scribee déduit la nature de la ligne de son quantity_unit_code - une unité de temps (hour, day, week, month, year, half_year, quarter) est traitée comme un service, tout le reste comme un bien. Cette classification déduit la lettre B, S ou M de BT-23 (cadre de facturation) quand vous n'envoyez pas invoicing_process_id. La mention obligatoire « catégorie d'opération » du PDF lit BT-23 : un invoicing_process_id envoyé (ou un profile_id qui est un code BT-23) décide donc de la mention, quelle que soit la nature des lignes.

La mention du régime de la marge (BT-21)​

Une vente au régime de la marge porte sa mention dans une note de niveau facture : une entrée de item_notes dont code vaut value_added_tax_margin_scheme et dont content porte le texte de la mention. code accepte aussi le code UNCL4451 brut AVE ; la réponse renvoie toujours la clé.

{
"item_notes": [
{ "code": "value_added_tax_margin_scheme", "content": "Régime particulier - Biens d'occasion" }
]
}

Le texte est le vôtre. Scribee n'ajoute jamais cette note de lui-même et n'en rédige jamais le contenu, même quand la ventilation de TVA désigne une vente au régime de la marge. Comme tout tableau item_notes envoyé, celui-ci remplace les mentions légales que Scribee aurait complétées (Les valeurs remplies par défaut) : placez-les dans le même tableau.

En sortie, la note devient ram:IncludedNote avec ram:SubjectCode AVE en CII et en Factur-X, et en UBL cbc:Note, dont le texte est préfixé de #AVE#. Une facture reçue ou importée qui porte une note sous le code AVE, en UBL, en CII ou en Factur-X, la conserve avec son texte tel quel ; elle se relit sous la clé value_added_tax_margin_scheme avec include=item_notes.

La note de ligne (BT-127)​

Chaque ligne accepte son propre tableau item_notes, distinct des item_notes de niveau facture (BT-21 / BT-22). content porte BT-127, le texte de la note ; code porte EXT-FR-FE-183, le code sujet de cette note - une extension française, la norme EN 16931 ne définissant aucun code sujet au niveau ligne. code accepte la clé Scribee ou le code UNCL4451 brut ; la réponse renvoie toujours la clé.

{
"lines": [
{
"line_id": "1",
"article_name": "Lave-linge",
"item_notes": [
{ "code": "general_information", "content": "Eco-contribution DEEE" }
]
}
]
}

Relisez la note avec GET /api/v1/invoices/{id}?include=lines : elle revient dans item_notes sur la ligne. En sortie Factur-X (CII) le couple devient ram:Content et ram:SubjectCode ; en UBL, où une ligne ne porte qu'un seul cbc:Note, le code est préfixé au texte sous la forme #AAI#Eco-contribution DEEE.

Les identifiants d'objet facturé (BT-128)​

object_identifier porte l'identifiant d'objet facturé de la ligne (BT-128), par exemple un numéro de compteur, et object_identifier_scheme_id son schéma (BT-128-1). Le profil EXTENDED-CTC-FR admet plusieurs identifiants sur une même ligne : les suivants se déclarent dans le tableau additional_object_identifiers, dont chaque entrée porte identifier et, facultativement, scheme_id. Le couple object_identifier / object_identifier_scheme_id reste toujours le premier identifiant de la ligne ; le tableau porte les suivants, dans l'ordre où vous les envoyez.

{
"lines": [
{
"line_id": "1",
"article_name": "Acheminement",
"object_identifier": "51214922223746",
"object_identifier_scheme_id": "AVE",
"additional_object_identifiers": [
{ "identifier": "C5", "scheme_id": "AWA" },
{ "identifier": "30001234567890", "scheme_id": "ACD" }
]
}
]
}

Chaque entrée du tableau est contrôlée, et l'appel échoue en 422 si l'une d'elles est refusée :

  • identifier est obligatoire, 255 caractères au plus ;
  • scheme_id doit être un code de la liste UNTDID 1153 retenue par la règle EN 16931 BR-CL-07 ; la comparaison est sensible à la casse, et une chaîne vide vaut absence ;
  • la ligne doit porter un object_identifier : un identifiant supplémentaire sans premier identifiant est refusé.

À la création, ce refus prend la forme d'une ligne de détail incomplète (voir Erreurs et cas limites) et aucune facture n'est créée ; sur un PATCH, le brouillon reste inchangé.

Relisez les identifiants avec GET /api/v1/invoices/{id}?include=lines : chaque ligne renvoie additional_object_identifiers, un tableau vide quand elle porte au plus un identifiant. Une facture reçue en UBL ou en CII conserve de la même façon tous les identifiants de chaque ligne, dans l'ordre du fichier.

Dans les fichiers produits, chaque identifiant devient un élément distinct, dans le même ordre : un cac:DocumentReference de cbc:DocumentTypeCode 130 en UBL, un ram:AdditionalReferencedDocument de ram:TypeCode 130 en CII, où le schéma est écrit dans ram:ReferenceTypeCode. Le PDF les liste tous. Hors du profil EXTENDED-CTC-FR, la norme EN 16931 n'admet qu'un identifiant par ligne : une facture dont le customization_id désigne un autre profil est acceptée à l'écriture, mais le téléchargement ubl ou cii échoue en 422 dès qu'une ligne en porte plusieurs (Formats et téléchargements).

Commande, avis d'expédition et livraison à la ligne​

Chaque ligne peut désigner sa propre commande, son propre avis d'expédition et son propre lieu de livraison, distincts de ceux de l'en-tête. Hormis order_line_reference (BT-132), ces champs sont des extensions françaises propres au profil EXTENDED-CTC-FR : la norme EN 16931 n'en définit aucun au niveau ligne.

Champ de ligneTermeContenu
order_line_referenceBT-132Référence de la ligne de commande
purchase_order_referenceEXT-FR-FE-135Numéro de la commande
despatch_advice_referenceEXT-FR-FE-140Numéro de l'avis d'expédition
despatch_advice_line_referenceEXT-FR-FE-141Ligne de l'avis d'expédition
despatch_advice_dateEXT-FR-FE-201Date de l'avis d'expédition
delivery_location_idEXT-FR-FE-146Identifiant du lieu de livraison
delivery_location_scheme_idEXT-FR-FE-148Schéma de cet identifiant, un code ICD ISO 6523 à quatre chiffres (0088, par exemple)
delivery_location_nameEXT-FR-FE-149Nom du lieu de livraison
delivery_address_line_1, delivery_address_line_2, delivery_address_line_3, delivery_address_postal_code, delivery_address_city, delivery_address_region_codeEXT-FR-FE-151 à EXT-FR-FE-156Adresse de livraison (EXT-FR-FE-150)
delivery_countryEXT-FR-FE-157Code pays de l'adresse de livraison
{
"lines": [
{
"line_id": "1",
"article_name": "Palette",
"order_line_reference": "OL-7",
"purchase_order_reference": "PO-2024-001",
"despatch_advice_reference": "DESADV-42",
"despatch_advice_line_reference": "3",
"despatch_advice_date": "2024-01-10",
"delivery_location_id": "3012345678901",
"delivery_location_scheme_id": "0088",
"delivery_location_name": "Entrepot Lyon Sud",
"delivery_address_city": "Lyon",
"delivery_country": "FR"
}
]
}

Trois règles lient ces champs entre eux :

  • despatch_advice_reference est obligatoire dès que la ligne porte despatch_advice_line_reference ou despatch_advice_date ;
  • delivery_location_id et delivery_location_scheme_id vont ensemble : l'un sans l'autre est refusé. C'est la différence avec l'identifiant du lieu de livraison de l'en-tête, accepté sans schéma mais alors jamais exporté ;
  • delivery_country est obligatoire dès que la ligne porte l'un des champs delivery_address_*.

À la création, une ligne qui enfreint l'une de ces règles fait échouer l'appel en 422, dans la même forme qu'une ligne de détail incomplète (voir Erreurs et cas limites).

Relisez ces champs avec GET /api/v1/invoices/{id}?include=lines. Chaque ligne renvoie order_line_reference et purchase_order_reference tels quels, puis deux objets :

  • despatch_advice regroupe reference, line_reference et issue_date. Il vaut null quand la ligne n'a pas de despatch_advice_reference.
  • delivery regroupe location_name, location_id, location_scheme_id et address. Il vaut null quand la ligne ne porte ni identifiant, ni nom, ni aucun champ d'adresse ou de pays. address (line_1, line_2, line_3, city, postal_code, country_subdivision, country_code) vaut null quand la ligne n'a ni champ d'adresse ni pays.

Dans les fichiers produits, la commande de la ligne devient ram:BuyerOrderReferencedDocument/ram:IssuerAssignedID en CII et en Factur-X, cac:OrderLineReference/cac:OrderReference/cbc:ID en UBL. L'avis d'expédition devient ram:DespatchAdviceReferencedDocument en CII, cac:DespatchLineReference en UBL. La livraison devient un ram:ShipToTradeParty sous le ram:SpecifiedLineTradeDelivery de la ligne en CII, un cac:Delivery de la ligne en UBL, qui porte l'identifiant et l'adresse dans cac:DeliveryLocation et le nom dans cac:DeliveryParty. L'adresse n'est émise qu'avec son pays.

:::warning Ces champs ne sont transmis que sous le profil EXTENDED-CTC-FR, et l'UBL exige deux numéros de ligne Hors order_line_reference, ces champs ne sont émis en ubl, cii et facturx que sous le profil EXTENDED-CTC-FR. Sous un autre profil - un customization_id EN 16931 ou Peppol, par exemple - ils sont omis des fichiers produits, sans erreur : le téléchargement réussit, et la facture les conserve et les renvoie avec GET /api/v1/invoices/{id}?include=lines. Une facture de vente créée par l'API sans customization_id est produite sous EXTENDED-CTC-FR et n'est pas concernée.

Sous ce profil, l'UBL impose en plus un numéro de ligne là où le CII n'en exige pas : purchase_order_reference n'y est transmis qu'avec order_line_reference, et despatch_advice_reference qu'avec despatch_advice_line_reference. Si la ligne porte le premier sans le second, le téléchargement ubl échoue en 422 en nommant les lignes, tandis que cii et facturx transmettent la valeur telle qu'enregistrée. Scribee n'invente jamais le numéro manquant. :::

Les débours​

Une ligne de vente se déclare débours avec le booléen disbursement : true la marque, false ou l'absence de la clé la laisse non marquée. Scribee ne déduit jamais le débours de la catégorie de TVA : une ligne en catégorie O (hors champ de la TVA) sans disbursement reste une ligne ordinaire, tout comme une ligne en catégorie E sous VATEX-EU-79-C. En lecture, GET /api/v1/invoices/{id}?include=lines renvoie disbursement sur chaque ligne, false compris.

{
"lines": [
{
"line_id": "2",
"article_name": "Frais de greffe",
"quantity": 1,
"quantity_unit_code": "one",
"article_unit_price_excluding_taxes": 300.0,
"line_extension_amount": 300.0,
"tax_category_id": "O",
"disbursement": true
}
]
}

Un débours peut aussi s'énoncer en catégorie E (exonérée), avec le motif d'exonération VATEX-EU-79-C porté par la ligne elle-même, dans tax_exemption_reason_code, et son libellé dans tax_exemption_reason. La ventilation tax_subtotals, que vous envoyez comme pour toute facture, porte alors une ligne de même catégorie et de même code, sans montant de TVA :

{
"lines": [
{
"line_id": "2",
"article_name": "Frais de greffe",
"quantity": 1,
"quantity_unit_code": "one",
"article_unit_price_excluding_taxes": 300.0,
"line_extension_amount": 300.0,
"tax_category_id": "E",
"vat_rate": 0,
"tax_exemption_reason_code": "VATEX-EU-79-C",
"tax_exemption_reason": "Débours",
"disbursement": true
}
],
"tax_subtotals": [
{ "tax_category_id": "E", "vat_rate": 0, "vat_amount": 0, "amount_without_taxes": 300.0, "currency_code": "EUR", "tax_exemption_reason_code": "VATEX-EU-79-C", "tax_exemption_reason": "Débours" }
]
}

En lecture, l'objet tax de chaque ligne renvoie tax_exemption_reason_code et tax_exemption_reason à côté de category_code et percent, null quand la ligne n'en porte pas.

Une remise ou une charge de niveau facture (allowance_charges) accepte elle aussi tax_exemption_reason_code et tax_exemption_reason, et GET /api/v1/invoices/{id}?include=allowance_charges les renvoie. Quand la ventilation porte, à côté de la ligne E sous VATEX-EU-79-C, une autre ligne E sous un autre code d'exonération, c'est ce code qui désigne la ligne de ventilation à laquelle la remise ou la charge se rattache : envoyez VATEX-EU-79-C sur celle qui porte sur les débours. Quand deux lignes E de même taux partagent le même code et ne diffèrent que par leur tax_exemption_reason, c'est ce libellé qui les départage : envoyez sur la remise ou la charge le libellé de la ligne de ventilation visée.

Les codes d'exonération tax_exemption_reason_code des lignes, de la ventilation tax_subtotals et des remises et charges sont enregistrés débarrassés de leurs espaces de début et de fin, et en majuscules : vatex-eu-79-c est enregistré et renvoyé VATEX-EU-79-C.

Cinq règles encadrent le champ :

  • il n'est accepté que sur une ligne en catégorie O, ou en catégorie E avec un tax_exemption_reason_code valant VATEX-EU-79-C : sur toute autre ligne - une ligne E sans code d'exonération ou sous un autre code comprise -, true fait échouer l'appel en 422 ;
  • une ligne marquée ne porte pas de TVA : envoyée avec un vat_rate non nul, elle fait échouer l'appel en 422. Scribee ne ramène pas son taux à 0, comme il le fait pour une ligne non marquée en catégorie O ou E. Envoyée sans vat_rate, une ligne marquée en catégorie E est enregistrée au taux 0 ; en catégorie O, elle reste sans taux ;
  • le code VATEX-EU-79-C n'est accepté que sur une ligne en catégorie E, marquée ou non : sur une ligne d'une autre catégorie, il fait échouer l'appel en 422 ;
  • il n'est accepté que sur une facture de vente : sur une facture d'achat, une ligne à true fait échouer la création comme la modification en 422 ;
  • sur un PATCH, les lignes sont reconstruites (voir l'étape 2) : une ligne marquée renvoyée sans la clé redevient non marquée. Renvoyez disbursement sur chaque ligne qui doit le rester.

Les refus sont détaillés dans Erreurs et cas limites. Le marquage n'apparaît dans aucun fichier produit : aucun terme de la norme ne le porte, et les fichiers ubl, cii et facturx ne changent pas selon qu'une ligne est marquée ou non.

Il change en revanche ce qui est transmis et déclaré. Une facture de vente dont chaque ligne est marquée, et dont chaque ventilation de TVA est en catégorie O - ou E avec un tax_exemption_reason_code valant VATEX-EU-79-C - sans montant de TVA, sort de la réforme : elle n'est pas déposée auprès du PPF, aucune copie n'en part par Peppol et aucun statut de cycle de vie n'est transmis pour elle ; elle n'est ni déclarée par une facture d'e-reporting, ni comptée dans l'agrégat B2C, et ses paiements ne sont pas déclarés (Déclarer les transactions). Elle passe pourtant en 200 au dépôt comme toute facture : seuls les envois réglementaires n'ont pas lieu. Une seule ligne non marquée, ou une ventilation qui porte de la TVA, suffit à la maintenir dans le circuit ordinaire. Seul le marquage décide : le code VATEX-EU-79-C ne sort à lui seul aucune facture de la réforme, et une facture dont les lignes sont en catégorie E sous ce code sans porter disbursement suit le circuit de toute facture. Une facture qui mêle lignes taxables et lignes de débours suit donc le circuit de toute facture, débours compris : pour un acheteur porteur d'un SIREN et établi dans le territoire de TVA français, elle est déposée auprès du PPF avec ses lignes de débours.

À l'inverse, une facture dont toute la ventilation de TVA est en catégorie O mais dont une ligne au moins n'est pas marquée reste dans le circuit ordinaire. Pour un tel acheteur, et pour une société déclarée dans la vague d'émission, son dépôt est refusé en 422, car le PPF rejette un flux 1 dont toute la ventilation de TVA est en catégorie O (Le cycle de vie d'une facture). S'il s'agit de débours, marquez chaque ligne avec disbursement ; sinon, corrigez les catégories de TVA ; puis redéposez la facture.

Une telle facture mixte dont les débours sont en catégorie O exige un customization_id de profil EXTENDED-CTC-FR. Sous un profil EN 16931, les fichiers produits sont contrôlés sur la règle BR-O-12, qui interdit qu'une facture portant une ventilation de TVA en catégorie O contienne une ligne d'une autre catégorie ; les règles EXTENDED-CTC-FR ne la contiennent pas.

Le type de facture​

Le type est choisi à la création via type_code. L'API accepte la clé Scribee ou le code UNTDID 1001 équivalent, et renvoie toujours la clé. Une valeur hors de cette liste répond 422.

type_codeUNTDID 1001Libellé
invoice380Facture
self_billed_invoice389Facture auto-facturée
factored_invoice393Facture affacturée
self_billed_factored_invoice501Facture auto-facturée affacturée
retainer_invoice386Facture d'acompte
self_billed_retainer_invoice500Facture d'acompte auto-facturée
corrected_invoice384Facture rectificative
self_billed_corrected_invoice471Facture rectificative auto-facturée
corrected_factored_invoice472Facture rectificative affacturée
self_billed_corrected_factored_invoice473Facture rectificative auto-facturée affacturée
credit_note381Avoir
self_billed_credit_note261Avoir auto-facturé
factored_credit_note396Avoir affacturé
self_billed_factored_credit_note502Avoir auto-facturé affacturé
retainer_credit_note503Avoir d'acompte
consolidated_credit_note262Avoir récapitulatif

L'auto-facturation (self_billed_*) désigne une facture établie par l'acheteur au nom du vendeur. Elle n'a rien à voir avec l'autoliquidation de TVA, qui se déclare par tax_category_id valant AE sur les lignes et les ventilations.

Facture d'acompte et facture définitive après acompte​

Une facture d'acompte se crée comme toute facture, avec type_code valant retainer_invoice (386) ou self_billed_retainer_invoice (500). Sur ces deux types, comme sur retainer_credit_note (503), invoicing_process_id (BT-23) refuse les cadres de facture définitive après acompte B4, S4 et M4 : l'appel répond 422.

La facture définitive qui solde des acomptes les cite dans invoice_references (BG-3), une entrée par facture d'acompte. Chaque entrée prend l'une de deux formes :

  • les valeurs elles-mêmes : invoice_number (BT-25), invoice_date (BT-26) et type_code (EXT-FR-FE-02), le type de la facture citée. type_code accepte la même liste que le type de la facture, clé Scribee ou code UNTDID 1001, et une valeur hors de cette liste répond 422 ;
  • document_id, l'identifiant Scribee de l'une de vos factures d'acompte : Scribee en recopie le numéro, la date d'émission et le type, et les autres valeurs de l'entrée sont ignorées. La facture désignée doit être une facture de vente de la même entreprise, de type retainer_invoice ou self_billed_retainer_invoice, dont le numéro n'est plus provisoire (ni DRAFT- ni TEMP-), émise dans le même currency_code que la facture définitive, et adressée au même acheteur : la partie buyer des deux factures porte le même party_id. Un acheteur envoyé sans party_id ne permet de désigner aucune facture d'acompte. Une facture de type retainer_invoice, self_billed_retainer_invoice ou retainer_credit_note ne solde aucun acompte : elle ne peut désigner aucune facture d'acompte par document_id, et son prepaid_amount n'est jamais calculé. Sinon l'appel répond 422 (voir Erreurs et cas limites).

Relisez les références avec GET /api/v1/invoices/{id}?include=invoice_references : chaque entrée renvoie type_code et document_id, ce dernier à null pour une entrée envoyée par ses valeurs.

Lorsqu'une facture définitive solde des factures d'acompte déjà comptées dans l'agrégat B2C, ces acomptes en sont repris (Déclarer les transactions), dans deux cas : la facture définitive est déposée auprès du PPF ou déclarée dans les données de transaction (10.1), ou elle est elle-même comptée dans l'agrégat B2C, où seul le solde reste alors déclaré. Le montant des acomptes se porte dans prepaid_amount (BT-113) : ne les déduisez pas en plus par une ligne négative.

Pour une société déclarée dans la vague d'émission, le dépôt de la facture définitive est refusé en 422, avant tout comptage ou reprise, lorsque l'une de ces factures d'acompte :

  • n'est citée que par son numéro, sans document_id. Renvoyez par un PATCH cette entrée de invoice_references avec le document_id de la facture d'acompte, adressée à la même fiche client que la facture définitive, puis redéposez la facture ;
  • est désignée par document_id mais n'est pas adressée à la même fiche client que la facture définitive : les parties buyer des deux factures ne portent pas le même party_id, ou l'une d'elles est saisie directement, sans party_id. Une facture définitive dont l'acheteur n'a pas de party_id ne rattache donc aucune facture d'acompte avec certitude, et son dépôt est refusé. L'API ne lève pas ce refus et n'a aucun champ pour le faire : seul un utilisateur autorisé à modifier le brouillon peut confirmer, depuis la page de la facture dans l'interface Scribee, que la facture d'acompte se rapporte bien à cette opération. Le message nomme les factures d'acompte concernées et renvoie à cette confirmation. Elle est enregistrée dans la traçabilité de la facture et ne vaut que pour les deux acheteurs présents au moment où elle est donnée : la fiche client de chacun ou, pour un acheteur saisi directement sans party_id, son name, son legal_registration_id et son legal_registration_scheme_id, sans tenir compte des espaces en début, en fin ou répétés ni de la casse. Si l'acheteur de l'une ou l'autre facture change de fiche client, en prend une ou n'en a plus, ou si l'un de ces trois champs d'un acheteur saisi directement est modifié, sur la facture définitive comme sur la facture d'acompte, le rapprochement redevient incertain : le dépôt, y compris par l'API, est de nouveau refusé jusqu'à ce qu'il soit confirmé à nouveau. Une fois le rapprochement confirmé, redéposez la facture ;
  • a déjà été reprise de l'agrégat B2C pour une autre facture définitive : la solder une seconde fois la laisserait comptée en totalité ou reprise deux fois. Retirez-la de cette facture, ou corrigez la facture définitive qui l'a soldée ;
  • a été reprise de l'agrégat B2C pour une autre facture définitive, annulée ou rejetée depuis, si bien que la reprise a été compensée et l'acompte déclaré à nouveau : un acompte n'est repris qu'une fois. Émettez une nouvelle facture d'acompte, ou retirez-la de cette facture ;
  • a été comptée dans l'agrégat B2C d'une autre entreprise avant d'être transférée à celle-ci : elle ne peut être reprise que de la déclaration de cette entreprise-là. Soldez-la depuis l'entreprise qui l'a déclarée, ou retirez-la de cette facture ;
  • est désignée par document_id mais n'appartient plus à la même entreprise que la facture définitive, l'une des deux ayant été transférée depuis : une facture ne solde que les acomptes de sa propre entreprise, et ils ne peuvent être repris que de la déclaration de l'entreprise qui les a déclarés. À la différence du cas précédent, ce n'est pas l'acompte qui a rejoint l'entreprise de la facture définitive après avoir été compté ailleurs : les deux factures se trouvent aujourd'hui dans des entreprises différentes. Replacez-les dans la même entreprise, ou retirez la facture d'acompte de cette facture ;
  • est aussi déduite par une ligne négative qui cite son numéro dans invoice_reference_number : elle serait déduite deux fois ;
  • a des encaissements déjà déclarés en données de paiement, ou en attente de l'être. Cela comprend une donnée de paiement que vous avez déclarée vous-même, par l'API ou par import CSV, dans un rapport de paiements de rôle vendeur de l'une des entreprises du workspace, et qui désigne la facture d'acompte : son invoice_number est exactement le numéro de la facture d'acompte et, lorsqu'elle porte une invoice_date, cette date est la date d'émission de la facture d'acompte ; ou son invoice_number est exactement le numéro que conserve l'entrée de invoice_references de la facture définitive dont le document_id désigne la facture d'acompte et, lorsque la donnée de paiement et cette entrée portent chacune une date, ces deux dates sont égales. Cette entrée garde le numéro et la date recopiés lorsqu'elle a été écrite, même si la facture d'acompte a été renumérotée ou redatée depuis. Une donnée de paiement sans numéro de facture ne désigne aucune facture d'acompte. Ce cas ne vaut que pour une facture définitive déposée auprès du PPF ou déclarée dans les données de transaction (10.1) ; ces encaissements n'empêchent ni le dépôt ni la reprise d'une facture définitive comptée elle-même dans l'agrégat B2C.
  • pourrait avoir pour encaissement une donnée de paiement que l'entreprise - ou une autre entreprise du même workspace - détient sans savoir à quelle facture elle se rapporte : une donnée de paiement déclarée par Scribee à partir d'un paiement de facture - ou déclarée avant que Scribee n'enregistre qui la déclarait - qui ne désigne plus ni sa facture ni son paiement, quelle que soit sa date - un acompte encaissé peut précéder la facture d'acompte -, et qui ne porte aucun numéro de facture, porte celui de la facture d'acompte, ou porte le numéro que conserve l'entrée de invoice_references dont le document_id désigne la facture d'acompte, à la même date lorsque cette donnée et cette entrée en portent chacune une. Reprendre l'acompte laisserait cet encaissement déclaré à côté de lui. Comme le cas précédent, celui-ci ne vaut que pour une facture définitive déposée auprès du PPF ou déclarée dans les données de transaction (10.1). Les données de paiement que vous déclarez vous-même, par l'API ou par import CSV, ne déclenchent jamais ce cas-ci : celle qui désigne la facture d'acompte relève du cas précédent. Le message vous invite à contacter le support, qui rattache chacun de ces encaissements à sa facture ; redéposez ensuite la facture.

Une facture rectificative (corrected_invoice, corrected_factored_invoice ou leur variante auto-facturée) dont invoice_references cite une facture définitive dont la reprise est écrite et non compensée ne déduit pas en plus les acomptes repris par une ligne négative qui cite leur numéro dans invoice_reference_number : la reprise reste en place tant que la facture rectificative remplace la facture définitive (La reprise compensée après l'annulation ou le rejet de la facture définitive), et ces acomptes ne seraient déclarés nulle part. Pour une société déclarée dans la vague d'émission, le dépôt d'une telle facture rectificative, destinée au PPF, aux données de transaction (10.1) ou à l'agrégat B2C, est refusé en 422, avec le code operation_failed. Le message d'erreur nomme les factures d'acompte concernées, et la facture reste un brouillon. Supprimez ces lignes négatives - les acomptes sont portés dans prepaid_amount (BT-113) - puis redéposez la facture.

Une facture définitive comptée dans l'agrégat B2C qui ne porte aucune partie buyer ne rattache de même aucune facture d'acompte avec certitude : son dépôt est refusé, sauf rapprochement par document_id confirmé par un utilisateur comme ci-dessus. Le message d'erreur nomme les factures d'acompte concernées, et la facture reste un brouillon.

Une facture définitive entrée dans Scribee par fichier, dont la reprise est écrite, ne revient plus en brouillon : revert_to_draft répond 422 avec le message Cette facture ne peut pas repasser en brouillon : son dépôt a repris de la déclaration des données de transaction B2C journalières les mensualités qu'elle solde, et cette correction est déclarée. La repasser en brouillon laisserait ces mensualités reprises sans facture qui les solde. Émettez plutôt un avoir pour la corriger., et n'apparaît plus dans lifecycle_available_transitions. Corrigez-la par un avoir.

De même, une facture d'acompte entrée dans Scribee par fichier, dont le comptage dans l'agrégat B2C a été repris par la facture définitive qui la solde, ne revient plus en brouillon : revert_to_draft répond 422 avec le message Cette facture de mensualité ne peut pas repasser en brouillon : la facture finale qui la solde l'a reprise de la déclaration des données de transaction B2C journalières, et cette correction est déclarée. Modifiée puis déposée à nouveau, elle ne pourrait pas être déclarée de nouveau à sa place, et les déclarations ne lui correspondraient plus. Émettez plutôt un avoir pour la corriger., et n'apparaît plus dans lifecycle_available_transitions. Corrigez-la par un avoir.

Ces contrôles ne s'appliquent pas à une facture définitive qui n'est déclarée nulle part, et dont aucun acompte n'est donc repris : une vente à un autre membre du même assujetti unique, ou une facture sortie de la réforme parce qu'elle ne porte que des débours.

Le cadre de facturation d'une facture définitive se déclare dans invoicing_process_id : B4 pour des biens, S4 pour des services, M4 pour les deux. Envoyez-le avec la facture définitive : invoicing_process_id reste null dans la réponse si vous ne l'envoyez pas.

Le montant des acomptes déjà versés se porte dans prepaid_amount (BT-113). Lorsque toutes les entrées de invoice_references de type retainer_invoice ou self_billed_retainer_invoice sont désignées par document_id, Scribee calcule ce montant lui-même et remplace les valeurs envoyées : prepaid_amount devient la somme des tax_inclusive_amount (BT-112) des factures d'acompte désignées, et payable_amount (BT-115) vaut tax_inclusive_amount moins cette somme, plus payable_rounding_amount. Ce calcul a lieu à la création, et lors d'un PATCH qui envoie invoice_references. Dès qu'une de ces entrées est envoyée par ses valeurs, Scribee conserve prepaid_amount et payable_amount tels que vous les envoyez.

Une ligne peut elle aussi citer une facture antérieure, par exemple la ligne qui reprend un acompte (EXT-FR-FE-BG-06) : invoice_reference_number (EXT-FR-FE-136), invoice_reference_date (EXT-FR-FE-138), invoice_reference_type_code (EXT-FR-FE-137, même liste que type_code) et invoice_reference_line_id (EXT-FR-FE-139). Ces valeurs reviennent sur la ligne dans l'objet invoice_reference, sous les clés invoice_number, invoice_date, type_code et line_id ; l'objet vaut null tant que invoice_reference_number est vide.

Dans les fichiers ubl, cii et facturx, le numéro et la date des entrées de invoice_references sont toujours émis. Leur type_code, ainsi que la référence portée par une ligne dans son ensemble, ne sont émis que sous l'un des deux customization_id EXTENDED-CTC-FR (les valeurs que cite l'erreur payer plus bas). La réponse de l'API restitue ces valeurs quel que soit le profil.

Opération triangulaire​

triangular_position indique la position de votre entreprise dans une opération triangulaire intracommunautaire : first_supplier (premier fournisseur), intermediary (intermédiaire) ou final_customer (acquéreur final). Ce n'est pas un champ EN16931. Il vaut null sur toute facture qui n'en relève pas, et c'est sa valeur tant que vous ne le renseignez pas : Scribee ne le déduit jamais de la facture. Il est renvoyé à chaque lecture de la facture.

Il s'envoie dans l'objet invoice, à la création (POST /api/v1/workspaces/{workspace_id}/invoices) comme à la modification du brouillon (PATCH /api/v1/invoices/{id}). Les valeurs admises dépendent de direction :

directionValeurs admises
salesfirst_supplier, intermediary
purchasesintermediary, final_customer

Une autre valeur - une valeur hors de cette liste, ou une valeur que la direction n'admet pas, comme final_customer sur une facture de vente - est refusée en 422 et rien n'est enregistré (voir Erreurs et cas limites). null et la chaîne vide valent absence de position.

En modification, ce champ ne suit pas tout à fait la règle des scalaires décrite à l'étape 2 : omis, il conserve la position enregistrée ; envoyé à null ou à "", il l'efface.

L'import de fichier (POST /api/v1/workspaces/{workspace_id}/invoices/upload) ne l'accepte pas : une facture importée porte null, et la position se renseigne ensuite par PATCH /api/v1/invoices/{id} tant qu'elle est un brouillon.

Sur une facture de vente, intermediary change ce que Scribee déclare en e-reporting : voir Déclarer les transactions.

Fournir votre propre PDF​

Le champ pdf_base64, envoyé dans l'objet invoice de ce même appel, remplace le lisible généré par Scribee par votre propre PDF. Ses contraintes, ses contrôles synchrones et ses cinq causes de 422 sont détaillés dans Fournir votre propre PDF. Il n'est accepté qu'à la création : PATCH l'ignore.

Créer et déposer en un seul appel​

Le champ lifecycle_state, envoyé à l'intérieur de l'objet invoice, fusionne cette étape et l'étape 4 : la facture est créée puis immédiatement déposée dans le même appel. Sur une facture de vente, la seule valeur qui fait avancer le cycle de vie est deposited ; draft est acceptée mais n'a aucun effet - c'est la création ordinaire décrite ci-dessus.

attention

Le dépôt demandé via lifecycle_state est tout-ou-rien. S'il échoue - modèle de numérotation absent, l'une des causes de la section Erreurs et cas limites - toute la création est annulée : ni la facture, ni ses lignes n'existent. C'est différent des quatre champs de niveau facture de l'étape 1, dont l'absence n'empêche pas la création.

curl -X POST https://app.scribee.tech/api/v1/workspaces/YOUR_WORKSPACE_ID/invoices \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"company_id": 317,
"invoice": {
"direction": "sales",
"invoice_number": "DRAFT-CRM-2026-0043",
"issue_date": "2026-07-31",
"due_date": "2026-08-30",
"type_code": "invoice",
"currency_code": "EUR",
"lifecycle_state": "deposited",
"parties": [
{ "role": "buyer", "party_id": 42 }
],
"lines": [
{
"line_id": "1",
"article_name": "Prestation de conseil",
"quantity": 2.0,
"quantity_unit_code": "day",
"article_unit_price_excluding_taxes": 500.0,
"line_extension_amount": 1000.0,
"tax_category_id": "S",
"vat_rate": 20.0
}
],
"tax_subtotals": [
{ "tax_category_id": "S", "vat_rate": 20.0, "vat_amount": 200.0, "amount_without_taxes": 1000.0, "currency_code": "EUR" }
],
"total_amount_excluding_taxes": 1000.0,
"total_tax_amount": 200.0,
"tax_inclusive_amount": 1200.0,
"payable_amount": 1200.0
}
}'

Réponse 201, la facture est déjà à l'état deposited (200 Déposée) avec son numéro définitif :

{
"data": {
"id": 12346,
"invoice_number": "FAC-2026-0199",
"lifecycle_state": "deposited",
"lifecycle_status_code": "200",
"lifecycle_available_transitions": ["collect"]
}
}

Étape 2 : modifier le brouillon​

PATCH /api/v1/invoices/{id} ne fonctionne que sur un brouillon et ne transmet rien. Deux règles s'appliquent, différentes selon le type de champ :

  • Les collections sont détruites puis reconstruites à chaque appel : parties, lines, tax_subtotals, payment_means, item_notes, allowance_charges, invoice_references. Une collection absente de la charge utile est vidée, pas conservée. Un PATCH qui omet parties laisse la facture sans acheteur ; les défauts (seller, mentions légales, coordonnées bancaires) sont ensuite réappliqués comme à la création.
  • Les champs scalaires absents sont conservés tels quels. Omettre due_date ne l'efface pas. Vous ne pouvez donc pas vider un scalaire en l'omettant.

Une collection fait exception à la première règle : margin_bases, les bases de marge d'une vente au régime de la marge. Absente de la charge utile, elle conserve les bases enregistrées ; un tableau les remplace, [] les efface. Un PATCH dont margin_bases est la seule clé ne modifie que ces bases : le reste de la facture reste tel qu'enregistré, sans reconstruction des collections ni aucun des trois effets de bord ci-dessous (voir Les ventes au régime de la marge).

Renvoyez la facture entière : c'est la seule forme dont le résultat soit prévisible.

Pour une société membre d'un assujetti unique, retirez-en la partie tax_representative et la note tax_declaration que Scribee a écrites : les renvoyer fait échouer l'appel en 422, et Scribee les réécrit de lui-même (Une société membre d'un assujetti unique).

Trois effets de bord à connaître :

  • direction et pdf_base64 sont acceptés par l'endpoint puis ignorés. Les envoyer ne produit ni changement ni erreur.
  • Le PATCH purge les quatre formats déjà générés ainsi que le PDF que vous aviez fourni, remet provided_pdf à false et facturx_conformance à null, puis relance la génération en tâche de fond. Un téléchargement lancé juste après un PATCH peut ne rien renvoyer.
  • Le PATCH efface les erreurs d'import sans les revérifier (voir l'étape 1).

Un champ, lui, est refusé explicitement plutôt qu'ignoré : lifecycle_state. Envoyé avec une valeur, il fait échouer tout l'appel en 422, avec le code invalid_argument et le message lifecycle_state ne peut pas être modifié sur ce point d'entrée. Utilisez PATCH /api/v1/invoices/{id}/transition pour faire évoluer la facture dans son cycle de vie. Aucune modification n'est appliquée, pas même celle des autres champs de la charge utile. Le refus porte sur la présence d'une valeur : lifecycle_state: null ou une chaîne vide traverse l'endpoint sans erreur et sans effet. Pour faire avancer la facture, passez par l'étape 4 ci-dessous (Le cycle de vie d'une facture).

curl -X PATCH https://app.scribee.tech/api/v1/invoices/12345 \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"invoice": {
"invoice_number": "DRAFT-CRM-2026-0042",
"issue_date": "2026-07-31",
"due_date": "2026-09-15",
"type_code": "invoice",
"currency_code": "EUR",
"parties": [
{ "role": "buyer", "party_id": 42 }
],
"lines": [
{
"line_id": "1",
"article_name": "Prestation de conseil",
"quantity": 2.0,
"quantity_unit_code": "day",
"article_unit_price_excluding_taxes": 500.0,
"line_extension_amount": 1000.0,
"tax_category_id": "S",
"vat_rate": 20.0
}
],
"tax_subtotals": [
{ "tax_category_id": "S", "vat_rate": 20.0, "vat_amount": 200.0, "amount_without_taxes": 1000.0, "currency_code": "EUR" }
],
"total_amount_excluding_taxes": 1000.0,
"total_tax_amount": 200.0,
"tax_inclusive_amount": 1200.0,
"payable_amount": 1200.0
}
}'
{
"data": {
"id": 12345,
"due_date": "2026-09-15",
"lifecycle_state": "draft"
}
}

Étape 3 : supprimer le brouillon​

DELETE /api/v1/invoices/{id} supprime définitivement la facture. L'endpoint accepte destroy ou write : le scope write que porte la combinaison courante read write suffit donc, et destroy reste disponible pour un client qui supprime sans écrire (Authentification).

L'appel n'aboutit que sur un brouillon dont le numéro est absent ou commence par DRAFT-. Tout autre numéro - le vôtre, ou le TEMP- écrit par Scribee quand invoice_number manquait à la création - rend la facture non supprimable et l'appel répond 403.

curl -X DELETE https://app.scribee.tech/api/v1/invoices/12345 \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"

La réponse est un statut 204 sans corps.

Étape 4 : déposer la facture​

Le dépôt est le point de non-retour. Cet appel :

  • remplace un numéro DRAFT- par le numéro définitif issu du modèle de numérotation de l'entreprise, et incrémente sa séquence de numérotation ;
  • fait passer la facture à l'état deposited (200 Déposée) et inscrit l'évènement dans lifecycle_events ;
  • régénère les formats, en conservant un PDF que vous avez fourni ;
  • déclenche la remise vers votre logiciel comptable si une intégration comptable connectée est réglée sur remise automatique au dépôt.

Une facture créée par l'API est un original légal : une fois déposée, elle ne revient jamais en brouillon (revert_to_draft n'est offert que sur les factures déposées dans Scribee depuis un fichier émis ailleurs). Toute correction passe par un Avoir (type_code : credit_note) référençant la facture d'origine via invoice_references.

curl -X PATCH https://app.scribee.tech/api/v1/invoices/12345/transition \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "invoice": { "event": "deposit" } }'
{
"data": {
"id": 12345,
"invoice_number": "FAC-2026-0198",
"lifecycle_state": "deposited",
"lifecycle_status_code": "200",
"lifecycle_available_transitions": ["collect"],
"delivery_status": "not_delivered"
}
}

Sur une facture de vente, votre système ne déclenche lui-même que deux évènements : deposit (200 Déposée) puis, une fois le paiement reçu, collect (212 Encaissée). Enregistrer un paiement qui solde la facture déclenche collect de lui-même, sans appel de transition ; défaire ce paiement peut ramener la facture en 211 (Enregistrer les paiements). Les autres codes du cycle de vie ne sont écrits par aucun appel de cette API, mais le traitement des flux réglementaires entrants peut les appliquer : voir Le cycle de vie d'une facture.

Dupliquer une facture de vente​

POST /api/v1/invoices/{id}/duplicate crée un nouveau brouillon à partir d'une facture de vente existante, quel que soit l'état de son cycle de vie. L'appel ne prend pas de corps et exige le scope write. La facture d'origine n'est pas modifiée, et rien n'est transmis.

curl -X POST https://app.scribee.tech/api/v1/invoices/12345/duplicate \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
{
"data": {
"id": 12347,
"invoice_number": "DRAFT-3f9a1c0b7e2d4a65",
"issue_date": "2026-09-29",
"due_date": "2026-11-14",
"type_code": "invoice",
"lifecycle_state": "draft"
}
}

La réponse 201 restitue le nouveau brouillon sous la même forme que GET /api/v1/invoices/{id}, avec son propre id. C'est un brouillon ordinaire : il se modifie par PATCH (étape 2), se supprime (étape 3) et se dépose (étape 4).

La copie repart de zéro sur ce qui date la facture :

  • invoice_number est un numéro provisoire DRAFT-, remplacé par le numéro définitif au dépôt ;
  • issue_date est la date du jour ;
  • due_date conserve le délai de paiement de l'original : elle tombe autant de jours après la date du jour que l'échéance d'origine tombait après sa date d'émission, et jamais avant la date du jour. Si l'original n'avait pas d'échéance, la copie tombe 30 jours après la date du jour. Sur une facture déjà payée à l'émission, due_date porte la date du paiement et non un délai : la copie, qui n'est pas déclarée déjà payée, tombe alors 30 jours après la date du jour. Un délai qui placerait l'échéance de la copie au-delà du 9999-12-31 fait refuser la duplication (voir 422 à la duplication : échéance hors limites).

Sont repris de la facture d'origine : le client (buyer.party_id), type_code (un avoir reste un avoir), currency_code, category_id (sauf une catégorie archivée depuis : il vaut alors null sur la copie ; une facture sans catégorie donne une copie sans catégorie, sans reprendre la catégorie par défaut du client), les lignes avec la première note et la remise de chacune, leur product_type et leur catégorie de TVA (tax.category_code, qui distingue par exemple une ligne exonérée E d'une ligne Z au même taux de 0 %), les remises de niveau facture et margin_bases. Une ligne catalogue dont le produit n'est plus vendable, ou dont le nom, la description ou l'unité ne correspondent plus à ceux du produit, est reprise comme ligne libre, avec son propre nom, sa description, son prix et sa TVA. Une facture que la copie ne peut pas reproduire à l'identique - frais, quantité de base de prix, remises d'une autre forme que celle du formulaire, plusieurs notes sur une ligne, débours exonéré sous un autre motif que celui du formulaire, ou tout autre élément repris que la copie ne redonne pas à l'identique - n'est pas dupliquée (voir Erreurs et cas limites). Il en va de même d'une facture qui porte payment_terms, buyer_reference, project_reference, contract_reference, tender_reference, accounting_cost ou payable_rounding_amount, ou une partie autre que seller et buyer (payee, payer, buyer_agent, seller_agent, invoicee, invoicer) : la copie ne les reprend pas.

Sont reconstruits à partir des données actuelles de l'entreprise et du client, et non recopiés : seller, les coordonnées de buyer, payment_means, tax_due_date_code (BT-8 : le code 5 si l'entreprise a opté pour la TVA sur les débits au moment de la duplication, aucun code sinon, quel que soit celui de l'original) et les mentions légales (item_notes). Les mentions légales de l'original doivent toutefois se retrouver à l'identique sur la copie : une mention que l'entreprise a modifiée ou retirée depuis fait refuser la duplication (voir 422 à la duplication : copie non identique à l'original).

Ne sont pas repris : invoicing_period, la date de livraison, invoice_references, purchase_order_reference, sales_order_reference, despatch_advice_reference, receiving_advice_reference, la référence de paiement (payment_id), les paiements et les pièces jointes.

attention

Un avoir ou une facture rectificative doit citer la facture qu'il corrige. Comme invoice_references n'est pas repris, renseignez-le sur la copie par un PATCH avant de la déposer, en renvoyant la facture entière (étape 2).

Ce qui se passe ensuite​

  • Le numéro définitif est consommé sur la séquence de numérotation de l'entreprise ; il n'est jamais réutilisé, même si la facture est ensuite annulée.
  • Le champ delivery_status ne décrit pas la remise au destinataire. Il suit la remise de la facture à un logiciel comptable connecté. Les valeurs effectivement écrites sont sent, confirmed et failed ; not_delivered est la valeur par défaut ; pending est déclarée mais aucun code ne l'écrit. Sans intégration comptable connectée, le champ reste not_delivered à vie.
  • L'historique des transitions se lit via GET /api/v1/invoices/{id} avec include=lifecycle_events. Pour être notifié plutôt que d'interroger l'API, voir Webhooks.
  • Chaque format se télécharge sur GET /api/v1/invoices/{id}/download : voir Formats et téléchargements.
  • Le dépôt n'envoie pas d'email à votre client. Pour lui adresser le document, utilisez Envoyer par email et suivre la réception ; l'enregistrement des paiements reçus est couvert par Enregistrer les paiements.

Erreurs et cas limites​

Les erreurs communes à tous les endpoints (401, 404, enveloppe d'erreur) sont décrites dans Conventions de l'API. Tous les 422 de cette page portent en plus un code machine, stable et non traduit : branchez vos traitements dessus plutôt que sur le texte du message.

404 à la création : company_id inconnu​

{
"error": "not_found",
"message": "La ressource demandée est introuvable"
}

Le company_id envoyé n'existe pas dans le workspace visé, ou n'est ni un nombre ni une chaîne.

422 à la création : l'offre n'inclut pas la facturation de vente​

{
"error": "unprocessable_entity",
"code": "operation_failed",
"message": "Votre offre n'inclut pas la facturation de vente. Contactez votre cabinet comptable pour mettre à niveau votre offre."
}

Une entreprise sous cabinet comptable n'émet des factures de vente que si son offre le prévoit. Sinon, direction: "sales" répond 422 : l'entreprise visée existe et reste visible dans le workspace, c'est l'opération qui est refusée. Le corps ne porte pas de details. POST /api/v1/workspaces/{workspace_id}/invoices/upload oppose au même blocage le même statut et le même texte, à ceci près qu'il le place dans details.file plutôt que dans message.

422 à la création : direction invalide​

{
"error": "unprocessable_entity",
"code": "validation_failed",
"message": "La validation a échoué",
"details": { "direction": ["doit être 'sales' ou 'purchases'"] }
}

direction est obligatoire et vaut sales ou purchases. Pour une facture que vous émettez, envoyez sales.

422 à la création : résolution de l'annuaire​

Trois échecs possibles sur une entrée de parties, chacun avec error: "unprocessable_entity", le code operation_failed et un message dédié, sans details :

{
"error": "unprocessable_entity",
"code": "operation_failed",
"message": "Aucun client ou fournisseur trouvé pour party_id 42 dans cette entreprise"
}
  • Aucun client ou fournisseur trouvé pour party_id 42 dans cette entreprise : le party_id n'existe pas dans l'annuaire de l'entreprise retenue, ou ne correspond pas au rôle (un buyer de vente se résout contre les clients, pas les fournisseurs). Vérifiez d'abord le company_id que vous avez envoyé, puis l'identifiant dans Clients et fournisseurs.
  • party_id n'est pas autorisé pour le rôle 'seller' : la partie de l'entreprise est dérivée de la fiche entreprise, pas de l'annuaire : retirez le party_id de l'entrée seller ; ce rôle est rempli automatiquement.
  • 'abc' n'est pas un identifiant de référence valide : party_id et billing_address_id doivent être des entiers positifs : corrigez le format de la référence avant de rejouer l'appel.

422 à la création ou à la modification : partie payer hors profil EXTENDED-CTC-FR​

{
"error": "unprocessable_entity",
"code": "operation_failed",
"message": "Une partie 'payer' (tiers payeur, EXT-FR-FE-BG-02) n'est autorisée qu'en profil EXTENDED-CTC-FR : renseignez customization_id avec l'une des valeurs urn:cen.eu:en16931:2017#conformant#urn:factur-x.eu:1p0:extended, urn:cen.eu:en16931:2017#conformant#urn.cpro.gouv.fr:1p0:extended-ctc-fr, ou retirez la partie payer"
}

Une entrée de parties de rôle payer n'est acceptée que sous l'un des deux customization_id EXTENDED-CTC-FR que le message énumère. Le customization_id retenu est celui de la charge utile dès que la clé est présente, y compris avec une chaîne vide ; sinon, sur un PATCH, celui déjà enregistré sur la facture. La réponse ne porte pas de clé details. Envoyez le customization_id attendu, ou retirez l'entrée payer.

422 à la création ou à la modification : document_id ne désigne pas une facture d'acompte à solder​

{
"error": "unprocessable_entity",
"code": "operation_failed",
"message": "document_id 42 n'est pas une facture d'acompte que cette facture peut solder : elle doit être une facture d'acompte émise (386 ou 500) de la même entreprise, adressée au même acheteur party_id"
}

Une entrée de invoice_references qui porte document_id doit désigner une facture d'acompte que la facture peut solder, dans les conditions décrites sous Facture d'acompte et facture définitive après acompte. La réponse ne porte pas de clé details. Vérifiez l'identifiant, le numéro de la facture d'acompte, le currency_code et le party_id de l'acheteur des deux factures, ou envoyez la référence par ses valeurs.

422 à la création ou à la modification : role_code hors rôle, hors liste, ou hors profil​

Trois causes distinctes, chacune avec error: "unprocessable_entity", le code operation_failed et aucune clé details. La première : un role_code porté par un rôle qui n'en a pas - seller, buyer, tax_representative ou delivery. Le message énumère les six rôles qui en portent un.

{
"error": "unprocessable_entity",
"code": "operation_failed",
"message": "role_code n'est pas accepté sur l'entrée 'seller' : seuls payer (EXT-FR-FE-44), payee (EXT-FR-FE-26), buyer_agent (EXT-FR-FE-04), seller_agent (EXT-FR-FE-67), invoicee (EXT-FR-FE-90) et invoicer (EXT-FR-FE-113) en portent un. Retirez-le de l'entrée 'seller'"
}

La deuxième : un role_code dont la valeur n'appartient pas à la liste UN/CEFACT PartyRoleCode D22A, sur l'une de ces six entrées.

{
"error": "unprocessable_entity",
"code": "operation_failed",
"message": "'PRR' n'est pas un role_code valide : un code rôle de partie doit provenir de la liste UN/CEFACT PartyRoleCode D22A (UNCL 3035), sensible à la casse"
}

La troisième : un role_code porté par une partie payee alors que le customization_id retenu n'est pas un profil EXTENDED-CTC-FR, seul profil à définir EXT-FR-FE-26.

{
"error": "unprocessable_entity",
"code": "operation_failed",
"message": "role_code sur une partie 'payee' (EXT-FR-FE-26) n'est défini qu'en profil EXTENDED-CTC-FR : renseignez customization_id avec l'une des valeurs urn:cen.eu:en16931:2017#conformant#urn:factur-x.eu:1p0:extended, urn:cen.eu:en16931:2017#conformant#urn.cpro.gouv.fr:1p0:extended-ctc-fr, ou retirez role_code de la partie payee"
}

Ce troisième contrôle est évalué après le deuxième : une charge utile doublement fautive - une valeur hors liste sur une partie payee hors profil - reçoit d'abord le message qui nomme la valeur en cause. Le customization_id retenu est déterminé comme pour la partie payer : celui de la charge utile dès que la clé est présente, sinon, sur un PATCH, celui déjà enregistré.

Ce contrôle ne porte que sur l'attribut : une partie payee sans role_code reste acceptée sous tous les profils. C'est la différence avec la partie payer, dont le bloc entier exige le profil EXTENDED-CTC-FR et qui est donc refusée plus tôt, qu'elle porte un role_code ou non (voir la section précédente).

Retirez le role_code des entrées qui n'en portent pas, corrigez la valeur - elle est reprise telle quelle, sans normalisation de casse (PR est accepté, pr non) - ou renseignez le customization_id EXTENDED-CTC-FR attendu. Une valeur vide n'est jamais refusée : elle est traitée comme une absence.

422 à la création ou à la modification : acteur EXTENDED-CTC-FR​

Une entrée de parties de rôle buyer_agent, seller_agent, invoicee ou invoicer n'est acceptée que sous l'un des deux profils EXTENDED-CTC-FR que le message énumère. Sous tout autre customization_id, elle est refusée avec error: "unprocessable_entity", le code operation_failed et aucune clé details, et rien n'est enregistré. Le message nomme le premier de ces rôles trouvé dans parties. Le customization_id retenu est déterminé comme pour la partie payer : celui de la charge utile dès que la clé est présente, sinon, sur un PATCH, celui déjà enregistré. Une charge utile qui porte aussi une partie payer reçoit d'abord le message de la partie payer.

{
"error": "unprocessable_entity",
"code": "operation_failed",
"message": "Une partie 'buyer_agent' est un bloc EXTENDED-CTC-FR (XP Z12-012 EXT-FR-FE-BG-01 / -03 / -04 / -05) sans équivalent EN 16931 : renseignez customization_id avec l'une des valeurs urn:cen.eu:en16931:2017#conformant#urn:factur-x.eu:1p0:extended, urn:cen.eu:en16931:2017#conformant#urn.cpro.gouv.fr:1p0:extended-ctc-fr, ou retirez la partie buyer_agent"
}

Sous ces profils, les contrôles de role_code de la section précédente s'appliquent à ces acteurs : un role_code hors liste D22A reçoit le message de valeur invalide, et sur invoicee ou invoicer une valeur de la liste autre que le code fixe du rôle - IV pour invoicee, II pour invoicer - reçoit celui-ci.

{
"error": "unprocessable_entity",
"code": "operation_failed",
"message": "role_code de l'entrée 'invoicee' doit valoir IV : ce bloc porte un code rôle fixe, et une autre valeur désignerait un autre acteur"
}

Chacun de ces rôles n'admet qu'une seule entrée par facture : une deuxième entrée du même rôle est refusée avec le message Une seule partie 'invoicee' est admise [...], sur POST comme sur PATCH. Chaque acteur exige aussi la partie dans laquelle l'UBL l'imbrique : un buyer_agent ou un invoicee sans buyer, ou un seller_agent ou un invoicer sans seller, est refusé avec le message Une partie 'invoicee' exige une partie 'buyer' [...], plutôt que l'acteur ne disparaisse du fichier UBL alors que le CII le transmet. La partie côté entreprise (le seller d'une vente, le buyer d'un achat), que l'API ajoute quand elle est omise, compte ; sur PATCH, qui remplace toutes les parties, c'est l'ensemble envoyé qui est jugé. Chaque acteur doit aussi porter un name, sa raison sociale (EXT-FR-FE-03 / -66 / -89 / -112, obligatoire dans le bloc), qu'il soit envoyé ou rempli depuis party_id ; un name qui n'est pas une chaîne JSON (par exemple false ou un nombre) est refusé comme un name absent. Un identifier doit de même être accompagné de son identifier_scheme_id (EXT-FR-FE-07 / -70 / -92-1 / -116) : sans lui, l'appel est refusé avec le message L'identifiant d'une partie 'invoicee' doit être accompagné de son identifier_scheme_id [...]. Un endpoint_id doit être accompagné de son endpoint_scheme_id (EXT-FR-FE-13 / -76 / -99 / -122) : sans lui, l'appel est refusé avec le message L'adresse électronique d'une partie 'invoicee' doit être accompagnée de son endpoint_scheme_id [...]. Un legal_registration_id doit être accompagné de son legal_registration_scheme_id (EXT-FR-FE-09 / -72 / -95 / -118) : sans lui, l'appel est refusé avec le message L'identifiant légal d'une partie 'invoicee' doit être accompagné de son legal_registration_scheme_id [...]. Une adresse d'acteur qui renseigne un champ (address_line_1 à address_line_3, postal_code, city, country_subdivision) doit porter son country_code : XP Z12-012 exige le pays dans l'adresse de l'invoicee et de l'invoicer (EXT-FR-FE-107 / -130), et le schéma Factur-X EXTENDED l'exige dans l'adresse des quatre acteurs. Sans lui, l'appel est refusé avec le message L'adresse postale d'une partie 'invoicee' doit porter son country_code [...], plutôt que l'adresse ne disparaisse des fichiers exportés. À l'inverse, un identifier_scheme_id, un endpoint_scheme_id ou un legal_registration_scheme_id envoyé sans sa valeur est refusé avec le message Le identifier_scheme_id d'une partie 'invoicee' est renseigné sans son identifier [...] : un schéma n'est émis que comme attribut de la valeur qu'il qualifie. Un directory_routing_identifier est refusé sur ces quatre acteurs avec le message Une partie 'invoicee' ne peut pas porter de directory_routing_identifier [...] : il n'adresse que le vendeur et l'acheteur, l'adresse électronique d'un acteur est son endpoint_id, et celui de la fiche désignée par party_id n'est pas recopié sur l'acteur. Un country_code renseigné doit être un code ISO 3166-1 alpha-2 : FRA ou tout autre code que Scribee ne reconnaît pas est refusé avec le message Le country_code 'FRA' d'une partie 'invoicee' n'est pas un code ISO 3166-1 alpha-2 [...], plutôt qu'enregistré vide et l'adresse entière perdue à l'export ; un country_code qui n'est pas une chaîne JSON est refusé de même. Chaque schéma doit en outre appartenir à la liste que le profil EXTENDED-CTC-FR impose à son champ : endpoint_scheme_id à la liste CEF EAS (BR-CL-25), identifier_scheme_id et legal_registration_scheme_id à la liste ISO 6523 ICD (BR-CL-10 / BR-CL-11). ridet (0228) est ainsi refusé comme endpoint_scheme_id, et fr_vat (9957) comme identifier_scheme_id ou legal_registration_scheme_id, avec le message Le endpoint_scheme_id 'ridet' d'une partie 'invoicee' n'est pas un schéma que la plateforme peut transmettre pour endpoint_id [...]. Seuls les codes de cette liste que connaît la table des schémas de Scribee sont acceptés, hors 0231, réservé à l'assujetti unique : un code de la liste qu'elle ignore est refusé avec le même message. Un endpoint_id de plus de 125 caractères est refusé avec le message L'endpoint_id d'une partie 'invoicee' dépasse 125 caractères [...] : BR-FR-25 (EXT-FR-FE-12 / -75 / -98 / -121) rejette à l'export une adresse électronique plus longue. Sous endpoint_scheme_id aife (0225), l'endpoint_id ne peut comporter que des lettres, des chiffres et + - _ . : ABC DEF est refusé avec le message L'endpoint_id 'ABC DEF' d'une partie 'invoicee' contient un caractère que le schéma 0225 n'admet pas [...] (BR-FR-23). Un identifier ou un legal_registration_id sous le schéma siren (0002) doit compter exactement 9 chiffres, sinon l'appel est refusé avec le message Le legal_registration_id 'ABC' d'une partie 'invoicee' n'est pas un SIREN [...] (BR-FR-32). Un identifier sous le schéma siret (0009) doit compter exactement 14 chiffres, sinon l'appel est refusé avec le message L'identifier '123' d'une partie 'invoicee' n'est pas un SIRET [...], et, quand le legal_registration_id de l'acteur est un SIREN, commencer par lui, sinon l'appel est refusé avec le message Le SIRET '55210055400013' d'une partie 'invoicee' ne commence pas par son SIREN '732829320' [...] (BR-FR-09). Un schéma qui n'est pas une chaîne JSON compte comme absent. Un identifier, un endpoint_id ou un legal_registration_id qui n'est pas une chaîne JSON (par exemple false ou un nombre) est refusé, même accompagné de son schéma, avec le message Le legal_registration_id d'une partie 'invoicee' doit être une chaîne JSON [...], plutôt qu'enregistré sous forme de texte et transmis comme un identifiant que personne n'a attribué. Ces contrôles passent après ceux de role_code.

{
"error": "unprocessable_entity",
"code": "operation_failed",
"message": "Une partie 'invoicee' doit porter un nom : la raison sociale d'un bloc acteur EXTENDED-CTC-FR est obligatoire (XP Z12-012 EXT-FR-FE-03 / -66 / -89 / -112). Renseignez name sur l'entrée invoicee"
}

Renseignez le customization_id EXTENDED-CTC-FR attendu, ou retirez l'entrée ; sur invoicee et invoicer, envoyez le code fixe du rôle ou omettez role_code ; n'envoyez qu'une entrée par rôle ; renseignez le name de l'acteur sous forme de chaîne, le schéma de son identifiant, de son adresse électronique et de son identifiant légal ou retirez ceux-ci ; et renseignez le country_code d'une adresse d'acteur, ou retirez l'adresse.

422 à la création ou à la modification : ventilation de TVA non raccordée aux totaux​

{
"error": "unprocessable_entity",
"code": "operation_failed",
"message": "La ventilation de TVA ne se raccorde pas aux totaux du document : total_amount_excluding_taxes indique 1000.00 alors que la somme des montants correspondants des tax_subtotals vaut 1200.00. La règle PPF G1.53 tolère un écart de 0,01 et refuse la facture au dépôt au-delà : la ventilation est donc refusée ici plutôt qu'au moment du dépôt."
}

Le message nomme le total en cause - total_amount_excluding_taxes pour la somme des amount_without_taxes, total_tax_amount pour la somme des vat_amount - puis les deux montants comparés, à deux décimales. Ici la ventilation a été remplie avec des montants toutes taxes comprises alors que le champ porte la base hors taxe (BT-116) : 1200,00 ventilés contre 1000,00 déclarés.

Les deux moitiés sont vérifiées l'une après l'autre et la première qui échoue arrête l'appel : corrigez celle que le message nomme, puis rejouez. La réponse ne porte pas de clé details. Aucune facture n'est créée, et sur un PATCH aucune modification n'est appliquée.

422 à la création ou à la modification : facture déjà payée incohérente​

{
"error": "unprocessable_entity",
"code": "operation_failed",
"message": "Une facture déjà payée (invoicing_process_id B2, S2 ou M2) doit indiquer un prepaid_amount égal au tax_inclusive_amount (BR-FR-CO-09) : prepaid_amount vaut '100.00', tax_inclusive_amount vaut '120.00'."
}

La facture déclare un cadre B2, S2 ou M2, mais ses montants ou sa date ne décrivent pas un règlement complet (voir Une facture déjà payée à l'émission). Les vérifications s'enchaînent dans cet ordre et la première qui échoue arrête l'appel : prepaid_amount égal à tax_inclusive_amount, payable_amount à 0, payable_rounding_amount absent ou à 0, due_date présente, due_date au plus tard à issue_date, aucune entrée de invoice_references portant document_id. Le message nomme le champ en cause et, pour les montants, la valeur retenue à deux décimales ; une valeur absente y apparaît vide (''). Les dates sont citées au format AAAA-MM-JJ.

La réponse ne porte pas de clé details. Aucune facture n'est créée, et sur un PATCH aucune modification n'est appliquée. Corrigez les montants ou revenez au cadre B1, S1 ou M1 si la facture n'est pas encore payée.

422 à la création ou à la modification : triangular_position refusée​

{
"error": "unprocessable_entity",
"code": "validation_failed",
"message": "La validation a échoué",
"details": { "triangular_position": ["n'est pas inclus(e) dans la liste"] }
}

La valeur envoyée n'est pas l'une des trois positions, ou la direction de la facture ne l'admet pas (voir Opération triangulaire). Le message est le même dans les deux cas. Aucune facture n'est créée, et sur un PATCH aucune modification n'est appliquée : la facture garde sa position précédente.

422 à la création : numéro déjà utilisé​

{
"error": "unprocessable_entity",
"code": "operation_failed",
"message": "Une facture avec le numéro 'DRAFT-CRM-2026-0042' existe déjà pour cette entreprise."
}

Les numéros sont uniques par entreprise, numéros provisoires compris. Suffixez vos numéros DRAFT- d'une référence unique de votre système.

Cette contrainte ne s'applique qu'aux factures de vente : le même numéro peut apparaître sur une facture d'achat de la même entreprise sans provoquer ce conflit, puisque ce numéro-là vient de votre fournisseur et échappe à votre contrôle.

Le même conflit sur un PATCH prend l'enveloppe de validation générique, avec un code propre au doublon :

{
"error": "unprocessable_entity",
"code": "duplicate_record",
"message": "La validation a échoué",
"details": { "base": ["Un enregistrement avec cet identifiant existe déjà"] }
}

422 à la création : ligne de détail incomplète​

{
"error": "unprocessable_entity",
"code": "operation_failed",
"message": "La ligne '1' de la facture est incomplète : Article name doit être rempli(e). Ces informations sont obligatoires ; corrigez la ligne puis soumettez à nouveau la facture."
}

article_name, tax_category_id, article_unit_price_excluding_taxes, quantity et quantity_unit_code sont obligatoires sur chaque ligne. Il manque ici article_name ; le nom de l'attribut apparaît en anglais même dans ce message français, faute de libellé localisé pour les lignes de facture. Contrairement aux erreurs de validation habituelles, cette réponse ne porte pas de clé details : le message nomme directement les champs en cause. Aucune facture n'est créée ; corrigez la ligne et rejouez l'appel.

422 à la création ou à la modification : disbursement refusé​

À la création, une ligne marquée disbursement hors de la catégorie O et de la catégorie E sous VATEX-EU-79-C est refusée dans la forme d'une ligne de détail incomplète :

{
"error": "unprocessable_entity",
"code": "operation_failed",
"message": "La ligne '1' de la facture est incomplète : Disbursement ne peut marquer qu'une ligne de catégorie O, ou E sous VATEX-EU-79-C (XP Z12-014 cas 16). Ces informations sont obligatoires ; corrigez la ligne puis soumettez à nouveau la facture."
}

Une ligne marquée envoyée avec un vat_rate non nul est refusée de la même façon :

{
"error": "unprocessable_entity",
"code": "operation_failed",
"message": "La ligne '1' de la facture est incomplète : Disbursement ne peut marquer une ligne portant de la TVA : un débours est remboursé pour son montant exact (CGI 267 II 2°). Ces informations sont obligatoires ; corrigez la ligne puis soumettez à nouveau la facture."
}

Tout comme une ligne, marquée ou non, qui porte VATEX-EU-79-C hors de la catégorie E :

{
"error": "unprocessable_entity",
"code": "operation_failed",
"message": "La ligne '1' de la facture est incomplète : Tax exemption reason code VATEX-EU-79-C n'est admis que sur une ligne de catégorie E. Ces informations sont obligatoires ; corrigez la ligne puis soumettez à nouveau la facture."
}

Sur un PATCH, ces refus prennent l'enveloppe de validation générique, sous la clé disbursement pour les deux premiers et tax_exemption_reason_code pour le dernier :

{
"error": "unprocessable_entity",
"code": "validation_failed",
"message": "La validation a échoué",
"details": { "disbursement": ["ne peut marquer qu'une ligne de catégorie O, ou E sous VATEX-EU-79-C (XP Z12-014 cas 16)"] }
}

Sur une facture d'achat, une ligne marquée est refusée à la création comme à la modification :

{
"error": "unprocessable_entity",
"code": "validation_failed",
"message": "disbursement ne peut être porté que par une ligne de facture de vente : les débours (XP Z12-014 cas 16) sont déclarés par le vendeur sur sa propre vente. Retirez disbursement des lignes de la facture d'achat.",
"details": { "disbursement": ["disbursement ne peut être porté que par une ligne de facture de vente : les débours (XP Z12-014 cas 16) sont déclarés par le vendeur sur sa propre vente. Retirez disbursement des lignes de la facture d'achat."] }
}

Une ligne d'achat qui porte disbursement à false, telle que la renvoie un GET, est acceptée. Dans tous les cas, aucune facture n'est créée et, sur un PATCH, les lignes enregistrées restent inchangées. Retirez disbursement de la ligne, passez-la en catégorie O ou en catégorie E sous VATEX-EU-79-C, ramenez son vat_rate à 0, ou retirez VATEX-EU-79-C d'une ligne qui n'est pas en catégorie E.

422 à la création ou à la modification : déclaration d'assujetti unique envoyée​

Sur une facture de vente d'une société membre d'un assujetti unique, une partie tax_representative ou une note de niveau facture de code tax_declaration (ou TXD) est refusée, quel qu'en soit le contenu :

{
"error": "unprocessable_entity",
"code": "operation_failed",
"message": "Un membre d'assujetti unique ne peut pas envoyer de partie tax_representative ni de note TXD au niveau du document : Scribee reprend le BG-11 et la note MEMBRE_ASSUJETTI_UNIQUE des paramètres d'assujetti unique de la société et les fige sur la facture. Retirez-les de la requête"
}

Sur une facture de vente d'une société qui n'est membre d'aucun assujetti unique, c'est la note tax_declaration dont le texte est MEMBRE_ASSUJETTI_UNIQUE qui est refusée :

{
"error": "unprocessable_entity",
"code": "operation_failed",
"message": "'MEMBRE_ASSUJETTI_UNIQUE' est réservé à un membre d'assujetti unique : cette société n'en déclare aucun. Déclarez l'assujetti unique dans les paramètres de la société, ou retirez la note"
}

Dans les deux cas, aucune facture n'est créée et, sur un PATCH, le brouillon reste inchangé. Retirez la partie ou la note de la charge utile et rejouez l'appel (Une société membre d'un assujetti unique).

422 à la création : valeur lifecycle_state invalide​

{
"error": "unprocessable_entity",
"code": "operation_failed",
"message": "Valeur lifecycle_state invalide à la création : 'collected'. Valeurs autorisées : draft, deposited, available"
}

Sur une facture de vente, seule deposited fait avancer le cycle de vie ; available est réservée aux factures d'achat. Aucune facture n'est créée.

403 : la facture n'est plus un brouillon​

PATCH /api/v1/invoices/{id} et DELETE /api/v1/invoices/{id} répondent 403 avec error: "forbidden" dès que la facture a quitté l'état draft, ou pour un DELETE sur un brouillon dont le numéro ne commence pas par DRAFT-. Aucune modification n'est appliquée. Le champ message porte ici un libellé technique en anglais, produit par la couche d'autorisation : ne l'analysez pas, appuyez-vous sur le code HTTP et sur error.

Si la facture est déposée par une autre requête pendant le traitement de votre PATCH, l'appel échoue en 422, avec le code operation_failed et le message Seules les factures en brouillon peuvent être mises à jour, que le PATCH soit complet ou ne porte que margin_bases. Là non plus, aucune modification n'est appliquée : la facture reste telle que le dépôt l'a figée.

Après dépôt, corrigez par un Avoir.

422 au dépôt : le contrôle qui refuse nomme sa cause​

Le dépôt évalue plusieurs contrôles métier avant de faire avancer la facture. Le premier qui échoue donne le message, et chacun a son propre texte : sur un brouillon, un refus de dépôt ne se présente plus jamais sous la phrase générique Impossible de passer de ....

{
"error": "unprocessable_entity",
"code": "operation_failed",
"message": "La facture comporte des erreurs d'import bloquantes. Corrigez-les avant de changer son statut.",
"details": {}
}

Ce contrôle couvre deux situations. Soit l'un des quatre champs invoice_number, issue_date, type_code, currency_code manquait à la création et Scribee a enregistré une erreur bloquante (voir l'étape 1). Soit le PDF que vous avez fourni n'a pas pu être traité : cet échec est lui aussi inscrit sur la facture comme erreur d'import bloquante, sans verdict de conformité - voir Fournir votre propre PDF. Dans les deux cas, corrigez par un PATCH portant la facture entière, avec un invoice_number préfixé DRAFT-, puis redéposez.

Un PDF fourni dont la conformité a été évaluée non conforme relève, lui, d'un contrôle distinct, évalué avant celui des erreurs d'import : le dépôt est alors refusé avec Le PDF Factur-X joint n'est pas conforme. Remplacez-le par un fichier conforme avant de déposer la facture. Ce brouillon-là ne peut pas recevoir un nouveau PDF - voir Fournir votre propre PDF.

Le contrôle des mentions légales obligatoires, lui, est évalué après celui des erreurs d'import. Il renvoie son propre message, Des mentions légales obligatoires sont absentes de la facture (...). Renseignez-les dans les paramètres de facturation de l'entreprise, puis réessayez., accompagné d'un objet details qui nomme, clé par clé, les attributs à renseigner. Il est détaillé dans Le cycle de vie d'une facture.

Le contrôle de la déclaration d'assujetti unique est évalué juste après celui des mentions légales. Il ne vise que les factures de vente dont Scribee est l'émetteur - créées par POST /api/v1/workspaces/{workspace_id}/invoices ou par la conversion d'un devis, jamais importées par POST /api/v1/workspaces/{workspace_id}/invoices/upload - et créées alors que la société déclarait un assujetti unique. Il refuse le dépôt quand la facture ne porte pas les trois éléments décrits dans Une société membre d'un assujetti unique : Cette facture a été créée alors que la société était membre d'un assujetti unique, mais elle ne le déclare pas en entier (SIREN du vendeur sous le schéma 0231, raison sociale, numéro de TVA et adresse de l'assujetti unique, note MEMBRE_ASSUJETTI_UNIQUE). Complétez l'assujetti unique dans les paramètres de la société, puis réenregistrez le brouillon avant de le déposer. Complétez les paramètres dans l'interface Scribee, puis envoyez un PATCH sur le brouillon, qui y écrit les trois éléments, et redéposez. Si la société ne déclare plus, avec ses coordonnées complètes, le SIREN d'assujetti unique qu'elle déclarait à la création de la facture, le PATCH ne les écrit pas et le dépôt reste refusé.

Le contrôle du mandat de facturation ne vise que les factures de vente qui nomment un invoicer (EXT-FR-FE-BG-05). Il refuse le dépôt tant que l'entreprise ne détient pas, à la date d'émission (BT-2), un mandat de facturation tiers facturant actif pour ce tiers, rapproché par son legal_registration_id : Tiers facturant doit disposer d'un mandat de facturation (tiers facturant) de la société actif à la date d'émission. La facture reste un brouillon. Faites enregistrer le mandat, puis redéposez. Un PATCH d'un brouillon qui modifie la date d'émission (ou le type, la direction ou l'entreprise) juge de même le tiers facturant que la charge utile installe, jamais celui qu'elle remplace : un invoicer sans mandat actif à la nouvelle date est refusé en 422 avec ce même message, et rien n'est modifié ; retirer l'invoicer est accepté.

Un mandat actif ne suffit pas au dépôt : il doit avoir été attesté par un administrateur de l'entreprise. Quand aucun des mandats actifs qui couvrent le tiers facturant à la date d'émission n'est attesté, le dépôt est refusé en 422, avec le code operation_failed et un message qui nomme le tiers facturant tel que le mandat l'enregistre : Tiers facturant doit disposer d'un mandat de facturation (tiers facturant) attesté : le mandat de Compta Services couvrant la date d'émission n'a pas été attesté par un administrateur de la société. Attestez-le dans les mandats de facturation de la société avant de déposer la facture. La facture reste un brouillon. Ce contrôle ne vise que le dépôt : un PATCH du brouillon n'exige pas l'attestation. Faites attester le mandat dans les paramètres de l'entreprise de l'interface Scribee, puis redéposez.

La phrase générique Impossible de passer de deposited à deposit. L'état actuel ne permet pas cette transition. ne subsiste que pour un appel réellement hors état - un deposit sur une facture qui n'est plus un brouillon, par exemple. Elle ne signale plus aucun de ces contrôles.

Le dépôt demandé en un seul appel - POST /api/v1/workspaces/{workspace_id}/invoices avec lifecycle_state: "deposited" - passe par les mêmes contrôles et renvoie les mêmes messages ; aucune facture n'est alors créée.

422 au dépôt : pas de modèle de numérotation​

{
"error": "unprocessable_entity",
"code": "operation_failed",
"message": "Impossible de déposer la facture : aucun modèle de numérotation configuré pour cette entreprise",
"details": {}
}

Le numéro provisoire DRAFT- ne peut pas être remplacé : le modèle de numérotation de l'entreprise doit être configuré dans les réglages de facturation de l'interface Scribee avant le premier dépôt.

422 au dépôt : aucun taux de change disponible​

{
"error": "unprocessable_entity",
"code": "operation_failed",
"message": "Impossible de déposer cette facture en USD : aucun taux de change n'est disponible pour le 12/03/2026. Une facture en devise étrangère doit porter son total de TVA en EUR, ce qui exige un taux publié. Attendez la synchronisation des taux, puis relancez le dépôt.",
"details": {}
}

Ce refus ne concerne que les factures libellées dans une autre devise que l'EUR : le dépôt doit convertir leur total de TVA en euros, et aucun taux publié n'a été trouvé pour la date d'émission. Il est évalué après les contrôles décrits plus haut et avant le contrôle EN 16931.

La facture n'est pas modifiée et reste au brouillon : rejouez le dépôt à l'identique une fois le taux disponible. Une issue_date erronée produit le même refus - antérieure à l'historique des taux, ou trop en avance sur le jour de publication le plus récent : vérifiez-la avant d'attendre. Voir Facturer dans une autre devise que l'euro.

422 : évènement inconnu ou réservé à la plateforme​

{
"error": "unprocessable_entity",
"code": "invalid_argument",
"message": "Évènement de cycle de vie inconnu ou manquant. Fournissez un nom d'évènement valide parmi les transitions disponibles de la facture.",
"details": {}
}

Le champ event doit être l'une des valeurs listées dans lifecycle_available_transitions. Le code invalid_argument est propre à ce cas : un évènement réservé à la plateforme (par exemple receive) est bien reconnu, et son refus porte le code operation_failed avec le message La transition receive ne peut pas être déclenchée manuellement.

403 à la duplication : facture non duplicable​

POST /api/v1/invoices/{id}/duplicate répond 403 avec error: "forbidden" et le message Vous n'êtes pas autorisé à effectuer cette action quand le jeton ne porte pas le scope write, ou quand la facture désignée est une facture d'achat, une facture auto-facturée (self_billed_*), une facture affacturée (factored_invoice, corrected_factored_invoice), un avoir d'acompte (retainer_credit_note, 503) ou un avoir de remise globale (consolidated_credit_note, 262). Aucun brouillon n'est créé.

404 à la duplication : facture hors de votre périmètre​

La duplication répond 404 avec l'enveloppe not_found ordinaire quand l'identifiant n'existe pas, désigne une facture d'un autre workspace, ou une facture de vente d'une entreprise dont l'offre n'inclut pas la facturation de vente.

422 à la duplication : acheteur non rattaché à un client​

{
"error": "unprocessable_entity",
"code": "operation_failed",
"message": "Cette facture n'est rattachée à aucun client et ne peut donc pas être dupliquée. Rattachez d'abord son acheteur à un client."
}

La facture d'origine est dupliquée pour le même client : son acheteur doit donc être rattaché à une fiche client, ce qui se lit à un buyer.party_id non nul. Aucun brouillon n'est créé. D'autres refus de création peuvent répondre de la même façon, avec le code operation_failed et leur cause dans message.

422 à la duplication : frais​

{
"error": "unprocessable_entity",
"code": "operation_failed",
"message": "Cette facture comporte des frais que le formulaire de facture ne sait pas encore reprendre : elle ne peut donc pas être dupliquée."
}

Une facture qui porte des frais, au niveau de la facture (allowance_charges avec charge_indicator: true) ou sur l'une de ses lignes, est refusée avec ce message : la copie ne reconstruit aucun frais. Les refus de duplication de cette section et des suivantes sont contrôlés dans l'ordre où ils apparaissent, et seul le premier rencontré est renvoyé : une facture qui porte à la fois des frais et des remises non reproductibles reçoit ce message. Aucun brouillon n'est créé.

422 à la duplication : quantité de base de prix​

{
"error": "unprocessable_entity",
"code": "operation_failed",
"message": "Une ligne de cette facture exprime son prix pour une quantité de base différente de 1, que le formulaire de facture ne sait pas reprendre : elle ne peut donc pas être dupliquée."
}

La copie calcule chaque ligne comme quantité x prix unitaire. Une ligne dont price.base_quantity (BT-149) est renseigné et différent de 1 - 100 unités à 10 EUR les 100, par exemple - reviendrait à un autre montant : elle est refusée avec ce message. Aucun brouillon n'est créé.

422 à la duplication : remises non reproductibles​

{
"error": "unprocessable_entity",
"code": "operation_failed",
"message": "Cette facture comporte des remises de pied de facture que le formulaire de facture ne peut pas reproduire : elle ne peut donc pas être dupliquée."
}

La copie ne reconstruit qu'une seule remise de niveau facture, répartie sur les groupes de lignes de même taux et de même catégorie de TVA : soit un même pourcentage sur chaque groupe, soit un montant réparti au prorata du total HT de chaque groupe. Des remises de niveau facture (allowance_charges avec charge_indicator: false) d'une autre forme - des pourcentages différents, des montants qui ne suivent pas ce prorata, ou une remise qui ne porte que sur certains groupes - sont refusées avec ce message. Aucun brouillon n'est créé.

{
"error": "unprocessable_entity",
"code": "operation_failed",
"message": "Une ligne de cette facture comporte une remise que le formulaire de facture ne peut pas reproduire (il en permet une par ligne, en pourcentage ou en montant, calculée sur quantité x prix) : elle ne peut donc pas être dupliquée."
}

La copie reconstruit une seule remise par ligne, à partir de son pourcentage s'il en a un, sinon de son montant, recalculée sur quantité x prix unitaire et arrondie à deux décimales. Une ligne qui porte plus d'une remise, ou dont la remise ainsi recalculée ne redonne pas exactement le montant et le pourcentage enregistrés - par exemple une remise en montant exprimée au-delà de deux décimales -, est refusée avec ce message. Aucun brouillon n'est créé.

422 à la duplication : plusieurs notes sur une ligne​

{
"error": "unprocessable_entity",
"code": "operation_failed",
"message": "Une ligne de cette facture comporte plusieurs notes, alors que le formulaire de facture n'en reprend qu'une par ligne : elle ne peut donc pas être dupliquée."
}

La copie ne reprend que la première note de chaque ligne. Une facture dont une ligne porte plus d'une note est refusée avec ce message. Aucun brouillon n'est créé.

422 à la duplication : débours exonéré​

{
"error": "unprocessable_entity",
"code": "operation_failed",
"message": "Une ligne de débours exonérée de cette facture (catégorie E) indique un autre motif d'exonération que celui que le formulaire de facture saisit pour elle (VATEX-EU-79-C, \"REMBOURSEMENT\") : elle ne peut donc pas être dupliquée."
}

La copie reprend une ligne marquée disbursement en catégorie O, et en catégorie E quand elle porte exactement le motif que le formulaire de facture saisit pour un débours exonéré : tax_exemption_reason_code valant VATEX-EU-79-C et tax_exemption_reason valant REMBOURSEMENT. Une ligne de débours en catégorie E sans libellé, ou sous un autre libellé - Débours dans l'exemple de Les débours compris -, est refusée avec ce message, car la copie la réécrirait. Aucun brouillon n'est créé.

422 à la duplication : produit modifié ou retiré de la vente​

{
"error": "unprocessable_entity",
"code": "operation_failed",
"message": "Une ligne de cette facture porte sur un produit modifié ou retiré de la vente depuis, et le formulaire de facture ne peut pas la reproduire en ligne libre : elle ne peut donc pas être dupliquée."
}

Une ligne catalogue dont le produit n'est plus vendable, ou dont le nom, la description ou l'unité ne correspondent plus à ceux du produit, est reprise comme ligne libre, et une ligne libre porte l'unité par défaut one (C62). Une telle ligne exprimée dans une autre unité est refusée avec ce message. Aucun brouillon n'est créé.

422 à la duplication : ventilation de TVA d'une facture sans lignes​

{
"error": "unprocessable_entity",
"code": "operation_failed",
"message": "Cette facture sans lignes comporte une ventilation de TVA dont le formulaire de facture ne peut pas reproduire les bases imposables : elle ne peut donc pas être dupliquée."
}

Une facture sans lignes est reprise par les taux et les montants de TVA de sa ventilation : chaque amount_without_taxes à taux positif est recalculé à partir de vat_amount et du taux, et une entrée unique à 0 % qui porte sa catégorie de TVA reçoit le reste de total_amount_excluding_taxes. Quand ce recalcul ne redonne pas à l'identique les tax_subtotals enregistrés, la duplication est refusée avec ce message. Aucun brouillon n'est créé.

422 à la duplication : échéance hors limites​

{
"error": "unprocessable_entity",
"code": "operation_failed",
"message": "Cette facture arrive à échéance trop longtemps après sa date d'émission pour que la copie reprenne le même délai de paiement : elle ne peut donc pas être dupliquée."
}

La copie reprend le délai de paiement de l'original à partir de la date du jour. Quand ce délai placerait son échéance au-delà du 9999-12-31, la duplication est refusée avec ce message. Aucun brouillon n'est créé.

422 à la duplication : copie non identique à l'original​

{
"error": "unprocessable_entity",
"code": "operation_failed",
"message": "Cette facture comporte des éléments que le formulaire de facture ne peut pas reproduire à l'identique : elle ne peut donc pas être dupliquée."
}

Ce refus vient après tous les précédents et garantit le résultat : la copie est identique à la facture d'origine dans chaque champ métier qu'elle reprend, sinon l'appel échoue en 422 et rien n'est créé. Une fois la copie construite, Scribee la compare champ par champ à l'original : les champs du document et ses parties autres que seller et buyer, chaque ligne, dans l'ordre et avec son regroupement, avec son contenu, ses quantités et ses montants, son taux, sa catégorie et son motif d'exonération de TVA, ses notes, ses identifiants d'objet et son type de produit ; chaque remise, de ligne ou de facture, avec son motif et ses codes ; la ventilation de TVA (tax_subtotals) ; les notes de niveau facture (item_notes), mentions légales comprises ; les totaux du document et son montant dû avant tout règlement. Ne sont pas comparés les éléments que la copie refixe volontairement, décrits plus haut : numéro, dates, période de facturation, livraison, invoice_references et les références de commande et d'avis, seller et buyer, moyens de paiement, tax_due_date_code, catégorie archivée depuis, la note tax_declaration et la partie tax_representative que Scribee écrit pour un assujetti unique, ainsi que les paiements de l'original. Pour les mentions légales, le seul écart toléré est une mention que l'entreprise a ajoutée depuis l'émission de l'original, sous un sujet (code) où l'original n'en porte aucune. Une facture qui porte une note de niveau facture propre, ou une mention légale dont l'entreprise a depuis modifié le texte ou qu'elle a retirée, est donc refusée avec ce message. Au moindre écart, la copie est annulée et la duplication refusée avec ce message. Aucun brouillon n'est créé.

Adresse IP hors liste blanche : 403 ou 404 selon l'endpoint​

Si le workspace restreint les adresses IP, le code renvoyé dépend de la forme de la route :

{
"error": "forbidden",
"message": "Cette adresse IP n'est pas autorisée pour cet espace de travail"
}

Cette réponse ne concerne que POST /api/v1/workspaces/{workspace_id}/invoices, qui nomme le workspace dans son chemin. Les routes construites sur l'identifiant de facture - PATCH, DELETE, PATCH .../transition, GET .../download, POST .../duplicate - répondent 404 avec l'enveloppe not_found ordinaire, indistinguable d'une facture inexistante.

Pages liées​