Aller au contenu principal

Écritures comptables bancaires

Une écriture comptable bancaire (bank_accounting_entry) est la projection comptable d'une opération bancaire : les lignes de grand livre que Scribee a passées pour cette opération, avec leurs comptes et leurs montants. C'est la ressource qui vous dit où un mouvement a été imputé, et pas seulement qu'il l'a été.

Un compte bancaire porte la configuration sans laquelle rien n'est projeté (Comptes bancaires), un journal comptable reçoit l'écriture (Journaux comptables), et cette ressource est ce que la projection produit.

La chose à comprendre avant tout le reste​

lines est la comptabilité elle-même, et elle est publiée sur chaque ligne de la liste, jamais derrière un include. Les deux totaux de l'écriture ne vous disent pas où l'argent est allé : une opération de 300,00 dont 200,00 sont rapprochés porte une ligne de contrepartie de 200,00 et une ligne d'attente de 100,00, et ces deux lignes ont exactement les mêmes totaux qu'une écriture qui aurait tout mis en attente. Si vous lisez cette ressource, lisez lines.

Lecture seule​

Cette ressource ne s'écrit pas. Il n'existe ni POST, ni PATCH, ni DELETE. Une écriture est recalculée à partir des rapprochements confirmés de son opération, elle n'est pas modifiée sur place : pour changer une écriture, changez le rapprochement qui la produit. Aucun appel de cette page n'étant une écriture, l'en-tête Idempotency-Key n'y a pas d'objet.

Une écriture n'existe que si la comptabilisation a réussi. Un incident de comptabilisation n'est donc jamais représentable ici - il n'y a pas d'écriture en échec à lire. Ce qu'une opération non comptabilisée vous dit, c'est qu'elle ne l'est pas : sur sa propre charge utile, que vous pouvez faire embarquer ici avec ?include=bank_operation, projection.posted vaut false et projection.bank_accounting_entry_id est nul.

Le motif d'un échec se lit sur l'opération, jamais ici. projection.incident_code dit ce qu'a rencontré la dernière tentative de comptabilisation de la ligne (Opérations bancaires). Ce n'est pas l'état actuel du compte : les conditions de comptabilisation du compte bancaire se lisent dans readiness.missing (Comptes bancaires) - c'est là que se trouve la cause de loin la plus fréquente, une configuration incomplète.

Les écritures issues d'une facture ne sont jamais rendues ici. Une écriture est soit d'origine facture, soit d'origine opération bancaire, jamais les deux, et cette ressource ne publie que les secondes : une écriture de facture adressée par son identifiant répond 404, comme si elle n'existait pas.

Les endpoints​

  • GET /api/v1/workspaces/{workspace_id}/companies/{company_id}/bank_accounting_entries - lister les écritures d'une entreprise
  • GET /api/v1/bank_accounting_entries/{id} - lire une écriture

Comme sur les autres ressources bancaires, seule la liste est adressée par workspace et par entreprise. L'endpoint portant un identifiant n'a pas de workspace_id dans le chemin : l'identifiant est résolu sur l'ensemble des workspaces rattachés à votre client OAuth. Les deux lectures demandent le scope read.

Une écriture porte quatorze champs, tous présents dans chaque réponse : id, company_id, bank_operation_id, entry_date, entry_kind, reference, label, ledger_id, total_debit, total_credit, exported, lines, created_at et updated_at.

