Aller au contenu principal

Entreprises et établissements

Les entreprises sont les entités légales pour le compte desquelles vous facturez dans Scribee : vendeur sur les factures de vente, acheteur sur les factures d'achat (Émettre une facture). La partie entreprise d'une facture ne peut jamais pointer vers une fiche de l'annuaire clients et fournisseurs : un party_id sur le rôle vendeur d'une facture de vente, ou acheteur d'une facture d'achat, est refusé. Omettez cette partie et Scribee la dérive de la fiche entreprise ; fournissez-la en clair et ce sont vos valeurs qui sont enregistrées. Les établissements décrivent les sites physiques d'une entreprise. Seul name est obligatoire ; le SIRET (legal_identifier) est facultatif et n'a aucune incidence sur l'adressage dans l'annuaire de la réforme. C'est l'entrée d'annuaire qui porte le SIRET décidant de sa maille : une entrée avec SIRET adresse l'établissement, une entrée au seul SIREN couvre l'entité légale entière. Cette entrée se crée avec son propre SIRET, indépendamment de vos fiches établissement, qu'elles en portent un ou non (Annuaire national). Cette page couvre la création et la gestion des deux par l'API.

Ce que Scribee fait pour vous​

  • Normalise l'identifiant légal et le numéro de TVA d'une entreprise à l'enregistrement : espaces en début et fin retirés, lettres mises en majuscules.
  • Refuse un identifiant légal ou un numéro de TVA déjà enregistré : chaque identifiant n'existe qu'une fois dans Scribee, tous espaces de travail confondus. Le SIRET d'un établissement suit la même règle.
  • Vérifie que l'identifiant légal d'une entreprise française est son SIREN de 9 chiffres : un SIRET y est refusé.
  • Vérifie que le SIRET d'un établissement compte exactement 14 chiffres.
  • Garde au moins une entreprise par espace de travail : la dernière n'est pas supprimable.

Étape 1 : créer une entreprise​

Cet appel crée la fiche entreprise dans votre espace de travail. Il ne transmet rien vers l'extérieur : ni au PPF (Portail Public de Facturation), ni au réseau Peppol. Il se défait avec le DELETE de l'étape 6, mais seulement tant que l'entreprise n'a produit aucune donnée rattachée : l'étape 6 en donne la liste complète, lisez-la avant de compter sur cette réversibilité. Le scope write est requis.

curl -X POST https://app.scribee.tech/api/v1/workspaces/YOUR_WORKSPACE_ID/companies \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"company": {
"name": "Acme Corp SAS",
"commercial_name": "Acme",
"legal_registering_country": "FR",
"legal_identifier": "443061841",
"vat_identifier": "FR32443061841"
}
}'

Réponse 201, abrégée aux champs utiles ici (chaque entreprise porte aussi created_at et updated_at) :

{
"data": {
"id": 7,
"name": "Acme Corp SAS",
"commercial_name": "Acme",
"legal_registering_country": "FR",
"legal_identifier": "443061841",
"vat_identifier": "FR32443061841",
"company_legal_form": null,
"parent_id": null
}
}

name est le seul champ obligatoire. legal_registering_country nomme le pays qui a immatriculé l'entreprise ; laissé vide, il vaut France. Quand il vaut FR ou qu'il est vide, legal_identifier porte le SIREN de l'entreprise, 9 chiffres exactement : un SIRET de 14 chiffres, comme toute autre valeur, est refusé en 422 avec l'erreur sous details.legal_identifier (Erreurs et cas limites). Les espaces entre les chiffres sont admis et retirés à l'enregistrement : 552 100 554 est accepté et enregistré 552100554, si bien qu'un SIREN déjà enregistré est refusé comme doublon quel que soit son espacement. Le SIRET identifie un établissement et se renseigne dans le legal_identifier de l'établissement (étape 4). Pour tout autre pays, le format est libre. Dans tous les cas, legal_identifier est unique et compte 50 caractères au maximum, 32 pour vat_identifier. Le contrôle du SIREN s'applique à la création, puis à chaque modification de legal_identifier ou de legal_registering_country : une entreprise enregistrée avant ce contrôle avec un autre identifiant reste modifiable sur ses autres champs. Avec legal_identifier, le pays décide du schéma d'immatriculation porté par la partie de facture dérivée de cette fiche - un SIREN sous un pays français donne siren, et une immatriculation étrangère ne donne aucun schéma (Émettre une facture). parent_id rattache l'entreprise à une société mère du même espace de travail, ce qui en fait une filiale ; un rattachement circulaire est refusé avec un statut 422, et une société mère située dans un autre espace de travail également. En revanche, un parent_id qui ne désigne aucune entreprise existante n'est pas validé : l'appel produit une erreur serveur, pas un 422. Vérifiez l'identifiant avec l'étape 2 avant de l'envoyer.

