Démarrer avec l’API de FactuPilot

Votre logiciel métier crée les clients et les factures dans FactuPilot, qui les numérote, les met au format Factur-X et les transmet à votre plateforme agréée.

Le plan Business

L’API est réservée au plan Business (49 € par mois, 6 utilisateurs inclus). Le propriétaire de l’entreprise le choisit dans Abonnement.

L’accès est vérifié à chaque appel : si l’entreprise quitte le plan Business, ses clés cessent aussitôt de répondre (erreur 403) et reprennent dès son retour sur le plan.

Créer une clé

  1. Ouvrez l’onglet API

    Dans Paramètres > API, la section « Brancher votre logiciel » contient le formulaire « Créer une nouvelle clé API ». Il est réservé au propriétaire et aux administrateurs.

  2. Nommez la clé et cochez ses portées

    Donnez-lui un nom parlant (par exemple « Intégration comptable ») et cochez uniquement ce dont votre logiciel a besoin : lecture ou écriture des clients, des factures et des devis. Pour ce tutoriel : clients:read, clients:write et invoices:write.

  3. Copiez la clé

    Cliquez sur « Créer la clé API ». La clé, fp_live_ suivi de 32 caractères, ne s’affiche qu’une seule fois : copiez-la aussitôt. Si vous la perdez, révoquez-la et créez-en une autre.

Votre premier appel

Rangez la clé dans une variable d’environnement de votre terminal, pour ne pas la recopier dans chaque commande :

export FACTUPILOT_API_KEY="fp_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

Toutes les requêtes sont en HTTPS, sur https://factupilot.fr/api/v1, avec la clé dans l’en-tête Authorization: Bearer. Listez cinq clients :

curl "https://factupilot.fr/api/v1/clients?limit=5" \
  -H "Authorization: Bearer $FACTUPILOT_API_KEY"

Une réponse 200 avec un objet data et un bloc pagination confirme que la clé fonctionne. Un 401 signale une clé absente, inconnue, expirée ou mal formée ; un 403, une portée manquante ou un plan sans API.

Émettre une facture

  1. Créez le client

    curl -X POST "https://factupilot.fr/api/v1/clients" \
      -H "Authorization: Bearer $FACTUPILOT_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"name": "Boulangerie Dupont", "email": "contact@boulangerie-dupont.fr"}'

    La réponse (201) contient le client dans data ; gardez son data.id.

  2. Émettez la facture en un appel

    Avec "emettre": true, la facture naît émise et numérotée. Sans cet indicateur, elle naît en brouillon.

    curl -X POST "https://factupilot.fr/api/v1/invoices" \
      -H "Authorization: Bearer $FACTUPILOT_API_KEY" \
      -H "Content-Type: application/json" \
      -H "Idempotency-Key: commande-2026-0042" \
      -d '{
        "clientId": "<le champ data.id renvoyé à la création du client>",
        "emettre": true,
        "items": [
          { "description": "Transport Perpignan - Toulouse", "quantity": 1, "unitPriceHt": 420, "vatRate": 20 }
        ]
      }'
    Extrait de la réponse (201).
    {
      "data": {
        "number": "FA-2026-0044",
        "status": "SENT",
        "totalHt": 420,
        "totalVat": 84,
        "totalTtc": 504,
        "transmission": {
          "statut": "transmise",
          "plateforme": "superpdp",
          "message": "Facture transmise à Super PDP."
        }
      }
    }
  3. Ou émettez un brouillon plus tard

    Un brouillon créé par l’API s’émet ensuite avec une seconde requête. Un brouillon saisi dans FactuPilot ne s’émet que depuis FactuPilot (erreur 409).

    curl -X POST "https://factupilot.fr/api/v1/invoices/<id de la facture>/emettre" \
      -H "Authorization: Bearer $FACTUPILOT_API_KEY"
  • Vous envoyez des lignes, jamais des totaux. FactuPilot calcule les montants. Ils sont en euros, jamais en centimes.
  • Précisez toujours le taux de TVA. Une ligne sans vatRate est à 0 %, et une ligne à 0 % exige un motif (motifTvaZero) pour une entreprise assujettie.
  • Une facture émise ne se modifie plus. Une correction passe par un avoir, depuis FactuPilot.

