API bexio depuis Make et Zapier : ce que les modules prêts à l’emploi ne font pas

Make et Zapier proposent bexio comme app prête à l’emploi : quelques champs à remplir, et la facture est dans la comptabilité. Pourtant, les forums communautaires des deux services contiennent depuis 2023 des questions sur bexio restées sans solution, parce qu’il manque au module un champ ou un point d’accès. J’ai parcouru ces fils et je les ai comparés à la documentation officielle de l’API bexio. Ce guide montre, cas par cas, où cela a bloqué dans le forum et quel champ de l’API bexio résout le cas. Il décrit les modules tels que les personnes qui posent la question les décrivent ; il ne repose pas sur une expérience personnelle de Make ou de Zapier.

Déroulement : la boutique, le formulaire ou le prestataire de paiement fournissent les données, un service dédié parle à l’API bexio avec tous les champs, api.bexio.com crée la facture, l’offre ou la saisie de tempsBoutique, formulaire,prestataire de paiementCommande, demande oupaiementService dédiéTous les champs del’API, les erreurssont réessayéesapi.bexio.comFacture avec lignes,offre, saisie detemps, PDFDéroulement : la boutique, le formulaire ou le prestataire de paiement fournissent les données, un service dédié parle à l’API bexio avec tous les champs, api.bexio.com crée la facture, l’offre ou la saisie de tempsBoutique, formulaire, prestataire de paiementCommande, demande ou paiementService dédiéTous les champs de l’API, les erreurssont réessayéesapi.bexio.comFacture avec lignes, offre, saisie detemps, PDF

D’où viennent les huit cas

Les cas proviennent des forums publics community.make.com et community.zapier.com, questions posées de 2023 à 2025. Chaque cas est lié ci-dessous. « Sans solution » signifie : le fil ne contient aucune réponse confirmée par la personne qui a posé la question, ou la réponse renvoie au support. Plusieurs personnes signalent le même schéma, parfois à des mois d’intervalle. La solution par l’API est à chaque fois étayée par la documentation ; les chemins y figurent tels quels.

Cas 1 : plusieurs lignes dans une facture

Le problème le plus fréquent. Dans Make, quelqu’un veut écrire plusieurs lignes dans une facture bexio ; le module refuse la liste, et « Update Invoice » ne propose aucune ligne. Dans Zapier, la même chose échoue avec une commande Shopify de plusieurs produits, avec une commande WooCommerce via un détour par une boucle et un stockage intermédiaire, et avec un paiement Payrexx, où le message indique que la liste des montants n’a pas la même longueur que la liste des articles ; au bout du compte, un brouillon sans lignes et un total de 0.

Dans l’API, ce n’est pas un cas particulier. POST /2.0/kb_invoice accepte un tableau positions, et la documentation précise que les types de lignes se combinent : KbPositionCustom pour les lignes libres, KbPositionArticle pour les articles du catalogue, plus des lignes de texte, de sous-total, de remise et de saut de page. Une facture de deux lignes ressemble à ceci :

{
  "contact_id": 14,
  "user_id": 1,
  "mwst_type": 0,
  "mwst_is_net": true,
  "positions": [
    { "type": "KbPositionArticle", "article_id": 3, "amount": "2", "unit_price": "45.00", "tax_id": 4 },
    { "type": "KbPositionCustom", "text": "Livraison", "amount": "1", "unit_price": "9.00", "tax_id": 4 }
  ]
}

bexio recommande au plus 150 lignes à la création ; les lignes suivantes s’ajoutent ensuite avec POST /2.0/kb_invoice/{document_id}/kb_position_article ou …/kb_position_custom. Livraison et remise sont ainsi des lignes ordinaires, sans voie détournée.

Cas 2 : numéro de document des offres

Un utilisateur de Zapier ne peut pas créer d’offre : bexio exige document_nr, l’action n’a pas de champ pour cela ; une deuxième personne touchée se manifeste dans le même fil. Une autre ne retrouve pas une offre par son numéro, alors que le même numéro donne un résultat dans un autre outil.