ChampCe qu'il porte
bank_operation_idL'opération dont cette écriture est la projection. Une opération a au plus une écriture bank_operation, à laquelle s'ajoutent les éventuelles corrections, qui partagent son bank_operation_id
entry_dateLa date de l'opération, pas la date de comptabilisation. created_at vous donne la seconde. Sur une bank_operation_correction, la plus tardive entre la date de l'opération et la date de verrouillage de l'écriture corrigée : une correction n'est jamais antérieure au verrouillage
entry_kindbank_operation pour la projection principale de l'opération, bank_operation_correction pour une correction émise contre une écriture verrouillée. Lisez-le plutôt que de le supposer : une nouvelle nature de projection arriverait comme une nouvelle valeur ici, pas comme une ligne cachée
referenceUne référence attribuée par Scribee, construite à partir de ses seuls identifiants : BQ, puis l'année et le mois de l'opération, puis un numéro d'au moins quatre chiffres - par exemple BQ-2026-07-0144. Elle est fixée à la création de l'écriture et n'est pas réécrite quand l'écriture est recalculée. Pour relier une écriture à son opération, utilisez bank_operation_id. Sur une bank_operation_correction, la référence de l'écriture corrigée suivie de -C et du rang de la correction (-C1, -C2, ...)
labelDérivé du libellé de l'opération (description, à défaut clean_description), tronqué à 255 caractères. Si l'opération ne porte ni l'un ni l'autre, Opération bancaire suivi de l'identifiant de l'opération. Sur une bank_operation_correction, Régularisation - suivi du libellé de l'écriture corrigée, le tout tronqué à 255 caractères
ledger_idLe journal comptable dans lequel l'écriture est passée. C'est celui du compte bancaire au moment de la projection
total_debit, total_creditÉgaux sur chaque écriture projetée : l'équilibre est acquis par construction, aucune ligne d'ajustement n'est ajoutée pour l'obtenir

:::warning Changement de comportement Jusqu'ici, reference reprenait l'identifiant externe de l'opération quand elle en portait un, sinon BANK-OP- suivi de l'identifiant de l'opération, et le libellé de repli d'une opération sans description reprenait ce même identifiant externe. Les deux sont désormais construits à partir des seuls identifiants Scribee, et les écritures existantes ont été réécrites une fois vers ces nouvelles valeurs. Si votre intégration a stocké une reference ou un label, la valeur que vous relirez n'est plus la même : rapprochez vos données par id ou par bank_operation_id, qui n'ont pas changé. :::

Lire une écriture​

Un token read suffit.

curl https://app.scribee.tech/api/v1/bank_accounting_entries/44120 \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
{
"data": {
"id": 44120,
"company_id": 34,
"bank_operation_id": 30144,
"entry_date": "2026-07-14",
"entry_kind": "bank_operation",
"reference": "BQ-2026-07-0144",
"label": "ACME CORP",
"ledger_id": 4,
"total_debit": 300.00,
"total_credit": 300.00,
"exported": false,
"lines": [
{
"account_number": "512999",
"label": "ACME CORP",
"debit_amount": 300.00,
"credit_amount": 0.00,
"tax_code": null,
"explanation": {
"source": "allocation",
"rule_id": null,
"rule_name": null,
"reason": "bank account 512999"
}
},
{
"account_number": "411ACME",
"label": "Facture 90210",
"debit_amount": 0.00,
"credit_amount": 200.00,
"tax_code": null,
"explanation": {
"source": "allocation",
"rule_id": null,
"rule_name": null,
"reason": "confirmed allocation 7001"
}
},
{
"account_number": "471000",
"label": "ACME CORP",
"debit_amount": 0.00,
"credit_amount": 100.00,
"tax_code": null,
"explanation": {
"source": "suspense",
"rule_id": null,
"rule_name": null,
"reason": "unallocated remainder on account 471000"
}
}
],
"created_at": "2026-07-14T06:12:04+02:00",
"updated_at": "2026-07-14T06:12:04+02:00"
}
}

lines : comment lire le grand livre​

Cet exemple est celui d'une opération entrante de 300,00 dont 200,00 sont rapprochés d'une facture. Trois lignes, dans cet ordre exact, qui est celui dans lequel la projection les écrit et celui dans lequel un comptable les lit :

  1. la ligne de banque, pour la totalité du montant - le compte comptable configuré sur le compte bancaire (512999 ici) ;
  2. une ligne de contrepartie par rapprochement confirmé - une seule ici, 411ACME pour 200,00 ;
  3. la ligne d'attente, pour le reste seulement - 471000 pour les 100,00 qui ne sont encore imputés nulle part.