Étape 2 : lister et retrouver vos entreprises​

GET /api/v1/workspaces/{workspace_id}/companies retourne les entreprises de l'espace de travail ; le scope read suffit. Le paramètre include (valeurs parent, subsidiaries, establishments, séparées par des virgules) ajoute les associations à chaque fiche.

curl "https://app.scribee.tech/api/v1/workspaces/YOUR_WORKSPACE_ID/companies?include=establishments" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
{
"data": [
{
"id": 7,
"name": "Acme Corp SAS",
"legal_identifier": "443061841",
"establishments": [
{
"id": 21,
"name": "Siège Paris",
"legal_identifier": "44306184100025",
"headquarters": true
}
]
}
],
"meta": {
"current_page": 1,
"per_page": 20,
"total_pages": 1,
"total_count": 1
}
}

La liste est paginée (page, per_page - 20 par défaut, 100 au maximum) et triable (sort_by : name, commercial_name, legal_identifier, created_at ou updated_at ; sort_order : asc ou desc ; tri par défaut : name croissant). L'enveloppe et la pagination sont décrites dans Conventions de l'API. GET /api/v1/companies/{id} retourne une fiche seule, avec le même paramètre include.

Étape 3 : modifier une entreprise​

Cet appel modifie la fiche dans votre espace de travail, sans transmission externe. Il se défait en rétablissant les valeurs précédentes par le même endpoint. Les champs sont ceux de la création.

curl -X PATCH https://app.scribee.tech/api/v1/companies/7 \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "company": { "commercial_name": "Acme France" } }'

Réponse 200 avec la fiche mise à jour, au même format que l'étape 1.

Étape 4 : déclarer les établissements​

Cet appel crée la fiche établissement sous l'entreprise, sans transmission externe. Il se défait par le DELETE de l'étape 5 tant qu'aucune unité organisationnelle n'est assignée à l'établissement et qu'aucune demande d'annuaire ne le référence. name est le seul champ obligatoire ; legal_identifier porte le SIRET (14 chiffres exactement), et ce SIRET doit être libre dans toute l'installation Scribee, pas seulement dans votre espace de travail.

curl -X POST https://app.scribee.tech/api/v1/companies/7/establishments \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"establishment": {
"name": "Siège Paris",
"legal_identifier": "44306184100025",
"headquarters": true,
"address_line_1": "123 Rue de Paris",
"postal_code": "75001",
"city": "Paris",
"country": "FR"
}
}'
{
"data": {
"id": 21,
"company_id": 7,
"name": "Siège Paris",
"legal_identifier": "44306184100025",
"headquarters": true,
"address_line_1": "123 Rue de Paris",
"postal_code": "75001",
"city": "Paris",
"country": "FR"
}
}

Le siège social est l'établissement dont le drapeau headquarters vaut true. La création d'une entreprise ne crée aucun établissement : déclarez le siège vous-même avec ce drapeau. Le drapeau n'est pas exclusif ; marquez un seul établissement comme siège par entreprise.

Étape 5 : lister, modifier, supprimer un établissement​

GET /api/v1/companies/{company_id}/establishments retourne les établissements de l'entreprise - paginée et triable (sort_by : name, legal_identifier, headquarters, created_at ou updated_at), avec include=company pour rappeler l'entreprise sur chaque fiche. GET /api/v1/establishments/{id} retourne une fiche seule.

curl -X PATCH https://app.scribee.tech/api/v1/establishments/21 \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "establishment": { "address_line_2": "Bâtiment A" } }'

