Produits
L'objet product représente une prestation ou un bien réutilisable dans votre catalogue. Les produits ne sont pas
obligatoires — vous pouvez créer des factures avec des lignes ad-hoc — mais ils accélèrent la saisie et garantissent la cohérence
des libellés, prix et taux de TVA entre vos documents.
Endpoints
| Méthode | Chemin | Description |
|---|---|---|
| POST | /v1/products | Créer un produit |
| GET | /v1/products | Lister les produits |
| GET | /v1/products/:id | Récupérer un produit |
| PATCH | /v1/products/:id | Modifier un produit |
| DELETE | /v1/products/:id | Supprimer (soft-delete) |
Créer un produit
$ curl -X POST https://facturino.com/api/v1/products \
-H "Authorization: Bearer fac_test_..." \
-H "Idempotency-Key: product-sku-734-create" \
-H "Content-Type: application/json" \
-d '{
"name": "Audit cybersécurité — Forfait",
"reference": "AUDIT-CYBER-1",
"description": "Audit complet : analyse, recommandations, restitution.",
"unitPrice": 350000,
"vatRate": 2000,
"vatCode": "S",
"unit": "flat_rate",
"category": "consulting",
"tags": ["audit", "cyber"]
}' Champs
| Champ | Type | Requis | Description |
|---|---|---|---|
name | string | oui | Nom affiché (max 200 caractères). |
reference | string | non | Référence interne / SKU (max 50 caractères) — utile pour rapprocher avec un PIM/ERP. |
description | string | non | Description longue pré-remplie sur les lignes (max 500 caractères). |
unitPrice | integer | oui | Prix unitaire HT en centimes (15000 = 150,00 €). |
vatRate | integer | oui | Taux TVA en centièmes de pourcent (2000 = 20 %). |
vatCode | enum | oui | S, Z, E, AE, G, IC, K, O, VATEX-FR-FRANCHISE (cf. codes TVA EN 16931). |
unit | enum | oui | unit (pièce), hour, day, month, flat_rate (forfait), kg, m, m2, m3, l. |
category | string | non | Catégorie libre (max 100 caractères) pour le regroupement et les rapports. |
tags | string[] | non | Étiquettes libres (max 20 tags, 50 caractères chacun) — exposées dans les filtres de liste. |
Le champ active n'est pas modifiable à la création — un produit est créé actif par défaut. Pour l'archiver, utilisez DELETE /v1/products/:id (soft-delete : il reste référençable par les anciennes factures mais disparaît des sélecteurs UI).
Utiliser un produit dans une ligne
Fournissez les champs de la ligne (description, quantity, unit,
unitPrice, vatRate, vatCode) et, si vous le souhaitez, le champ
product pour lier la ligne au produit du catalogue. Il n'y a pas de copie
automatique : pré-remplissez la ligne depuis GET /v1/products/{id} côté client.
# Ligne de facture avec référence produit optionnelle (champ "product")
# Les valeurs de la ligne sont fournies explicitement ; "product" est un simple
# lien (dépliable via ?expand=items.product sur la réponse), pas une copie auto.
{
"customerId": "cus_...",
"lines": [
{
"description": "Audit cybersécurité",
"quantity": "2",
"unit": "flat_rate",
"unitPrice": 300000,
"vatRate": 2000,
"vatCode": "S",
"product": "prod_a1b2c3"
}
]
}
# "product" est facultatif : une ligne peut être entièrement libre
{
"customerId": "cus_...",
"lines": [
{
"description": "Prestation sur mesure",
"quantity": "1",
"unit": "flat_rate",
"unitPrice": 150000,
"vatRate": 2000,
"vatCode": "S"
}
]
} Pourquoi fournir les valeurs ? Une facture finalisée est immuable (numéro opposable, hash chain). Chaque ligne embarque ses propres valeurs figées à la date d'émission : modifier le prix d'un produit dans le catalogue ne change donc pas les factures historiques. Le champ product reste un lien (dépliable via ?expand=items.product sur la réponse), pas une référence vivante.
Recherche
Filtres supportés sur GET /v1/products :
| Paramètre | Description |
|---|---|
q | Recherche par préfixe du name (insensible à la casse) |
category | Filtrer par catégorie (correspondance exacte) |
active | true, false, ou omis pour tout |
limit | Nombre d'éléments par page (défaut 25, max 100) |
date_from, date_to | Filtrer par date de création (ISO 8601) |
sort | Ordre de tri (hérité de la pagination) |
Création en lot
Pour importer un catalogue complet, utilisez POST /v1/products/import : envoyez le CSV en JSON dans un champ
csv (corps application/json). L'export miroir GET /v1/products/export renvoie l'ensemble
de vos produits au format CSV avec le même en-tête de colonnes.
Vous pouvez aussi scripter via boucle POST /v1/products avec un Idempotency-Key stable par référence
pour permettre les retries :
for product in catalog:
key = f"product-import-{product.reference}"
client.products.create(
name=product.name,
reference=product.reference,
unitPrice=product.price_cents,
vatRate=product.vat_centi,
vatCode="S",
idempotency_key=key,
) Respectez la limite de débit de votre plan — espacez les appels si nécessaire ou utilisez l'auto-pagination intégrée aux SDKs.
Suppression
DELETE /v1/products/:id est un soft-delete (deleted: true). Les factures historiques référençant le produit
ne sont pas affectées (snapshot). Le produit n'apparaît plus dans le catalogue, mais reste consultable via
GET /v1/products?include_deleted=true pour le debug.
Étapes suivantes
- Factures — utiliser le produit dans une ligne
- Webhooks — événements
product.* - Référence interactive