Isolation
Toutes les ressources sont limitées au compte propriétaire de la clé. Impossible de lire / modifier les données d’un autre tenant.
Documentation API · v1
Guide prêt à l’emploi : créer une clé, authentifier vos appels, créer clients & factures, récupérer les PDF et vérifier les webhooks. Exemples curl inclus.
Plan Business · Base URL /api/v1
/developer). LIVE (ou TEST pour le préfixe nf_test_). Copiez-la immédiatement — elle n’est plus réaffichée. export NF_KEY="nf_live_…" Les clés nf_test_* pointent vers les mêmes données que LIVE (préfixe distinct uniquement — pas de sandbox isolée pour l’instant).
Chaque requête /api/v1/** exige une clé API. Un JWT de session web est refusé sur cette API.
Authorization: Bearer nf_live_<secret>
# ou
X-Api-Key: nf_live_<secret>Par défaut, une clé a tous les scopes. Vous pouvez restreindre à la création :
clients:read / clients:writeinvoices:read / invoices:writequotes:read / quotes:write Sans le bon scope → 403 avec code: "insufficient_scope".
Toutes les ressources sont limitées au compte propriétaire de la clé. Impossible de lire / modifier les données d’un autre tenant.
Les listes renvoient { data, page, size, total, totalPages }. Utilisez ?page=0&size=50 (max 100).
~60 requêtes / minute / clé. Au-delà → 429rate_limited. Headers X-RateLimit-* fournis.
Local : /api/v1
Prod : https://<votre-hôte>/api/v1
Enchaînement classique pour facturer depuis votre application :
POST /clients puis stockez le id.
POST /invoices avec clientId, taxRate et lines.
POST /invoices/{id}/send → numéro officiel + email.
GET /invoices/{id}/pdf → URL temporaire à télécharger.
invoice.* et quote.* (créée, envoyée, payée, acceptée, convertie, annulée…) pour garder votre système à jour.
Ressource de base. Créez d’abord un client pour obtenir un clientId utilisable sur les factures.
/clientsclients:readRetourne la page de clients du compte lié à la clé API.
Quand l’utiliser : Pour synchroniser un CRM, afficher une liste, ou retrouver un clientId avant de facturer.
Query :page (défaut 0), size (défaut 50, max 100)
Réponse
{
"data": [{ "id": 12, "name": "ACME", "email": "contact@acme.fr", ... }],
"page": 0,
"size": 50,
"total": 1,
"totalPages": 1
}Exemple curl
curl -s -H "Authorization: Bearer $NF_KEY" \
"/api/v1/clients?page=0&size=50"/clients/{id}clients:readRécupère un client par son identifiant interne Flow.
Quand l’utiliser : Après une création, ou pour vérifier SIRET / adresse avant d’émettre une facture.
Réponse
{
"id": 12,
"name": "ACME",
"legalName": "ACME SAS",
"email": "contact@acme.fr",
"phone": "+33102030405",
"address": "10 rue de Rivoli",
"postalCode": "75001",
"city": "Paris",
"country": "France",
"siret": "12345678900012",
"vatNumber": "FR12345678900",
"createdAt": "2026-07-25T10:00:00",
"updatedAt": "2026-07-25T10:00:00"
}Exemple curl
curl -s -H "Authorization: Bearer $NF_KEY" \
"/api/v1/clients/12"/clientsclients:writeAjoute un client à votre carnet Flow. L’email doit être unique **dans votre compte**.
Quand l’utiliser : Avant de créer une facture : vous aurez besoin du `id` renvoyé.
Body JSON
{
"name": "ACME",
"email": "contact@acme.fr",
"customerKind": "B2B",
"legalName": "ACME SAS",
"phone": "+33102030405",
"address": "10 rue de Rivoli",
"postalCode": "75001",
"city": "Paris",
"country": "France",
"siret": "12345678900012",
"vatNumber": "FR12345678900"
}Réponse
Même forme que le détail client (avec `id`).Exemple curl
curl -s -X POST -H "Authorization: Bearer $NF_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"ACME","email":"contact@acme.fr","city":"Paris","vatNumber":"FR12345678900"}' \
"/api/v1/clients"/clients/{id}clients:writeMet à jour partiellement les champs fournis (les autres restent inchangés).
Quand l’utiliser : Correction d’adresse, téléphone, SIRET, etc.
Body JSON
{ "phone": "+33102030405", "city": "Lyon" }Exemple curl
curl -s -X PATCH -H "Authorization: Bearer $NF_KEY" \
-H "Content-Type: application/json" \
-d '{"phone":"+33102030405"}' \
"/api/v1/clients/12"/clients/{id}clients:writeSupprime un client sans facture, devis ni facture récurrente associés.
Quand l’utiliser : Nettoyer un doublon ou un client créé par erreur.
Réponse
{ "message": "Client supprimé" }Exemple curl
curl -s -X DELETE -H "Authorization: Bearer $NF_KEY" \
"/api/v1/clients/12"Créez, émettez, récupérez le PDF. Les totaux HT/TTC sont calculés côté Flow à partir des lignes et du taux de TVA.
/invoicesinvoices:readListe paginée des factures du compte. Filtre optionnel par statut.
Quand l’utiliser : Tableau de bord externe, sync comptable, suivi des impayés.
Query :page, size, status (ex. Brouillon, A_Envoyer, En_Attente_de_Paiement, Payée, Annulée…)
Exemple curl
curl -s -H "Authorization: Bearer $NF_KEY" \
"/api/v1/invoices?page=0&size=50&status=En_Attente_de_Paiement"/invoices/{id}invoices:readRetourne la facture avec lignes, totaux HT/TTC, client et statut.
Quand l’utiliser : Afficher une facture dans votre UI, ou vérifier l’état avant envoi / PDF.
Réponse
{
"id": 10,
"number": "BROUILLON-…",
"status": "Brouillon",
"type": "FACTURE",
"clientId": 12,
"clientName": "ACME",
"emissionDate": "2026-07-25",
"dueDate": "2026-08-25",
"totalHt": 1950.00,
"totalTtc": 2340.00,
"taxRate": 20,
"lines": [
{ "id": 1, "name": "Conseil", "quantity": 3, "unitPrice": 650, "taxRate": 20 }
],
"createdAt": "2026-07-25T11:00:00"
}Exemple curl
curl -s -H "Authorization: Bearer $NF_KEY" \
"/api/v1/invoices/10"/invoicesinvoices:writeCrée une facture rattachée à un client existant. Les prestations (lignes) sont créées / réutilisées dans votre catalogue.
Quand l’utiliser : Depuis votre outil métier (CRM, ERP, marketplace) dès qu’une prestation est facturable.
Body JSON
{
"clientId": 12,
"taxRate": 20,
"emissionDate": "2026-07-25",
"dueDate": "2026-08-25",
"status": "Brouillon",
"lines": [
{ "name": "Conseil", "quantity": 3, "unitPrice": 650 }
]
}Exemple curl
curl -s -X POST -H "Authorization: Bearer $NF_KEY" \
-H "Content-Type: application/json" \
-d '{
"clientId": 12,
"taxRate": 20,
"status": "Brouillon",
"lines": [{"name":"Conseil","quantity":3,"unitPrice":650}]
}' \
"/api/v1/invoices"/invoices/{id}/readyinvoices:writeNumérote si besoin et passe `Brouillon` → `A_Envoyer`. Obligatoire avant `/send` si vous avez créé un brouillon.
Quand l’utiliser : Validation métier du brouillon avant émission.
Exemple curl
curl -s -X POST -H "Authorization: Bearer $NF_KEY" \
"/api/v1/invoices/10/ready"/invoices/{id}/sendinvoices:writePasse en `En_Attente_de_Paiement`, attribue un numéro officiel si besoin, webhook `invoice.sent`, notification in-app. Si la facture est encore en brouillon, elle est d’abord passée en « À envoyer » automatiquement.
Quand l’utiliser : Quand la facture est validée côté métier et doit être considérée comme émise.
Exemple curl
curl -s -X POST -H "Authorization: Bearer $NF_KEY" \
"/api/v1/invoices/10/send"/einvoice/painvoices:readIndique si la transmission PA est disponible pour le compte (mode, stub, adresse vendeur…).
Quand l’utiliser : Avant d’intégrer un flux e-facture.
Exemple curl
curl -s -H "Authorization: Bearer $NF_KEY" \
"/api/v1/einvoice/pa"/invoices/{id}/einvoice/readinessinvoices:readRetourne `readyForExport`, `paApplicable`, la liste des checks et la validation EN16931 le cas échéant.
Quand l’utiliser : Avant `transmit`, pour savoir ce qui bloque.
Exemple curl
curl -s -H "Authorization: Bearer $NF_KEY" \
"/api/v1/invoices/10/einvoice/readiness"/invoices/{id}/einvoice/transmissioninvoices:readDernier dépôt PA pour la facture (`NOT_SENT`, `SUBMITTED`, `REJECTED`…).
Quand l’utiliser : Suivi après transmit ou auto-PA au `/send`.
Exemple curl
curl -s -H "Authorization: Bearer $NF_KEY" \
"/api/v1/invoices/10/einvoice/transmission"/invoices/{id}/einvoice/transmitinvoices:writeDépose la facture électronique chez la Plateforme Agréée. Facture déjà émise (après `/send`), client B2B, checklist OK.
Quand l’utiliser : Contrôle explicite du dépôt PA depuis votre intégration.
Exemple curl
curl -s -X POST -H "Authorization: Bearer $NF_KEY" \
"/api/v1/invoices/10/einvoice/transmit"/invoices/{id}/pdfinvoices:readGénère (ou régénère) le PDF et renvoie une **URL de téléchargement temporaire** signée.
Quand l’utiliser : Archivage, pièce jointe dans votre outil, ou affichage au client hors Flow.
Réponse
{
"downloadUrl": "https://…/api/invoices/pdf/download/<token>",
"expiresInSeconds": 300
}Exemple curl
curl -s -H "Authorization: Bearer $NF_KEY" \
"/api/v1/invoices/10/pdf"/invoices/{id}invoices:writeRemplace client, taxe, dates et lignes d’un brouillon. Mêmes règles que la création.
Quand l’utiliser : Corriger un brouillon avant émission (montant, ligne oubliée, mauvais client…).
Body JSON
{
"clientId": 12,
"taxRate": 20,
"emissionDate": "2026-07-25",
"dueDate": "2026-08-25",
"lines": [
{ "name": "Conseil", "quantity": 4, "unitPrice": 650 }
]
}Exemple curl
curl -s -X PUT -H "Authorization: Bearer $NF_KEY" \
-H "Content-Type: application/json" \
-d '{"clientId":12,"taxRate":20,"lines":[{"name":"Conseil","quantity":4,"unitPrice":650}]}' \
"/api/v1/invoices/10"/invoices/{id}invoices:writeSupprime définitivement un brouillon sans paiement.
Quand l’utiliser : Nettoyer un brouillon créé par erreur.
Réponse
{ "message": "Facture supprimee" }Exemple curl
curl -s -X DELETE -H "Authorization: Bearer $NF_KEY" \
"/api/v1/invoices/10"/invoices/{id}/cancelinvoices:writePasse une facture émise en `Annulée`. Restitue le stock lié si applicable.
Quand l’utiliser : La prestation n’aura finalement pas lieu et aucun paiement n’a été encaissé.
Exemple curl
curl -s -X POST -H "Authorization: Bearer $NF_KEY" \
"/api/v1/invoices/10/cancel"/invoices/{id}/credit-noteinvoices:writeAvoir total (body vide ou `lines` omis) ou partiel (`lines` avec quantités à créditer) sur une facture émise.
Quand l’utiliser : Correction après émission, retour partiel, geste commercial.
Body JSON
{
"lines": [
{ "sourceLineItemId": 1, "quantity": 1 }
]
}Réponse
Une facture de type `AVOIR` (mêmes champs qu’une facture, montants négatifs).Exemple curl
curl -s -X POST -H "Authorization: Bearer $NF_KEY" \
-H "Content-Type: application/json" \
"/api/v1/invoices/10/credit-note"/invoices/{id}/paymentsinvoices:readHistorique des paiements (manuels ou Stripe) enregistrés sur la facture.
Quand l’utiliser : Rapprochement comptable, affichage du solde restant.
Réponse
[{
"id": 3,
"invoiceId": 10,
"amount": 1000.00,
"paidAt": "2026-08-01T10:00:00",
"method": "MANUAL",
"note": "Acompte"
}]Exemple curl
curl -s -H "Authorization: Bearer $NF_KEY" \
"/api/v1/invoices/10/payments"/invoices/{id}/paymentsinvoices:writeAjoute un paiement manuel sur une facture émise et renvoie la facture à jour (statut, montant restant dû).
Quand l’utiliser : Paiement reçu hors Stripe (virement, chèque, espèces…) à rapprocher.
Body JSON
{ "amount": 1000.00, "method": "MANUAL", "note": "Acompte" }Exemple curl
curl -s -X POST -H "Authorization: Bearer $NF_KEY" \
-H "Content-Type: application/json" \
-d '{"amount":1000.00,"method":"MANUAL"}' \
"/api/v1/invoices/10/payments"Créez, éditez, envoyez et convertissez des devis rattachés à un client existant — du brouillon jusqu’à la facture. Seules l’acceptation et le refus restent réservés à l’app / au portail client (parcours signé, pas un simple changement de statut par API).
/quotesquotes:readListe paginée des devis du compte. Filtre optionnel par statut.
Quand l’utiliser : Tableau de bord externe, suivi des devis en attente de réponse client.
Query :page, size, status (ex. Brouillon, A_Envoyer, Envoyé, Accepté, Refusé, Converti)
Exemple curl
curl -s -H "Authorization: Bearer $NF_KEY" \
"/api/v1/quotes?page=0&size=50&status=Envoyé"/quotes/{id}quotes:readRetourne le devis avec lignes, totaux HT/TTC, client et statut.
Quand l’utiliser : Afficher un devis dans votre UI, ou vérifier son statut avant relance.
Réponse
{
"id": 4,
"number": "DEV-2026-07-4",
"status": "Brouillon",
"clientId": 12,
"clientName": "ACME",
"emissionDate": "2026-07-25",
"validUntilDate": "2026-08-25",
"totalHt": 1950.00,
"totalTtc": 2340.00,
"taxRate": 20,
"lines": [
{ "id": 1, "name": "Conseil", "quantity": 3, "unitPrice": 650, "taxRate": 20 }
],
"createdAt": "2026-07-25T11:00:00"
}Exemple curl
curl -s -H "Authorization: Bearer $NF_KEY" \
"/api/v1/quotes/4"/quotesquotes:writeCrée un devis rattaché à un client existant. Les prestations (lignes) sont créées / réutilisées dans votre catalogue, comme pour les factures.
Quand l’utiliser : Depuis votre outil métier dès qu’un chiffrage doit être proposé au client.
Body JSON
{
"clientId": 12,
"taxRate": 20,
"emissionDate": "2026-07-25",
"validUntilDate": "2026-08-25",
"status": "Brouillon",
"lines": [
{ "name": "Conseil", "quantity": 3, "unitPrice": 650 }
]
}Exemple curl
curl -s -X POST -H "Authorization: Bearer $NF_KEY" \
-H "Content-Type: application/json" \
-d '{
"clientId": 12,
"taxRate": 20,
"status": "Brouillon",
"lines": [{"name":"Conseil","quantity":3,"unitPrice":650}]
}' \
"/api/v1/quotes"/quotes/{id}quotes:writeRemplace client, taxe, dates et lignes d’un devis brouillon.
Quand l’utiliser : Corriger un devis avant de le passer « À envoyer ».
Body JSON
{
"clientId": 12,
"taxRate": 20,
"emissionDate": "2026-07-25",
"validUntilDate": "2026-08-25",
"lines": [
{ "name": "Conseil", "quantity": 4, "unitPrice": 650 }
]
}Exemple curl
curl -s -X PUT -H "Authorization: Bearer $NF_KEY" \
-H "Content-Type: application/json" \
-d '{"clientId":12,"taxRate":20,"lines":[{"name":"Conseil","quantity":4,"unitPrice":650}]}' \
"/api/v1/quotes/4"/quotes/{id}quotes:writeSupprime définitivement un devis brouillon.
Quand l’utiliser : Nettoyer un devis créé par erreur.
Réponse
{ "message": "Devis supprimé" }Exemple curl
curl -s -X DELETE -H "Authorization: Bearer $NF_KEY" \
"/api/v1/quotes/4"/quotes/{id}/statusquotes:writeChange le statut entre `Brouillon` et `A_Envoyer` uniquement. L’envoi, l’acceptation et le refus suivent un parcours dédié (e-mail signé / portail client), pas un simple changement de statut.
Quand l’utiliser : Repasser un devis « À envoyer » en brouillon pour le corriger, ou l’y préparer.
Body JSON
{ "status": "A_Envoyer" }Exemple curl
curl -s -X PATCH -H "Authorization: Bearer $NF_KEY" \
-H "Content-Type: application/json" \
-d '{"status":"A_Envoyer"}' \
"/api/v1/quotes/4/status"/quotes/{id}/sendquotes:writeGénère le PDF et l’envoie au client (ou à `recipientEmail`). Passe `A_Envoyer` → `Envoyé` automatiquement.
Quand l’utiliser : Le devis est prêt et doit partir au client.
Body JSON
{ "recipientEmail": "client@exemple.fr" }Réponse
{ "sent": true, "recipientEmail": "client@exemple.fr", "status": "Envoyé", "numQuote": "DEV-2026-07-4" }Exemple curl
curl -s -X POST -H "Authorization: Bearer $NF_KEY" \
-H "Content-Type: application/json" \
"/api/v1/quotes/4/send"/quotes/{id}/pdfquotes:readRetourne directement le fichier PDF (pas de lien intermédiaire, contrairement aux factures).
Quand l’utiliser : Archivage ou aperçu côté intégration.
Exemple curl
curl -s -H "Authorization: Bearer $NF_KEY" \
"/api/v1/quotes/4/pdf" -o devis-4.pdf/quotes/{id}/convert-to-invoicequotes:write + invoices:writeCrée une facture (`A_Envoyer`) à partir d’un devis `Accepté` et marque le devis `Converti`.
Quand l’utiliser : Le client a accepté (portail ou en direct) : passez à la facturation sans ressaisie.
Réponse
La facture créée (même forme que `GET /invoices/{id}`).Exemple curl
curl -s -X POST -H "Authorization: Bearer $NF_KEY" \
"/api/v1/quotes/4/convert-to-invoice"Configurez une URL HTTPS depuis API développeurs dans l’app. Flow POST le JSON d’événement et signe le corps pour que vous puissiez vérifier l’origine.
invoice.createdAprès POST /invoices réussi.
invoice.sentAprès POST /invoices/{id}/send.
invoice.paidQuand la facture passe au statut Payée (manuel ou Stripe).
invoice.cancelledAprès POST /invoices/{id}/cancel.
invoice.credit_note.createdAprès POST /invoices/{id}/credit-note (avoir total ou partiel).
quote.createdAprès POST /quotes réussi.
quote.sentAprès POST /quotes/{id}/send.
quote.acceptedQuand le client accepte le devis (app ou portail).
quote.convertedAprès POST /quotes/{id}/convert-to-invoice.
{
"id": "evt_…",
"type": "invoice.paid",
"createdAt": "2026-07-25T12:00:00",
"data": {
"invoiceId": 10,
"number": "FAC-2026-0001",
"status": "Payée",
"totalTtc": 2340.00
}
} Header : X-Flow-Signature: t=<unix_seconds>,v1=<hex>
Calcul : v1 = HMAC_SHA256(secret, t + "." + raw_body) où secret est celui affiché une seule fois à la création du webhook (whsec_…).
Exemple Node.js (vérification)
const crypto = require('crypto');
function verify(sigHeader, rawBody, secret, maxSkewSec = 300) {
const parts = Object.fromEntries(
sigHeader.split(',').map((p) => p.trim().split('='))
);
const t = parts.t;
const v1 = parts.v1;
if (!t || !v1) return false;
if (Math.abs(Date.now() / 1000 - Number(t)) > maxSkewSec) return false;
const expected = crypto
.createHmac('sha256', secret)
.update(t + '.' + rawBody)
.digest('hex');
return crypto.timingSafeEqual(Buffer.from(v1), Buffer.from(expected));
}2xx rapidement (< 10 s).Format commun :
{ "error": "message lisible", "code": "…" }| code | HTTP | Signification |
|---|---|---|
api_key_required | 401 | Pas de clé API (ou JWT seul) |
unauthorized | 401 | Clé invalide / révoquée |
plan_required | 403 | Plan Business requis |
insufficient_scope | 403 | Scope manquant sur la clé |
not_found | 404 | Ressource absente ou hors compte |
conflict | 409 | Ex. email client déjà présent |
bad_request | 400 | Payload / paramètres invalides |
rate_limited | 429 | > 60 req/min sur la clé |
Créez un compte Business, générez une clé dans l’app, puis rejouez le parcours client → facture → send → PDF.