La documentation de POST /2.0/kb_offer explique la règle : document_nr ne doit pas être renseigné si la numérotation automatique est active dans bexio, et il est obligatoire si elle est désactivée. Un module sans ce champ ne fonctionne donc qu’avec la numérotation automatique. Qui tient ses propres numéros les transmet par l’API. La recherche passe par POST /2.0/kb_offer/search avec document_nr comme champ de recherche :

[{ "field": "document_nr", "value": "AN-00001", "criteria": "=" }]

Sans criteria, bexio cherche en mode « like », donc par correspondance partielle ; pour un numéro, = est la voie sûre. Les mêmes champs de recherche existent pour les factures sous POST /2.0/kb_invoice/search.

Cas 3 : taux de TVA par ligne

Une facture arrive dans bexio avec 7,7 % au lieu de 8,1 %, et le taux ne se choisit pas dans le module. Zapier confirme dans le fil un rapport de bogue ; la solution de contournement consiste à enregistrer le taux sur le produit dans bexio.

Dans l’API, chaque ligne porte son champ tax_id. Les valeurs valables viennent de GET /3.0/taxes?types=sales_tax&scope=active ; c’est exactement l’appel que recommande la documentation, parce que seules les taxes sur les ventes actives sont admises sur les offres, les commandes et les factures. La réponse donne pour chaque taux id, code, value et les années de validité. Un service lit cette liste une fois et choisit la tax_id d’après le pourcentage, au lieu de figer un numéro qui deviendra faux au prochain changement de taux.

Cas 4 : référence pour le rapprochement des paiements

Quelqu’un crée des factures depuis un Google Sheet et veut écrire la référence à 27 positions dans le champ de référence, pour que bexio attribue automatiquement les paiements reçus de la banque. Zapier enregistre une demande de fonctionnalité ; aucune échéance n’est donnée.

La facture a deux champs de référence dans l’API. reference est un texte libre sur le document. api_reference, selon la documentation, ne se lit et ne se modifie que par l’API et sert à stocker des renvois vers d’autres systèmes, par exemple le numéro de commande de la boutique ou l’identifiant de paiement du prestataire ; c’est aussi un champ de recherche de POST /2.0/kb_invoice/search. La réponse d’une facture contient en outre qr_invoice_id. Un champ permettant de définir soi-même la référence de la section de paiement QR n’est pas décrit dans la documentation.

Qui reçoit de toute façon le paiement signalé par un prestataire n’a pas besoin du rapprochement bancaire pour cela : POST /2.0/kb_invoice/{invoice_id}/payment enregistre le paiement directement sur la facture avec date, value et bank_account_id. Le paiement figure alors sur la facture dans bexio, et personne ne relance des clients qui ont payé depuis longtemps.

Cas 5 : utilisateur dans la saisie des temps

Des saisies de temps venant d’un Google Sheet doivent être attribuées au bon collaborateur dans bexio. Dans le module Zapier, l’identifiant d’utilisateur ne se définit pas ; le champ se remplit avec un contact, et la personne ne trouve aucune issue.

POST /2.0/timesheet exige user_id comme champ obligatoire, ainsi que client_service_id pour la prestation, allowable_bill pour « facturable » et un objet tracking, soit comme durée (type: duration avec date et duration), soit comme plage horaire (type: range). Les utilisateurs viennent de GET /3.0/users, les prestations de GET /2.0/client_service. Contact et projet sont facultatifs (contact_id, pr_project_id). Une saisie d’une heure quarante :

{
  "user_id": 1,
  "client_service_id": 1,
  "allowable_bill": true,
  "contact_id": 2,
  "tracking": { "type": "duration", "date": "2026-11-04", "duration": "01:40" }
}

Cas 6 : PDF d’une offre

Un utilisateur de Make veut archiver des offres en PDF dans DocuWare. Il existe un module pour les factures, pas pour les offres ; l’essai avec un appel HTTP donne un PDF qui ne s’ouvre pas. La seule réponse renvoie aux bases du HTTP.

GET /2.0/kb_offer/{quote_id}/pdf fournit le document, avec ou sans papier à en-tête (logopaper). Le point où la personne a échoué : la réponse n’est pas un PDF, mais du JSON avec les champs name, size, mime et content, et content contient le fichier encodé en Base64. Ce n’est qu’après décodage qu’on obtient un fichier PDF valide. Il en va de même pour les factures (/2.0/kb_invoice/{invoice_id}/pdf) et les commandes (/2.0/kb_order/{order_id}/pdf).