DELETE /api/v1/establishments/{id} supprime la fiche définitivement - réponse 204 sans corps ; le scope write est requis. La suppression est refusée par un 422 tant que des unités organisationnelles sont assignées à l'établissement (les unités organisationnelles se gèrent depuis l'interface Scribee). Elle est refusée par le même 422 si une demande de modification d'annuaire référence l'établissement - une inscription faite par les endpoints d'Annuaire national suffit à créer cette référence. Les deux refus portent le code dependent_records.

Étape 6 : supprimer une entreprise​

Cet appel supprime définitivement la fiche entreprise et les données rattachées, dont ses établissements et ses fiches clients et fournisseurs. Il ne transmet rien vers l'extérieur. Le scope write est requis.

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

Réponse 204 sans corps.

Une entreprise qui a porté au moins une facture ne peut pas être supprimée par l'API. C'est le cas le plus courant en production : traitez le DELETE comme réservé aux fiches créées par erreur et encore vierges, pas comme un mécanisme d'annulation général.

Voici la liste complète des conditions qui font échouer la suppression :

ConditionRéponse
L'entreprise est la dernière de l'espace de travail422, code = operation_failed, "Impossible de supprimer la dernière entreprise de l'espace de travail"
L'entreprise porte au moins un mandat, quel que soit son état422, code = dependent_records, "Impossible de supprimer une entreprise qui a des mandats"
L'entreprise a des filiales422, code = dependent_records, "Impossible de supprimer une entreprise qui a des filiales"
L'entreprise a des demandes de prélèvement ou des mandats de prélèvement422, code = dependent_records, message nommant l'association bloquante
L'entreprise est référencée par une facture, un lot d'import de factures, un document d'achat (commande, réception, demande, rapprochement) ou une demande de modification d'annuaire422, code = dependent_records, message nommant l'association bloquante

Trois précisions sur ce tableau :

  • Le blocage par mandat est définitif. DELETE /api/v1/mandates/{id} fait passer le mandat à l'état deleted et la résiliation à l'état terminated, mais l'une comme l'autre conservent la ligne. Une entreprise qui a un jour porté un mandat reste donc bloquée, quel que soit le nettoyage effectué ensuite (Mandats de facturation électronique).
  • Les deux dernières lignes nomment le document bloquant. L'appel retourne un 422 de code dependent_records, dont le message nomme l'association en cause - "Vous ne pouvez pas supprimer l'enregistrement parce que les factures dépendants existent" quand ce sont des factures. Plusieurs associations bloquantes sont énumérées dans le même message. Branchez votre logique de reprise sur le code, jamais sur le texte.
  • La seule issue est de traiter les documents en amont. Supprimez ou réaffectez les factures, documents d'achat et demandes d'annuaire concernés depuis l'interface Scribee, puis rejouez le DELETE. Si ces documents doivent être conservés, l'entreprise n'est pas supprimable : laissez-la en place et contactez Scribee.

Ce qui se passe ensuite​

  • La fiche entreprise alimente chaque facture émise sous son identité (Émettre une facture) : quand vous n'envoyez pas la partie vendeur d'une facture de vente, ou la partie acheteur d'une facture d'achat, Scribee la construit à partir de la fiche entreprise et de son siège social.
  • Des réglages consommés par la facturation se configurent par entreprise depuis l'interface Scribee et n'apparaissent pas dans la fiche de l'API : le motif de numérotation des factures et des devis, et les mentions légales ajoutées aux factures générées (pénalités de retard, frais de recouvrement, escompte). company_legal_form (la forme juridique) est présent en lecture dans les réponses mais se renseigne depuis l'interface.
  • L'inscription des entreprises à l'annuaire national de la réforme se gère par les endpoints d'annuaire, décrits dans Annuaire national.

Erreurs et cas limites​

422 : champ manquant ou format invalide​

Un legal_identifier d'établissement qui n'est pas un SIRET de 14 chiffres :

{
"error": "unprocessable_entity",
"code": "validation_failed",
"message": "La validation a échoué",
"details": {
"base": ["Legal identifier doit être un SIRET valide (14 chiffres)"]
}
}

Les deux ressources ne remplissent pas details de la même façon. Un établissement regroupe ses erreurs sous la clé base, chaque message préfixé du nom du champ humanisé, comme ci-dessus. Une entreprise porte une clé par champ fautif - le nom du champ tel qu'il apparaît dans l'API - et ses messages n'ont pas ce préfixe : une entreprise sans name donne "name": ["doit être rempli(e)"]. Corrigez le champ et rejouez l'appel.