Rejouer sans doublon

L’en-tête Idempotency-Key (1 à 100 caractères visibles, sans espace : un UUID, ou la référence de la facture dans votre logiciel) rend l’appel rejouable. Si votre client HTTP abandonne avant la réponse, renvoyez exactement la même requête avec la même clé.

  • Sans l’en-tête, rejouer la requête crée une seconde facture et consomme un nouveau numéro.
  • Avec l’en-tête, le rejeu répond 200 (et non 201) avec la facture déjà créée et l’en-tête Idempotent-Replayed: true. Aucun doublon, aucun numéro consommé, aucune retransmission.

La clé désigne la facture, pas le corps de la requête : la même clé avec un autre corps rend quand même la facture d’origine. Les créations de clients et de devis ne sont pas idempotentes : après un échec incertain, vérifiez avec la liste avant de rejouer.

La transmission automatique

FactuPilot peut remettre à votre plateforme agréée les factures émises par l’API, sans action de votre part. Activez le réglage dans Paramètres > API, section « Transmission automatique » : « Transmettre à votre plateforme agréée les factures émises par l’API ». Désactivé, ce qui est le cas par défaut, les factures sont numérotées et mises en forme, mais aucune n’est envoyée tant que vous ne la transmettez pas vous-même.

La transmission est attendue avant la réponse : l’appel peut donc durer plus longtemps qu’une simple création. Son résultat figure dans data.transmission :

statutSens
transmiseLa facture est remise à la plateforme.
refuseeUne règle l’interdit, rien n’est parti : plan, dépôt manuel, adresse électronique de l’acheteur manquante.
echecIncident : à relancer depuis FactuPilot.
desactiveeLa transmission automatique n’est pas activée pour l’entreprise (ou coupée sur ce serveur).
inconnueRéponse d’un rejeu dont la transmission n’est pas encore enregistrée ; rien n’est retransmis.

Recevoir des webhooks

Plutôt que d’interroger l’API, laissez FactuPilot prévenir votre serveur. Dans Paramètres > API, section « Webhooks », « Ajouter un webhook » : saisissez l’adresse de réception (HTTPS, port 443 uniquement), cochez les événements, puis « Créer le webhook ». FactuPilot affiche alors le secret de signature, whsec_ suivi de 32 caractères, une seule fois. Le bouton « Envoyer un test » envoie un événement webhook.test.

ÉvénementQuand
facture.creeeUne facture vient d’être créée, par l’API ou depuis FactuPilot.
facture.emiseUne facture vient d’être émise.
facture.payeeUne facture vient d’être entièrement payée, paiement en ligne compris.
facture.statut_plateformeLe suivi de la facture par la plateforme agréée a changé.
Corps reçu par votre serveur (extrait).
{
  "id": "evt_9f2c4a7e1b3d58606a1c0e2f",
  "type": "facture.emise",
  "creeLe": "2026-10-16T09:12:44.318Z",
  "donnees": {
    "facture": { "numero": "FA-2026-0043", "statut": "SENT", "totalTtc": 1032 }
  }
}
  • Vérifiez la signature de chaque requête (en-tête X-FactuPilot-Signature) sur le corps brut, avant tout JSON.parse. La documentation en donne le code complet.
  • Répondez en 2xx en moins de 10 secondes. Sinon, FactuPilot réessaie jusqu’à 6 tentatives au total, avec le même identifiant d’événement.
  • Dédupliquez sur l’identifiant (id, repris dans X-FactuPilot-Livraison) et ne comptez pas sur l’ordre des événements.
  • Cinq webhooks au plus par entreprise ; le secret se régénère s’il a fuité.

Pour aller plus loin

La documentation de l’API détaille chaque opération (clients, factures, devis, PDF), les portées, les limites de débit (par exemple 30 écritures par minute, 429 avec Retry-After au-delà), les codes d’erreur et les exemples de réponse. La section Webhooks donne la vérification de signature pas à pas.

La description OpenAPI se télécharge sur /api/v1/openapi.json et s’importe dans Postman ou Insomnia.

À lire ensuite

Une étape reste floue, ou un écran ne ressemble pas à ce tutoriel ? Écrivez-nous ou envoyez un message à contact@factupilot.fr.