API Commandes
Récupérez et gérez les commandes importées de tous les canaux de vente avec mises à jour de statut et filtrage.
7 min de lecture
Sur cette page
Vue d'ensemble
Les commandes arrivent dans Kataio depuis tous les canaux de vente connectés. L'API Commandes fournit un accès en lecture aux données de commandes et permet de mettre à jour les statuts. Les changements de statut sont automatiquement synchronisés vers le canal d'origine.
Lister les commandes
GET https://app.kataio.com/api/v1/orders?page=1&limit=20&status=PROCESSING&channelId=ch_01...
Authorization: Bearer {accessToken}
Paramètres de requête
page/limit— Pagination (par défaut : page 1, limit 20)status— Filtrer :PENDING,PROCESSING,PARTIALLY_SHIPPED,SHIPPED,DELIVERED,CANCELLED,RETURNEDchannelId— Filtrer par canal d'originecustomerId(depuis v2.3) — Filtrer par client canonique (UUID).customerEmail(depuis v2.3) — Filtrer par email (insensible à la casse). Utile pour les commandes invitées sans fiche client.createdAtGte/createdAtLte(depuis v2.3) — Bornes inférieure / supérieure ISO 8601 surcreatedAt. Alias cohérent dedateFrom/dateTo.search— Recherche par numéro de commande ou nom du clientdateFrom/dateTo— Filtrer par plage de dates (ISO 8601). Équivalent àcreatedAtGte/createdAtLte; les deux sont acceptés.sortBy— Trier par :createdAt,total,orderNumbersortOrder—ascoudesc
Réponse (200)
{
"data": [
{
"id": "ord_01...",
"orderNumber": "ORD-2026-001542",
"status": "PROCESSING",
"channelId": "ch_01...",
"channelName": "Boutique Shopify FR",
"channelType": "SHOPIFY",
"customer": {
"name": "Marie Dupont",
"email": "marie.dupont@example.com",
"phone": "+33 6 12 34 56 78"
},
"shippingAddress": {
"line1": "15 Rue de la Paix",
"line2": "Apt 3B",
"city": "Paris",
"postalCode": "75002",
"country": "FR"
},
"items": [
{
"productId": "prod_01...",
"name": "Chemise Oxford Bleue - Taille M",
"sku": "CHM-OXF-BLU-M",
"quantity": 2,
"unitPrice": 49.90,
"lineTotal": 99.80
}
],
"subtotal": 99.80,
"shippingCost": 5.90,
"tax": 21.14,
"total": 126.84,
"currency": "EUR",
"createdAt": "2026-03-14T16:23:00.000Z",
"updatedAt": "2026-03-15T09:00:00.000Z"
}
],
"meta": {
"page": 1,
"limit": 20,
"total": 156,
"totalPages": 8
}
}
Obtenir une commande
GET https://app.kataio.com/api/v1/orders/ord_01...
Authorization: Bearer {accessToken}
Retourne l'objet commande complet tel que montré ci-dessus, incluant tous les articles, les informations client, l'adresse de livraison et l'historique complet des statuts.
Créer une commande
Envoyez une commande dans Kataio depuis votre propre checkout, marketplace ou back-office. Requiert le scope write:orders.
POST https://app.kataio.com/api/v1/orders
Authorization: Bearer {accessToken}
Content-Type: application/json
Idempotency-Key: ord_2026-04-22_CNB-AB12CD
{
"customerName": "Marie Dupont",
"customerEmail": "marie.dupont@example.com",
"externalReference": "CNB-AB12CD",
"initialStatus": "PROCESSING",
"currency": "EUR",
"items": [
{ "sku": "CHM-OXF-BLU-M", "quantity": 2, "unitPrice": 49.90 }
],
"shippingAddress": { "line1": "15 Rue de la Paix", "city": "Paris", "zip": "75002", "country": "FR" },
"billingAddress": { "line1": "15 Rue de la Paix", "city": "Paris", "zip": "75002", "country": "FR" },
"paymentMetadata": { "stripePaymentIntentId": "pi_3OaBcDxxx", "stripeChargeId": "ch_3OaBcDxxx" },
"notes": "Livraison urgente — client VIP"
}
Corps de la requête
customerName(requis) — nom affiché.customerId(depuis v2.3) — UUID du client canonique. Prioritaire surcustomerEmailsi les deux sont fournis.customerEmail— crée ou met à jour automatiquement un client et le lie à la commande. Depuis v2.3 : l'upsert émetcustomer.created.items[].sku,items[].quantity,items[].unitPrice(requis) — les lignes sont résolues par SKU (les SKU de variantes sont acceptés).items[].name(depuis v2.3, optionnel) — surcharge le nom affiché de la ligne (ex. nom localisé depuis votre boutique). Persisté sur l'item et renvoyé à chaque lecture.currency— ISO 4217,EURpar défaut.externalReference— votre propre numéro de commande (ex.CNB-AB12CD). Unique par tenant — les doublons retournent409. Renvoyé sur chaque lecture.initialStatus— enregistre la commande directement enPROCESSING,SHIPPED, etc. Par défautPENDING. UtilisezPROCESSINGlorsque le paiement a déjà été encaissé côté checkout (Stripe, etc.) pour éviter un aller-retour.shippingAddress/billingAddress— objets JSON libres ; la facturation reprend la livraison si omise.paymentMetadata— JSON libre pour les identifiants PSP (ex.stripePaymentIntentId). Conservé et renvoyé tel quel.notes— notes internes.
Idempotence
Passez un header Idempotency-Key (chaîne libre ≤255 caractères) pour rendre POST /orders sûr à rejouer. La première requête est traitée normalement et la réponse est mise en cache pendant 24 heures. Les requêtes suivantes avec la même clé rejouent la réponse à l'identique (statut 201 + header Idempotent-Replay: true). Même clé + corps différent → 409 Conflict ; générez une nouvelle clé si vous vouliez créer une autre commande.
ord_{votreOrderId}) et réessayez en cas d'échec réseau avec la même clé. La seconde tentative rejouera la réponse d'origine sans créer de doublon — même si la réponse de la première requête s'est perdue en route.
Réponse (201)
{
"data": {
"id": "894c736a-7471-4848-b094-24bddf471730",
"externalId": "CNB-AB12CD",
"externalReference": "CNB-AB12CD",
"status": "PROCESSING",
"totalAmount": "99.80",
"currency": "EUR",
"customerName": "Marie Dupont",
"customerEmail": "marie.dupont@example.com",
"shippingAddress": { "line1": "15 Rue de la Paix", "city": "Paris", "zip": "75002", "country": "FR" },
"billingAddress": { "line1": "15 Rue de la Paix", "city": "Paris", "zip": "75002", "country": "FR" },
"paymentMetadata": { "stripePaymentIntentId": "pi_3OaBcDxxx", "stripeChargeId": "ch_3OaBcDxxx" },
"itemCount": 1,
"createdAt": "2026-04-22T10:15:03.000Z"
}
}
Erreurs
400— erreur de validation (items manquants, statut invalide, etc.).409—externalReferenceen doublon ou conflitIdempotency-Key. Le corps de la réponse nomme l'id de la commande existante.
Mettre à jour le statut d'une commande
Faites progresser une commande dans son cycle de vie. La mise à jour du statut est synchronisée vers le canal de vente d'origine.
PATCH https://app.kataio.com/api/v1/orders/ord_01.../status
Authorization: Bearer {accessToken}
Content-Type: application/json
{
"status": "SHIPPED",
"trackingNumber": "COLISSIMO-FR-9876543210",
"trackingUrl": "https://www.laposte.fr/outils/suivre-vos-envois?code=9876543210",
"note": "Expédié via Colissimo le 15/03/2026"
}
Transitions de statut
PENDING→PROCESSINGouCANCELLEDPROCESSING→PARTIALLY_SHIPPED(via les expéditions),SHIPPEDouCANCELLEDPARTIALLY_SHIPPED→SHIPPED(dernier colis) ouCANCELLEDSHIPPED→DELIVEREDouRETURNEDDELIVERED→RETURNEDCANCELLEDetRETURNEDsont terminaux.
Modifier les lignes d'une commande
Depuis v2.12. Remplace les lignes d'une commande qui n'a pas commencé sa préparation : autorisé tant que le statut est PENDING ou PROCESSING sans colis ni retour (409 sinon). C'est un remplacement complet — les lignes avec un id sont mises à jour, celles sans id ajoutées, les lignes existantes absentes supprimées — un seul appel est donc idempotent pour votre intégration.
PUT /api/v1/orders/{id}/items
{
"items": [
{ "id": "c3d4e5f6-7890-abcd-ef12-345678901234", "sku": "BACFERM-640", "quantity": 2, "unitPrice": 129.9 },
{ "sku": "OEILLET-INOX", "quantity": 22, "unitPrice": 0.6 }
],
"shippingAmount": 5.9,
"discountAmount": 0
}
items[]— obligatoire, même format que Créer une commande (sku,quantity,unitPrice, et en optionname,description,metadata) plus unidoptionnel. Un id inconnu répond400.shippingAmount,discountAmount,taxAmount— optionnels ; par défaut les valeurs actuelles de la commande. SanstaxAmount, la TVA est recalculée depuis letaxRatede la commande (null si elle n'en a pas).- Sous-total et total sont recalculés, les réservations de stock suivent le delta par ligne, le total dépensé du client bouge de la différence.
- Retourne
200avec la commande complète (même format queGET /orders/{id}). Émetorder.updated.
Expéditions (livraison partielle)
Depuis v2.12. Une commande peut partir en plusieurs colis. Chaque colis est une expédition qui liste les lignes et quantités qu'il contient. Tant qu'il reste des quantités non expédiées, la commande est PARTIALLY_SHIPPED ; le colis qui expédie la dernière unité la passe en SHIPPED. Marquer une commande SHIPPED via PATCH /orders/{id}/status fonctionne toujours et crée une expédition pour tout ce qui reste.
POST /api/v1/orders/{id}/shipments
{
"carrier": "Colissimo",
"trackingNumber": "6A12345678901",
"trackingUrl": "https://www.laposte.fr/outils/suivre-vos-envois?code=6A12345678901",
"shippedAt": "2026-09-20T09:30:00.000Z",
"notes": "Fragile",
"items": [
{ "orderItemId": "c3d4e5f6-7890-abcd-ef12-345678901234", "quantity": 2 }
]
}
items— obligatoire, au moins une ligne.quantityne peut pas dépasser la quantité restante de la ligne (400 Cannot ship 3 of SKU — only 2 remaining).carrier,trackingNumber,trackingUrl,shippedAt(par défaut maintenant),notes— optionnels. Transporteur et suivi sont recopiés sur la commande (dernier colis).- Retourne
201avec l'expédition ;409sur une commande annulée, retournée ou livrée.
GET /api/v1/orders/{id}/shipments
DELETE /api/v1/orders/{id}/shipments/{shipmentId}
Supprimer un colis recalcule le statut (PARTIALLY_SHIPPED s'il reste d'autres colis, PROCESSING sinon). GET /orders/{id} renvoie shipments[] et une shippedQuantity sur chaque ligne.
Webhooks : chaque colis émet order.shipment_created (charge utile = l'expédition plus orderId, externalId, orderStatus) ; order.status_changed est émis à chaque transition et order.shipped une seule fois, quand la commande devient SHIPPED.
422 Unprocessable Entity. L'API applique un flux de statut strict pour maintenir l'intégrité des données.