La troisième ligne n'existe que s'il reste quelque chose à imputer. Une opération intégralement rapprochée n'a pas de ligne d'attente du tout ; une opération qui n'a aucun rapprochement confirmé a une ligne d'attente qui porte la totalité. Une seule ligne d'attente de 300,00 sur cet exemple ne serait pas une simplification, ce serait une erreur : Scribee ne produit jamais cette forme.

Six attributs par ligne, tous présents :

AttributCe qu'il porte
account_numberLe compte du plan comptable sur lequel cette ligne est passée
labelLe libellé de la ligne. Celui du rapprochement sur une ligne de contrepartie, celui de l'écriture sur la ligne de banque et sur la ligne d'attente
debit_amountPositif ou nul
credit_amountPositif ou nul
tax_codeToujours null sur ces écritures : la projection bancaire n'attache aucun code de taxe à ses lignes
explanationPourquoi la ligne est passée sur ce compte - voir ci-dessous. Un objet, ou null

Un IBAN cité dans un libellé n'est jamais publié en entier. Le label de l'écriture et celui de chacune de ses lines reprennent le libellé de l'opération ; un IBAN qu'il cite y est rendu sous la forme de iban_masked - FR*********************0189 - selon la règle décrite pour les opérations bancaires. Les lignes d'écriture du webhook bank_operation.reconciled sont rendues de la même façon.

Les deux montants sont toujours positifs ou nuls, et exactement un des deux côtés est non nul. Une ligne ne porte jamais un montant unique signé : lisez le côté, pas le signe. Le sens de l'opération décide du côté : une opération entrante débite la banque et crédite la contrepartie, une opération sortante fait l'inverse.

Les lignes n'ont pas d'identifiant, et c'est délibéré. Elles sont réécrites intégralement à chaque nouvelle projection, donc un identifiant que vous auriez stocké désignerait une ligne qui n'existe plus. Ce que vous pouvez stocker, c'est l'identifiant de l'écriture.

explanation : pourquoi une ligne est sur son compte​

Chaque ligne dit pourquoi elle a été passée sur son compte. La réponse reprend l'ordre dans lequel la projection choisit un compte - rapprochement confirmé, puis règle société, puis règle de workspace (Règles d'imputation bancaires), puis compte d'attente - et prend la forme d'un objet à quatre clés, toujours présentes. Les lignes d'une correction se situent hors de cet ordre : elles portent leur propre source, correction.

CléCe qu'elle porte
sourceallocation, company_rule, tenant_rule, suspense ou correction. La ligne de banque et les lignes de contrepartie d'un rapprochement confirmé portent allocation ; une ligne de reste imputée par une règle porte company_rule ou tenant_rule ; un reste qu'aucune règle n'a atteint porte suspense ; chaque ligne d'une écriture dont l'entry_kind vaut bank_operation_correction porte correction
rule_idL'identifiant de la règle qui a décidé la ligne, quand source vaut company_rule ou tenant_rule. null sinon
rule_nameLe nom de cette règle au moment où elle a décidé. null quand rule_id l'est
reasonUn texte destiné à un humain, rédigé en anglais quelle que soit la langue de l'utilisateur à l'origine de l'écriture. Ne l'analysez pas : sa formulation ne fait pas partie du contrat

Une ligne imputée par une règle :

{
"account_number": "651600",
"label": "PRLV SEPA SAAS ACME",
"debit_amount": 89.90,
"credit_amount": 0.00,
"tax_code": null,
"explanation": {
"source": "company_rule",
"rule_id": 88,
"rule_name": "Abonnements SaaS",
"reason": "description contains \"SAAS\""
}
}

L'explication est enregistrée au moment où la ligne est écrite, et n'est jamais recalculée. Une règle renommée, modifiée ou supprimée depuis continue de se lire ici telle qu'elle était quand elle a décidé la ligne : rule_id peut donc désigner une règle qui n'existe plus, et rule_name peut différer du nom actuel de la règle. C'est voulu - l'explication décrit ce qui a produit la ligne, pas ce que les règles d'aujourd'hui produiraient. Seule une nouvelle écriture de la ligne remplace son explication : une nouvelle projection, ou un rapprochement confirmé ou annulé qui déplace la ligne, lui donne l'explication de cette écriture-là.

Une ligne de correction :

