Facturino / Documentation / Clients

Clients

L'objet customer représente une entité destinataire de vos factures — particulier (B2C) ou personne morale (B2B). Les clients B2B sont validés et pré-remplis à partir des données officielles INSEE (SIRET, raison sociale, code NAF, adresse du siège) et du service VIES (UE) pour les numéros de TVA intra-communautaires.

Endpoints

MéthodeCheminDescription
POST/v1/customersCréer un client
GET/v1/customersLister les clients
GET/v1/customers/:idRécupérer un client
PATCH/v1/customers/:idModifier un client
DELETE/v1/customers/:idSupprimer (soft-delete)
POST/v1/customers/lookupRecherche par SIRET (pré-remplissage INSEE)
POST/v1/customers/importImport CSV en lot
GET/v1/customers/exportExport CSV

Créer un client

$ curl -X POST https://facturino.com/api/v1/customers \
  -H "Authorization: Bearer fac_test_..." \
  -H "Idempotency-Key: customer-create-acme-2026" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Durand & Associés SARL",
    "siret": "73282932000074",
    "vatNumber": "FR44732829320",
    "address": {
      "line1": "15 rue de la Paix",
      "city": "Paris",
      "postalCode": "75002",
      "country": "FR"
    },
    "contacts": [
      { "firstName": "Marie", "lastName": "Dupont", "email": "compta@durand.fr" }
    ],
    "paymentTerms": 30,
    "defaultPaymentMethod": "transfer"
  }'

Réponse :

{
  "id": "cus_8f2k4m9n",
  "object": "customer",
  "livemode": false,
  "name": "Durand & Associés SARL",
  "siret": "73282932000074",
  "vatNumber": "FR44732829320",
  "siretVerified": false,
  "vatVerified": false,
  "address": {
    "line1": "15 rue de la Paix",
    "city": "Paris",
    "postalCode": "75002",
    "country": "FR"
  },
  "contacts": [
    {
      "firstName": "Marie",
      "lastName": "Dupont",
      "email": "compta@durand.fr"
    }
  ],
  "paymentTerms": 30,
  "defaultPaymentMethod": "transfer",
  "created": "2026-04-22T13:48:10.000Z",
  "updated": "2026-04-22T13:48:11.000Z"
}

Champs principaux

ChampTypeRequisNotes
namestringouiRaison sociale ou nom complet (max 200 caractères)
siretstringB2B FR14 chiffres, validation Luhn appliquée
vatNumberstringB2B UEFormat FR12345678901, validé via VIES en async
addressobjectouiline1, line2?, city, postalCode, country (ISO 3166)
contactsarraynonListe de contacts (firstName, lastName, email, phone) — max 10.
paymentTermsintegernonDélai de paiement par défaut en jours (0–365). Hérité par les factures émises au client.
defaultPaymentMethodenumnontransfer, card, check, cash, direct_debit, sepa, paypal.
tagsstring[]nonÉtiquettes libres (max 20 tags, 50 caractères chacun) pour filtrage / segmentation.
typeenumnoncompany (défaut) ou individual.
metadataobjectnonClés-valeurs libres pour vos propres références.

Validation TVA et SIRET

À la création ou mise à jour, Facturino lance en arrière-plan :

  • SIRET : validation Luhn synchrone + enrichissement à partir des données officielles INSEE (raison sociale officielle, code NAF, adresse du siège). Le booléen siretVerified passe à true lorsque le SIRET est trouvé dans le répertoire SIRENE, sinon reste false.
  • Numéro TVA : validation VIES asynchrone (15 s timeout). Le champ booléen vatVerified passe à true après confirmation, ou reste false en cas d'échec / d'indisponibilité du service.

Tant que la validation n'est pas confirmée, vatVerified reste false. Ces validations ne bloquent jamais la création — elles permettent de signaler les anomalies sans interrompre votre flux.

Pourquoi c'est important. Pour les factures intracommunautaires (VATEX-EU-IC), un numéro TVA non vérifié au VIES peut entraîner un refus URSSAF ou DGFiP. Vérifiez vatVerified === true avant de finaliser une facture à TVA exonérée.

Recherche et enrichissement

POST /v1/customers/lookup renvoie les informations officielles INSEE associées à un SIRET sans créer de client — utile pour pré-remplir un formulaire en temps réel.