Cas 7 : détecter les factures modifiées

Le déclencheur Make « Watch Invoices », selon une personne du forum, ne livre aucun enregistrement quand une facture est seulement modifiée. Une personne qui répond soupçonne un bogue du module, une deuxième propose de passer par une recherche.

L’API offre pour cela le champ de recherche updated_at avec des critères de comparaison. Un service retient l’horodatage de sa dernière exécution et interroge :

[{ "field": "updated_at", "value": "2026-11-04 06:00:00", "criteria": ">" }]

sur POST /2.0/kb_invoice/search?order_by=updated_at_desc. Le format de date correspond à celui que bexio renvoie dans updated_at. Les factures nouvelles et modifiées apparaissent ainsi de la même manière, par exemple un passage au statut « payée ».

Cas 8 : facture à partir d’une commande

Une commande Shopify devient dans Make une commande bexio ; la facture doit en être tirée par un appel HTTP, faute de module. L’appel échoue avec le statut 415, alors que le même appel fonctionne dans Postman. Le support de Make confirme dans le fil un problème connu (« known issue ») et le transmet au développement, sans échéance.

Le point d’accès est POST /2.0/kb_order/{order_id}/invoice. Le corps est facultatif : s’il manque, bexio reprend toutes les lignes de la commande ; sinon positions nomme les lignes voulues avec id, type et amount. Le statut 415 signifie que le serveur n’accepte pas le type de contenu de la requête ; la documentation exige Accept: application/json et du JSON comme corps. Un service dédié définit lui-même les en-têtes et ne dépend pas de la façon dont un intermédiaire les transmet.

Les huit cas en un coup d’œil

CasDans le forumDans l’API bexio
Plusieurs lignesliste refusée, brouillon avec total 0positions dans POST /2.0/kb_invoice, types combinés
Numéro de documentchamp obligatoire absent, recherche sans résultatdocument_nr, recherche avec criteria: "="
Taux de TVAnon sélectionnable, mauvais tauxtax_id par ligne, liste depuis /3.0/taxes
Référencechamp absent, demande de fonctionnalité ouvertereference, api_reference, paiement via …/payment
Saisie des tempsutilisateur non définissableuser_id dans POST /2.0/timesheet
PDF d’offrepas de module, fichier illisible/2.0/kb_offer/{id}/pdf, décoder content en Base64
Factures modifiéesle déclencheur ne réagit pasrecherche sur updated_at avec >
Facture depuis commandepas de module, statut 415POST /2.0/kb_order/{id}/invoice

S’y ajoute un risque qu’aucun champ ne couvre : un utilisateur de Zapier signale que bexio a bloqué l’ID client de l’app Zapier et que sa connexion s’est arrêtée avec elle. Qui se connecte par une app tierce dépend de son autorisation ; une app propre dans le Developer Portal ne dépend que de la vôtre. Sa création est décrite dans le guide Créer un token d’accès à l’API bexio, la connexion par OAuth 2 dans le guide Connecter l’API bexio à WordPress.

Quand la connexion directe vaut la peine

Pour un contact issu d’un formulaire, les modules prêts à l’emploi suffisent la plupart du temps. Dès qu’il s’agit de factures à plusieurs lignes, de numéros propres, de taux de TVA, de saisies de temps par collaborateur ou de PDF, le détour par la plateforme intermédiaire coûte plus de temps qu’il n’en fait gagner : chaque champ manquant devient un fil de forum sans fin.

Une interface qui parle directement à l’API bexio, je la construis à prix fixe : vous m’indiquez le système source et le déroulement, je fixe le périmètre sur vos vrais documents, la connexion tourne sur votre propre infrastructure sans abonnement chez un tiers, avec nouvelle tentative en cas d’erreur et un journal qui montre ce qui a été transmis. Pour HubSpot, la connexion existe déjà : bexio ↔ HubSpot transforme un deal gagné en offre ou en facture avec ses lignes et renvoie l’état du paiement. Pour tout le reste : Contact, avec le système source et ce qui se fait aujourd’hui à la main.

Tous les guides