{
"account_number": "471000",
"label": "Régularisation - VIR SEPA RECU ACME SAS",
"debit_amount": 1200.00,
"credit_amount": 0.00,
"tax_code": null,
"explanation": {
"source": "correction",
"rule_id": null,
"rule_name": null,
"reason": "Adjustment of entry BQ-2026-03-1001: imputation adjusted on account 471000."
}
}

Une ligne de correction n'a été décidée par aucune règle : elle porte l'écart, compte par compte, entre ce que les écritures de l'opération ont déjà comptabilisé et ce que l'opération justifie désormais. rule_id et rule_name valent donc null, et reason désigne l'écriture corrigée par sa reference - celle que la reference de la correction prolonge de -C et de son rang. Le label de la ligne et son explanation sont deux choses distinctes : le libellé est celui que la ligne porte dans le grand livre, l'explication dit pourquoi elle est sur son compte.

explanation vaut null quand aucune raison n'a été enregistrée pour la ligne, ce qui arrive dans trois cas :

  • une ligne écrite avant que Scribee n'enregistre cette explication, quand sa raison ne se déduisait pas sans ambiguïté de ce qui était stocké ou que son écriture était déjà figée - une ligne de reste, en particulier, n'est jamais reconstituée, même sur le compte d'attente, puisqu'une règle a pu la décider et changer depuis ;
  • une ligne d'une écriture dont l'entry_kind vaut bank_operation_correction écrite avant que Scribee n'enregistre cette explication sur les corrections : elle n'est pas reconstituée ;
  • le solde qu'une annulation de rapprochement laisse sur une ligne de contrepartie qui citait ce rapprochement.

Un null ne signifie pas que la ligne est fausse.

Les montants et leur précision​

Les montants de l'écriture - total_debit, total_credit, et les deux montants de chaque ligne - sont des nombres JSON à deux décimales. C'est la précision à laquelle la projection est calculée, et celle que le contrat de cette ressource annonce.

Un montant de cette page se lit donc différemment du montant d'une opération bancaire, et la différence est délibérée. Si vous demandez ?include=bank_operation, l'opération embarquée publie son amount comme une chaîne de caractères à quatre décimales - "300.0000", guillemets compris - parce que c'est la valeur exacte telle qu'elle est stockée et qu'une opération se relit à la décimale près. Un client qui parserait ce champ comme un nombre JSON échouerait. Les deux formes coexistent volontairement : les chiffres de l'écriture sont dérivés et arrondis, celui de l'opération est stocké tel quel.

exported : ce qui a quitté les livres​

exported est dérivé à chaque lecture, jamais stocké : il ne peut donc pas être périmé. Il vaut true dès que l'écriture a été exportée vers un logiciel comptable, ou livrée à un logiciel comptable.

Une écriture exportée est figée. Une nouvelle projection ne la réécrit pas et ne la supprime pas, et un changement de rapprochement qui la viserait est refusé en 422 avec le code entry_already_exported - refus qui appartient aux endpoints de rapprochement, pas à ceux de cette page, qui ne refusent jamais une lecture pour ce motif.

Lister les écritures d'une entreprise​

curl "https://app.scribee.tech/api/v1/workspaces/YOUR_WORKSPACE_ID/companies/YOUR_COMPANY_ID/bank_accounting_entries?entry_date_from=2026-07-01&ledger_id=4" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"

La liste est rendue de l'entry_date la plus récente à la plus ancienne, à égalité de date de l'identifiant le plus grand au plus petit, et l'enveloppe data + meta suit Conventions de l'API.

La pagination est par décalage, avec page et per_page - 20 par défaut, 100 au maximum - comme sur toutes les autres ressources bancaires. Il n'y a pas de curseur. Une pagination par décalage sur un ensemble qui grandit peut répéter ou sauter une ligne entre deux requêtes : bornez votre fenêtre avec entry_date_from et entry_date_to plutôt que de supposer un instantané stable.

{
"data": [],
"meta": {
"current_page": 1,
"per_page": 20,
"total_pages": 5,
"total_count": 87
}
}

Cinq filtres, tous facultatifs et cumulables :