Un legal_identifier d'entreprise française qui n'est pas un SIREN de 9 chiffres - ici un SIRET, dont la place est sur l'établissement :

{
"error": "unprocessable_entity",
"code": "validation_failed",
"message": "La validation a échoué",
"details": {
"legal_identifier": ["doit être le SIREN à 9 chiffres d'une entreprise française, et non un SIRET à 14 chiffres : le SIRET identifie l'un de ses établissements et se renseigne sur l'établissement"]
}
}

422 : identifiant déjà enregistré​

Un legal_identifier ou un vat_identifier déjà présent dans Scribee est refusé avec "a déjà été pris", dans le format que sa ressource emploie : sous la clé legal_identifier ou vat_identifier pour une entreprise, sous base et préfixé - "Legal identifier a déjà été pris" - pour le SIRET d'un établissement.

L'unicité porte sur l'installation Scribee entière, pas sur votre espace de travail. La fiche en conflit peut donc appartenir à un espace de travail hors du périmètre de votre application : vous ne la trouverez pas, et rejouer l'appel ne changera rien. Cherchez d'abord dans votre espace de travail ; si rien n'y correspond, l'identifiant est pris ailleurs et il faut contacter Scribee.

422 : suppression bloquée​

La suppression refusée retourne le motif dans message, sans objet details :

{
"error": "unprocessable_entity",
"code": "dependent_records",
"message": "Impossible de supprimer une entreprise qui a des filiales"
}
  • "Impossible de supprimer une entreprise qui a des mandats" : ce blocage est définitif, aucun appel de l'API ne le lève (voir l'étape 6).
  • "Impossible de supprimer la dernière entreprise de l'espace de travail" : chaque espace de travail conserve au moins une entreprise. Seul ce refus porte le code operation_failed et non dependent_records.
  • "Impossible de supprimer un établissement auquel des unités organisationnelles sont assignées" : retirez d'abord les assignations depuis l'interface Scribee.
  • Tout autre document rattaché produit un message construit par Scribee qui nomme l'association bloquante, sur le modèle de "Vous ne pouvez pas supprimer l'enregistrement parce que les factures dépendants existent".

422 : référence non résolue​

Deux situations tiennent à une référence qui ne se résout pas. Toutes deux restent dans l'enveloppe d'erreur habituelle :

  • Un POST ou un PATCH d'entreprise dont le parent_id ne désigne aucune entreprise existante : code vaut validation_failed et details porte la clé parent. Vérifiez l'identifiant avec l'étape 2 avant de l'envoyer.
  • Un DELETE d'entreprise ou d'établissement encore référencé par des documents (voir l'étape 6) : code vaut dependent_records et le message nomme l'association bloquante.

Dans les deux cas, corrigez la donnée en amont, ou contactez Scribee.

404 Not Found​

L'entreprise ou l'établissement n'existe pas, ou appartient à un espace de travail hors du périmètre de votre application :

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

Vérifiez l'identifiant et le rattachement du workspace (Votre premier appel).

Sur GET, PATCH et DELETE /api/v1/companies/{id} et /api/v1/establishments/{id}, une adresse IP absente de la liste d'autorisation de l'espace de travail produit ce même 404, et non un 403 : la fiche existe, mais votre appel ne la voit pas. Vérifiez votre IP d'appel avant de conclure à un identifiant erroné.

403 Forbidden​

Sur les endpoints préfixés par {workspace_id}, un client OAuth non rattaché à l'espace de travail reçoit "L'application n'a pas accès à cet espace de travail", et une adresse IP absente de la liste d'autorisation de l'espace de travail reçoit "Cette adresse IP n'est pas autorisée pour cet espace de travail". Un token sans le scope requis (write pour créer, modifier et supprimer) reçoit :

{
"error": "forbidden",
"message": "Vous n'êtes pas autorisé à effectuer cette action"
}

Redemandez un token avec les scopes voulus (Authentification).

400 Bad Request : page au-delà de la dernière​

Sur les listes, demander une page au-delà de la dernière page d'une collection non vide retourne "Le numéro de page dépasse le nombre de pages disponibles". Bornez vos requêtes avec meta.total_pages.

Pages liées​