$ curl -X POST "https://facturino.com/api/v1/customers/lookup" \
  -H "Authorization: Bearer fac_test_..." \
  -H "Content-Type: application/json" \
  -d '{"siret": "73282932000074"}'

# Réponse — informations officielles INSEE pré-remplies depuis le SIRET
{
  "object": "sirene_lookup",
  "found": true,
  "data": {
    "name": "DURAND & ASSOCIES",
    "siret": "73282932000074",
    "siren": "732829320",
    "vatNumber": "FR44732829320",
    "legalForm": { "code": "5499", "sigle": "SARL", "label": "Société à responsabilité limitée" },
    "naf": { "code": "62.02A", "label": "Conseil en systèmes et logiciels informatiques" },
    "address": { /* ... */ },
    "active": true
  }
}

Vous pouvez aussi rechercher par query (recherche floue sur le nom) ou par vatNumber. Le résultat inclut une suggestion d'address et de legalForm à valider par l'utilisateur avant création.

Import CSV

Pour migrer un catalogue existant, utilisez l'import CSV :

$ curl -X POST https://facturino.com/api/v1/customers/import \
  -H "Authorization: Bearer fac_test_..." \
  -H "Content-Type: application/json" \
  -d '{"csv": "name,email\nAcme SAS,contact@acme.fr"}'

# Réponse 200 OK — traitement synchrone, compte des lignes importées
{
  "object": "import_result",
  "imported": 2,
  "errors": [],
  "total_rows": 2
}

Format attendu (UTF-8, séparateur virgule, header obligatoire). Seule la colonne name est requise :

name,siret,vat_number,address_line1,address_city,address_postal_code,address_country,email,phone
"Durand & Associés","73282932000074","FR44732829320","15 rue de la Paix","Paris","75002","FR","compta@durand.fr","+33145678910"
"Acme Corp","83012345600028","FR45830123456","2 avenue des Champs","Lyon","69003","FR","invoice@acme.com",

Limites : 10 000 lignes par fichier, 2 imports par heure. Les erreurs ligne-par-ligne sont retournées directement dans la réponse (tableau errors avec le numéro de ligne et le détail des champs invalides). Si aucune ligne n'est importée alors que des erreurs sont présentes, la réponse est un 422.

Contacts

Chaque client peut avoir jusqu'à 10 contacts, chacun avec un role facultatif parmi billing, technical et main :

  • role = "billing" — reçoit les factures et les relances par défaut. À défaut de contact billing, l'envoi retombe sur l'email principal du client (email).
  • role = "technical" — contact technique (intégration, rejets PA, anomalies).
  • role = "main" — contact général de l'entité.

Mettre à jour les contacts via PATCH :

curl -X PATCH https://facturino.com/api/v1/customers/cus_8f2k4m9n \
  -H "Authorization: Bearer fac_test_..." \
  -H "Content-Type: application/json" \
  -d '{
    "contacts": [
      { "firstName": "Marie", "lastName": "Dupont", "email": "marie@durand.fr", "role": "billing" },
      { "firstName": "Paul", "lastName": "Martin", "email": "paul@durand.fr", "role": "technical" }
    ]
  }'

Clients B2C

Pour des particuliers, le champ siret est facultatif. Précisez type: "individual" :

{
  "type": "individual",
  "name": "Jean Dupont",
  "address": { "line1": "1 rue Example", "city": "Paris", "postalCode": "75001", "country": "FR" },
  "contacts": [{ "email": "jean@example.com" }]
}

Les factures B2C sont émises sans dépôt PA (la facturation électronique obligatoire 2026 ne couvre que le B2B intracommunautaire). Elles restent générées en Factur-X mais ne déclenchent pas de transmission DGFiP.

Soft-delete

DELETE /v1/customers/:id marque le client comme supprimé (deleted: true) sans purger les données — les factures historiques restent inchangées. Les clients supprimés sont exclus par défaut des listes ; ajoutez ?include_deleted=true pour les inclure.

Pour une suppression définitive (RGPD, droit à l'oubli), utilisez POST /v1/account/export (portabilité art. 20) puis demandez la suppression manuelle au support — l'opération est irréversible et peut nécessiter de purger des factures liées.

Étapes suivantes

  • Factures — utiliser le client comme destinataire
  • Produits — catalogue réutilisable dans les lignes
  • Webhooks — événements customer.*