FiltreValeursCe qu'il retient
bank_operation_idun entierLes écritures projetées depuis une opération : son écriture bank_operation, s'il y en a une, et chacune de ses corrections bank_operation_correction. Zéro, une ou plusieurs lignes ; entry_kind les distingue
entry_date_fromune date ISO 8601Les écritures dont l'entry_date est à cette date ou après, bornes incluses
entry_date_toune date ISO 8601Les écritures dont l'entry_date est à cette date ou avant, bornes incluses
ledger_idun entierLes écritures passées dans un journal donné
bank_account_idun entierLes écritures dont l'opération source appartient à un compte bancaire donné

bank_account_id mérite un mot : l'écriture ne porte aucun compte bancaire. Ce filtre passe par l'opération source, donc il vous rend exactement les écritures des opérations de ce compte.

Une valeur qu'un filtre ne sait pas lire ne remonte rien, et ce n'est pas une erreur - ni un 422, ni une fenêtre silencieusement plus large. Un ledger_id qui n'est pas un entier, une date qui n'est pas au format YYYY-MM-DD, un paramètre envoyé sous forme de tableau : dans les trois cas la réponse est un 200 avec une collection vide. Les deux bornes de dates n'acceptent que le format ISO 8601 : 14/07/2026 ne remonte rien plutôt que d'être deviné comme le 14 juillet ou comme le 7 avril.

Un paramètre absent ou vide n'est pas un filtre : il ne restreint rien.

Embarquer l'opération source​

?include=bank_operation ajoute à chaque écriture la charge utile complète de son opération source, sous la clé bank_operation. Sans ce paramètre, la clé est absente - et non pas présente à null. C'est le seul include de cette ressource ; toute autre valeur est ignorée.

L'opération embarquée n'embarque à son tour rien du tout : elle ne porte ni son compte, ni son relevé, ni son écriture. La charge utile ne peut donc pas s'emboîter indéfiniment.

Quel chemin choisir​

La même écriture est atteignable par deux chemins, et ce recouvrement est voulu. Les opérations bancaires publient un include nommé bank_accounting_entry qui en rend un sous-ensemble de onze clés. Cette ressource publie ces onze clés, avec exactement les mêmes noms et le même sens, et y ajoute lines, created_at et updated_at.

  • Vous parcourez déjà les opérations et vous voulez voir au passage si chacune est comptabilisée, et sur quels totaux : demandez l'include sur les opérations, vous économisez un appel.
  • Vous voulez les écritures pour elles-mêmes - avec leurs propres filtres, leur propre pagination, et surtout avec lines : utilisez cette ressource. Le sous-ensemble ne porte pas lines, donc il ne peut pas vous montrer la ventilation.

Les onze clés communes ne peuvent pas diverger entre les deux chemins : c'est le même concept avec une seule orthographe.

Les erreurs​

StatuterrorQuand
400bad_requestUn page qui n'est pas un entier supérieur ou égal à 1, ou une page au-delà de la dernière page d'une collection non vide
403forbiddenVotre client OAuth n'a pas d'habilitation sur ce workspace, ou le token ne porte pas le scope read
404not_foundL'entreprise ou l'écriture n'est pas atteignable par vos habilitations

Une page au-delà de la fin :

{
"error": "bad_request",
"message": "Le numéro de page dépasse le nombre de pages disponibles"
}

Un page qui n'est pas un entier valide porte le message "Le numéro de page doit être un entier supérieur ou égal à 1". Sur une collection vide, aucun numéro de page ne déborde : la réponse est un 200 avec une collection vide.

Une ressource hors de portée répond 404, jamais 403. L'atteignabilité est tranchée avant la question des droits : une écriture d'un workspace que vos habilitations ne couvrent pas, une écriture qui n'existe pas et une écriture d'origine facture reçoivent la même réponse, de sorte que la réponse ne permet pas de deviner laquelle des trois vous avez rencontrée.

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

Le 403 est réservé à ce qui relève des droits et non de l'atteignabilité : une habilitation manquante sur le workspace nommé dans le chemin, ou un scope insuffisant.

Référence API​