API Clients
Créez, mettez à jour, listez et fusionnez les fiches clients. Inclut des champs B2B typés (SIRET, TVA intracom).
3 min de lecture
Sur cette page
Vue d'ensemble
L'API Clients permet de synchroniser des clients depuis vos propres systèmes vers Kataio, d'enrichir les fiches existantes et de fusionner les doublons. Requiert read:customers / write:customers.
Créer un client
POST https://app.kataio.com/api/v1/customers
Authorization: Bearer {accessToken}
Content-Type: application/json
Idempotency-Key: cust_marie-dupont-2026-04-22
{
"email": "marie.dupont@example.com",
"firstName": "Marie",
"lastName": "Dupont",
"phone": "+33 6 12 34 56 78",
"company": "Dupont & Fils SARL",
"siret": "12345678901234",
"vatIntracomNumber": "FR12345678901",
"tags": ["vip", "b2b"],
"metadata": { "checkout_mode": "registered", "source": "click-n-baches-site" }
}
Corps de la requête
email(requis) — unique par tenant.firstName,lastName,phone,company.siret— SIRET français, exactement 14 chiffres. B2B uniquement.vatIntracomNumber— TVA intracommunautaire (ex.FR12345678901), ≤20 caractères.tags— tableau de chaînes pour le filtrage.metadata— JSON libre pour les champs spécifiques à l'intégration (mode checkout, source, niveau de fidélité, etc.).
Idempotence
Mêmes sémantiques que POST /orders. Passez un header Idempotency-Key et les retries sur 24h rejoueront la réponse d'origine au lieu de créer un doublon.
Mettre à jour, lister, obtenir, fusionner
PATCH /api/v1/customers/:id— mise à jour partielle. Depuis v2.3 :siretetvatIntracomNumbersont acceptés ici (auparavant réservés à la création). Émetcustomer.updated.PUT /api/v1/customers/:id— Depuis v2.4 : alias dePATCHpour les intégrations qui utilisent PUT par défaut. Même handler, même sémantique partielle.GET /api/v1/customers?search=…&segmentId=…— liste paginée avec filtres.GET /api/v1/customers/:id— fiche complète. Depuis v2.4 : quand le carnet d'adresses explicite est vide,addresses[]est dérivé automatiquement desshippingAddressesuniques des commandes du client (dédup parline1|city|zip; chaque entrée dérivée porte_derived: true).GET /api/v1/customers/:id/orders?page=&limit=&status=&createdAtGte=&createdAtLte=— historique paginé. Même syntaxe de filtre queGET /ordersci-dessous.POST /api/v1/customers/merge— fusionne les doublons vers une fiche principale ({ primaryId, secondaryIds: [...] }). Les commandes et tags sont réaffectés ; les fiches secondaires sont désactivées.
Adresses (depuis v2.3, étendues en v2.4)
Les clients peuvent porter plusieurs adresses (sites de livraison, facturation alternative). Les trois endpoints émettent customer.updated.
POST /api/v1/customers/:id/addresses— ajoute une adresse. Champs (depuis v2.4) :- Requis :
line1(≤255),city(≤100),country(ISO 3166-1 alpha-2), et l'un dezip/postalCode(≤20, alias — le service normalise verszip; les réponses retournent les deux clés). - Optionnels :
name(≤120),company(≤200, raison sociale au niveau adresse pour B2B),type("shipping"|"billing"|"both"; omettre pour non spécifié),line2,state,phone,isDefault.
idgénéré.- Requis :
PATCH /api/v1/customers/:id/addresses/:addressId— mise à jour partielle ; même forme.DELETE /api/v1/customers/:id/addresses/:addressId— suppression.
Syntaxe de filtre commandes (depuis v2.4)
GET /api/v1/orders et GET /api/v1/customers/:id/orders acceptent l'ancienne syntaxe plate ou les alternatives compactes :
- Statut multi-valeur :
?status=PENDING,PROCESSING,SHIPPED— séparé par virgules. - Plage de dates : notation crochets
?createdAt[gte]=…&createdAt[lte]=…, ou plate?createdAtGte=…&createdAtLte=…. - Tri : notation deux-points
?sort=createdAt:desc, ou séparé?sort=createdAt&order=desc.
Événements webhook
Catalogue complet via GET /api/v1/developer/webhooks/events (depuis v2.4).
customer.created— émis surPOST /customerset sur l'auto-upsert depuisPOST /orders(quandcustomerEmailest inconnu).customer.updated— émis surPATCH/PUT /customers/:idet sur toute mutation d'adresse (ajout / modification / suppression).customer.merged— émis surPOST /customers/merge.customer.erased— Depuis v2.11 : émis surPOST /customers/:id/erase(RGPD). Charge utile{ id, erasedAt, orders }uniquement — aucune donnée personnelle. EnsuiteGET /customers/:idrenvoieerasedAtet un e-mailerased-<id>@anonymised.invalid;PATCHrépond 409.order.status_changed— émis à chaque transition de statut (la charge utile inclutpreviousStatusetstatus).order.shipped/order.delivered/order.cancelled/order.returned— Depuis v2.4 : compagnons granulaires deorder.status_changed. Émis simultanément quand la transition correspond.order.shipment_created— Depuis v2.12 : un événement par colis (voir Expéditions). Émis aussi pour les colis partiels, quandorder.shippedne l'est pas.order.updated— Depuis v2.12 : les lignes ou montants d'une commande ont changé avant préparation (voir Modifier les lignes). Charge utile :id,externalId,status,totalAmount,currency,items[{ sku, quantity, unitPrice }].
+tag (ex. marie+ikadran@société.fr).