Créer / mettre à jour des articles
POST /articles
Crée ou met à jour un ou plusieurs articles. Fonctionne en mode upsert : si un article avec la même combinaison activityCode + articleReference existe, il est mis à jour.
Selon votre mode de gestion VL
Section intitulée « Selon votre mode de gestion VL »Les variantes logistiques sont calculées automatiquement à partir des dimensions que vous envoyez (netWeightPerUVC, quantityPerPCB, etc.).
Ne pas envoyer le champ logisticalVariants — l’API retourne l’erreur 200 si ce champ est présent.
Vous gérez les variantes logistiques explicitement via le champ logisticalVariants. Les poids et dimensions de chaque conditionnement sont portés par les VL, pas par les champs racine.
Voir la section Variantes logistiques en bas de page.
Paramètres de requête
Section intitulée « Paramètres de requête »| Paramètre | Type | Défaut | Description |
|---|---|---|---|
validationOnly | bool | false | Si true, valide les données sans les persister |
Corps de la requête
Section intitulée « Corps de la requête »Un tableau JSON d’objets Article.
Champs de l’article
Section intitulée « Champs de l’article »Identification (obligatoires)
Section intitulée « Identification (obligatoires) »| Champ | Type | Max | Description |
|---|---|---|---|
activityCode | string | 3 | Code de l’activité. Doit correspondre à un de vos client_context. |
activityName | string | 30 | Libellé de l’activité |
articleReference | string | 16 | Référence unique de l’article. Format : ^[A-Z0-9_.#/\-]+$ |
longArticleDescription | string | 60 | Désignation longue de l’article |
shortArticleDescription | string | 30 | Désignation courte de l’article |
netWeightPerUVC | int | — | Poids net de l’UVC en grammes. Défaut : 0 |
Type et classification
Section intitulée « Type et classification »| Champ | Type | Max | Requis | Description |
|---|---|---|---|---|
articleType | int | — | Non | 0 = stockable, 1 = consommable, 2 = service. Défaut : 0 |
articleAnalysisCode | string | 1 | Non | E = normal, C = comptable, D = échantillons. Défaut : E |
articleCategory | string | 25 | Non | Catégorie de l’article |
articleRotationClass | string | 25 | Non | Classe de rotation (A, B, C…) |
articleFamily | string | 10 | Non | Famille de l’article |
articleSubFamily | string | 20 | Non | Sous-famille |
articleBrand | string | 20 | Non | Marque |
articleSize | string | 10 | Non | Taille |
articleColor | string | 30 | Non | Couleur |
articleTypology | string | 20 | Non | Typologie |
modelReference | string | 100 | Non | Référence du modèle |
modelDescription | string | 100 | Non | Description du modèle |
Dimensions UVC
Section intitulée « Dimensions UVC »| Champ | Type | Requis | Description |
|---|---|---|---|
netWeightPerUVC | int | Oui | Poids net en grammes |
grossWeightPerUVC | int | Non | Poids brut en grammes. Défaut : 0 |
lengthPerUVC | int | Non | Longueur en mm. Défaut : 0 |
widthPerUVC | int | Non | Largeur en mm. Défaut : 0 |
heightPerUVC | int | Non | Hauteur en mm. Défaut : 0 |
Dimensions PCB (Par Combien / carton)
Section intitulée « Dimensions PCB (Par Combien / carton) »| Champ | Type | Requis | Description |
|---|---|---|---|
quantityPerPCB | int | Non | Nombre d’UVC par carton. Défaut : 0 |
grossWeightPerPCB | int | Non | Poids brut du carton en grammes. Défaut : 0 |
lengthPerPCB | int | Non | Longueur en mm. Défaut : 0 |
widthPerPCB | int | Non | Largeur en mm. Défaut : 0 |
heightPerPCB | int | Non | Hauteur en mm. Défaut : 0 |
Dimensions SPCB (sous-palette)
Section intitulée « Dimensions SPCB (sous-palette) »| Champ | Type | Requis | Description |
|---|---|---|---|
quantityPerSPCB | int | Non | Nombre d’UVC par sous-palette. Défaut : 0 |
grossWeightPerSPCB | int | Non | Poids brut. Défaut : 0 |
lengthPerSPCB | int | Non | Longueur en mm. Défaut : 0 |
widthPerSPCB | int | Non | Largeur en mm. Défaut : 0 |
heightPerSPCB | int | Non | Hauteur en mm. Défaut : 0 |
Dimensions SUP (palette)
Section intitulée « Dimensions SUP (palette) »| Champ | Type | Requis | Description |
|---|---|---|---|
uvcQuantityPerCartonOrPalette | int | Non | Nombre d’UVC par palette. Défaut : 9999 si non renseigné |
weightPerCartonOrPalette | int | Non | Poids brut. Défaut : 0 |
lengthPerCartonOrPalette | int | Non | Longueur en mm. Défaut : 0 |
widthPerCartonOrPalette | int | Non | Largeur en mm. Défaut : 0 |
heightPerCartonOrPalette | int | Non | Hauteur en mm. Défaut : 0 |
Logistique et stockage
Section intitulée « Logistique et stockage »| Champ | Type | Max | Requis | Description |
|---|---|---|---|---|
receptionMethod | string | 25 | Non | Taille emplacement dans le WMS |
storageMethod | string | 25 | Non | Famille de péremption. Défaut : "001" |
preferredStorageZone | string | 25 | Non | Zone préférentielle de stockage |
preferredStorageAisle | string | 25 | Non | Famille de stockage. Défaut selon config |
storageClass | string | 25 | Non | Classe de stockage |
preparationMethod | string | 25 | Non | Famille de préparation. Défaut selon config |
articlePackaging | string | 30 | Non | Emballage article |
customsCode | string | 15 | Non | Code douane |
countryOfOriginCode | string | 15 | Non | Code pays d’origine (ISO 3166-1 alpha-2) |
minimumPriorityDateDayNumber | int | — | Non | Nombre de jours minimum de la date d’ordonnancement pour la réception. Plage autorisée : 0–999. Verrouillé après la première réception. |
Fournisseur
Section intitulée « Fournisseur »| Champ | Type | Max | Requis | Description |
|---|---|---|---|---|
supplierCode | string | 14 | Non | Code fournisseur principal |
supplierArticleReference | string | 50 | Non | Référence de l’article chez le fournisseur |
supplierArticleDescription | string | 100 | Non | Désignation fournisseur |
supplierArticleReference2 à 5 | string | 20 | Non | Références fournisseurs additionnelles |
brandCode | string | 8 | Non | Code marque |
Référence client
Section intitulée « Référence client »| Champ | Type | Max | Requis | Description |
|---|---|---|---|---|
dOReferenceCode | string | 30 | Non | Référence de l’article chez le client donneur d’ordre |
Gestion de péremption
Section intitulée « Gestion de péremption »| Champ | Type | Requis | Description |
|---|---|---|---|
saleExpirationDate | bool | Non | L’article a une date limite de vente |
receptionDeadlineInDays | int | Non | Durée de vie minimale à la réception (en jours) |
shippingDeadlineInDays | int | Non | Durée de vie minimale à l’expédition (en jours) |
Gestion spéciale
Section intitulée « Gestion spéciale »| Champ | Type | Requis | Description |
|---|---|---|---|
serializedArticle | bool | Non | Gestion par numéro de série |
lotTrackedArticle | bool | Non | Gestion par numéro de lot |
miniArticlesManaged | bool | Non | Gestion de type mini-articles |
quantityDeclarationManaged | bool | Non | Déclaration de quantité à la préparation |
fragileArticle | bool | Non | Article fragile (préparation spécifique) |
nomenclatureManaged | bool | Non | Gestion de la nomenclature |
| Champ | Type | Requis | Description |
|---|---|---|---|
articlePrice1 à articlePrice4 | int | Non | Prix de l’article (en centimes) |
| Champ | Type | Écriture | Description |
|---|---|---|---|
topHazardousMaterial | bool | Non | Article dangereux (géré par le module dangereux) |
topAlcoholArticle | bool | Oui | Article alcool. Non défini automatiquement : doit être positionné explicitement même si l’objet alcool est renseigné. |
topConsignedArticle | bool | Oui | Article consigné |
disableProduit | bool | Oui | Article désactivé |
Champs personnalisés
Section intitulée « Champs personnalisés »| Champ | Type | Max | Description |
|---|---|---|---|
customField1, customField2 | DateTime | — | Dates personnalisées |
customField3 à customField11 | string | 256 | Texte libre |
customField12 à customField16 | int | — | Entiers personnalisés |
customField17, customField18 | DateTime | — | Dates personnalisées |
Codes-barres (barcodes)
Section intitulée « Codes-barres (barcodes) »Tableau d’objets Barcode :
| Champ | Type | Max | Requis | Description |
|---|---|---|---|---|
code | string | 17 | Oui | Code-barre (EAN, UPC, etc.) |
isPrimary | bool | — | Non | Code-barre principal |
barcodeUnit | string | 17 | Non | Unité logistique. Défaut : "UVC". Valeurs acceptées : BID, BOI, BOU, CAR, CUV, DOS, ETU, FLA, FUT, KG, LIT, LTR, MET, PAC, PCB, ROU, SAC, SCH, SPC, SUP, UVC |
barcodeQuantity | int | — | Non | Quantité représentée par le code-barre. Défaut : 1 |
logisticalVariantCode | string | 3 | Non | Code VL associé (10, 15, 20, 30) |
disabled | bool | — | Non | Code-barre désactivé |
Données alcool (alcool)
Section intitulée « Données alcool (alcool) »Objet optionnel :
| Champ | Type | Max | Requis | Description |
|---|---|---|---|---|
articleReference | string | 16 | Oui | Doit correspondre à l’article parent |
itemType | string | 3 | Oui | "010" = acquit, "020" = CRD |
regieCodes | string | 2 | Non | Code régie |
degree | double | — | Non | Degré d’alcool |
capacity | double | — | Non | Contenance en ml |
categoryOfTaxation | string | 50 | Non | Libellé fiscal |
customsBrandName | string | 40 | Non | Marque douanière |
customsClassification | string | 9 | Non | Rubrique douanière |
Variantes logistiques (logisticalVariants) — mode managedVl uniquement
Section intitulée « Variantes logistiques (logisticalVariants) — mode managedVl uniquement »Tableau d’objets LogisticalVariant :
| Champ | Type | Requis | Description |
|---|---|---|---|
logisticalVariantCode | string | Oui | Code de la VL : 10, 15, 20, 30 |
lvTypeCode | string | Oui | Type de la VL. Défaut auto : UVC, SPC, PCB, SUP |
baseLv | bool | Non | true uniquement pour la VL 10 |
packagingLv | bool | Non | true uniquement pour la VL 30 |
managementLv | bool | Non | VL de gestion |
subpackagingLvCode | string | Conditionnel | Code de la VL parent. Obligatoire sauf pour VL 10 avec baseLv=true |
quantityInSubpackagingLv | int | Conditionnel | Quantité dans la VL parent. Obligatoire sauf pour VL 10 avec baseLv=true |
quantityInBaseLv | string | Oui | Quantité en UVC de base |
netWeight | int | Non | Poids net (g). Défaut : 0 |
grossWeight | int | Non | Poids brut (g). Défaut : 0 |
height | int | Non | Hauteur (mm). Défaut : 0 |
width | int | Non | Largeur (mm). Défaut : 0 |
depth | int | Non | Profondeur (mm). Défaut : 0 |
volume | int | Non | Volume (cm3). Défaut : 0 |
standardPrice | int | Non | Prix standard (centimes). Défaut : 0 |
checkAtReceipt | bool | Non | Contrôle à réception. Défaut : false |
repackingAtReceipt | bool | Non | Reconditionnement à réception. Défaut : false |
hdTypeCode | string | Non | Type de support (si packagingLv=true). Défaut : "434" |
locationSizeCode | string | Non | Taille emplacement (si packagingLv=true). Défaut : "434" |
storageGroupCode | string | Non | Famille de stockage (si packagingLv=true). Défaut : "E01" |
preparationGroupCode | string | Non | Famille de préparation (si packagingLv=true). Défaut : "001" |
bulkStorageGroupCode | string | Non | Groupe de stockage vrac |
kit | bool | Non | Article kit. Défaut : false |
specif1 à specif4 | DateTime | Non | Champs spécifiques date |
specif5 à specif8 | string (256) | Non | Champs spécifiques texte |
specif9 à specif12 | int | Non | Champs spécifiques numériques |
barcodes | Barcode[] | Non | Codes-barres spécifiques à cette VL |
subpackagingLvNbConstitutingLayer | int | Non | Nombre d’unités par couche (palettisation) |
heightLayer | double | Non | Hauteur de la couche en mm (palettisation) |
disableVl | bool | — | Lecture seule. Positionné automatiquement à true par le système quand une VL présente en base n’est plus dans l’envoi |
newLv | bool | — | Lecture seule. false pour la VL 10, true pour la VL 30 sur un nouvel article. Passe à false après la première réception WMS. |
Règles de validation
Section intitulée « Règles de validation »Champs obligatoires
Section intitulée « Champs obligatoires »activityCode,activityName,articleReference,longArticleDescription,shortArticleDescription,netWeightPerUVC
articleReference:^[A-Z0-9_.#/\-]+$(majuscules, chiffres, et_,.,#,/,-) — erreur 104 si format invalidearticleType:0,1ou2— erreur 202 si valeur invalidearticleAnalysisCode:E,CouD— erreur 202 si valeur invalidealcool.itemType:"010"ou"020"— erreur 202 si valeur invalidecountryOfOriginCode: ISO 3166-1 alpha-2minimumPriorityDateDayNumber: entier entre0et999inclus — erreur 202 si hors plage
Codes-barres
Section intitulée « Codes-barres »- Chaque
codedoit être unique au sein de l’envoi (erreur 203 si doublon) barcodeUnitdoit être une des 21 valeurs autorisées
Variantes logistiques (mode managedVl)
Section intitulée « Variantes logistiques (mode managedVl) »- Pas de doublons dans les
logisticalVariantCode(erreur 204) - Exactement une VL 10 avec
baseLv=true(erreur 207) - Exactement une VL 30 avec
packagingLv=true(erreur 207) - Une VL ne peut avoir qu’un seul flag actif parmi
baseLv,packagingLv,managementLv subpackagingLvCodedoit référencer une VL existante avec un code inférieur ou égal- Les quantités doivent être cohérentes hiérarchiquement
Verrouillage post-réception
Section intitulée « Verrouillage post-réception »- En mode
skipVl: après la première réception WMS, les champs de dimensions et quantités racine sont silencieusement ignorés. - En mode
managedVl: quand la VL 30 anewLv = false, toutes les VL sont silencieusement gelées — modifications ignorées, status0retourné, article danspassed. Aucune erreur n’est retournée. L’erreur 209 n’est pas déclenchée parPOST /articles.
Erreurs possibles
Section intitulée « Erreurs possibles »| Code | HTTP | Description |
|---|---|---|
| 104 | 400 | Caractères non autorisés dans articleReference (ou autre champ de format contrôlé) |
| 200 | 400 | logisticalVariants non autorisé en mode skipVl |
| 201 | 400 | Champ obligatoire manquant. Répété autant de fois qu’il y a de champs manquants (y compris par VL) |
| 202 | 400 | Valeur hors plage ou enum invalide : articleAnalysisCode, articleType, alcool.itemType, minimumPriorityDateDayNumber |
| 203 | 400 | Code-barre en doublon dans l’envoi |
| 204 | 400 | logisticalVariantCode en doublon dans logisticalVariants |
| 206 | 403 | Activité non autorisée — réponse HTTP 403 avec corps texte brut (hors OperationResult) |
| 207 | 400 | Structure des variantes logistiques invalide (VL manquante, flags incohérents, quantités incohérentes, parent inexistant) |
| 209 | 400 | Modification non autorisée — non déclenché par POST /articles (endpoint dédié VL uniquement) |
Exemple de requête
Section intitulée « Exemple de requête »[ { "activityCode": "001", "activityName": "Mon activité", "articleReference": "ART-001", "longArticleDescription": "T-shirt coton bio taille M bleu", "shortArticleDescription": "T-shirt M bleu", "netWeightPerUVC": 200, "grossWeightPerUVC": 250, "lengthPerUVC": 300, "widthPerUVC": 200, "heightPerUVC": 30, "articleType": 0, "quantityPerPCB": 12, "grossWeightPerPCB": 3500, "articleFamily": "TEXTILE", "articleSubFamily": "TSHIRT", "articleBrand": "EcoBrand", "articleSize": "M", "articleColor": "Bleu", "supplierCode": "FOUR01", "supplierArticleReference": "ECO-TSH-M-BLU", "countryOfOriginCode": "PT", "barcodes": [ { "code": "3760001234567", "isPrimary": true, "barcodeUnit": "UVC", "barcodeQuantity": 1 }, { "code": "03760001234567", "barcodeUnit": "PCB", "barcodeQuantity": 12 } ], "customField3": "Collection été 2024" }]Payload managedVl — 3 VL (10 + 20 + 30)
Section intitulée « Payload managedVl — 3 VL (10 + 20 + 30) »[ { "activityCode": "001", "activityName": "Mon activité", "articleReference": "ART-002", "longArticleDescription": "Boîte de céréales 500g", "shortArticleDescription": "Céréales 500g", "netWeightPerUVC": 0, "logisticalVariants": [ { "logisticalVariantCode": "10", "lvTypeCode": "UVC", "baseLv": true, "quantityInBaseLv": "1", "netWeight": 520 }, { "logisticalVariantCode": "20", "lvTypeCode": "PCB", "managementLv": true, "subpackagingLvCode": "10", "quantityInSubpackagingLv": 6, "quantityInBaseLv": "6", "netWeight": 3200 }, { "logisticalVariantCode": "30", "lvTypeCode": "SUP", "packagingLv": true, "subpackagingLvCode": "20", "quantityInSubpackagingLv": 4, "quantityInBaseLv": "24", "netWeight": 13000, "hdTypeCode": "434", "locationSizeCode": "434", "storageGroupCode": "E01", "preparationGroupCode": "001" } ] }]Exemples de code
Section intitulée « Exemples de code »curl -X POST "https://api.ezyconnect.com/articles" \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '[ { "activityCode": "001", "activityName": "Mon activité", "articleReference": "ART-001", "longArticleDescription": "T-shirt coton bio taille M bleu", "shortArticleDescription": "T-shirt M bleu", "netWeightPerUVC": 200 } ]'const response = await fetch("https://api.ezyconnect.com/articles", { method: "POST", headers: { "Authorization": "Bearer YOUR_TOKEN", "Content-Type": "application/json" }, body: JSON.stringify([ { activityCode: "001", activityName: "Mon activité", articleReference: "ART-001", longArticleDescription: "T-shirt coton bio taille M bleu", shortArticleDescription: "T-shirt M bleu", netWeightPerUVC: 200 } ])});
const result = await response.json();console.log(result);import requests
url = "https://api.ezyconnect.com/articles"headers = { "Authorization": "Bearer YOUR_TOKEN", "Content-Type": "application/json"}payload = [ { "activityCode": "001", "activityName": "Mon activité", "articleReference": "ART-001", "longArticleDescription": "T-shirt coton bio taille M bleu", "shortArticleDescription": "T-shirt M bleu", "netWeightPerUVC": 200 }]
response = requests.post(url, json=payload, headers=headers)result = response.json()print(result)using System.Net.Http;using System.Net.Http.Json;
var client = new HttpClient();client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", "YOUR_TOKEN");
var articles = new[]{ new { activityCode = "001", activityName = "Mon activité", articleReference = "ART-001", longArticleDescription = "T-shirt coton bio taille M bleu", shortArticleDescription = "T-shirt M bleu", netWeightPerUVC = 200 }};
var response = await client.PostAsJsonAsync("https://api.ezyconnect.com/articles", articles);var result = await response.Content.ReadAsStringAsync();Console.WriteLine(result);import java.net.URI;import java.net.http.HttpClient;import java.net.http.HttpRequest;import java.net.http.HttpResponse;
String body = """ [{ "activityCode": "001", "activityName": "Mon activité", "articleReference": "ART-001", "longArticleDescription": "T-shirt coton bio taille M bleu", "shortArticleDescription": "T-shirt M bleu", "netWeightPerUVC": 200 }] """;
HttpClient client = HttpClient.newHttpClient();HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://api.ezyconnect.com/articles")) .header("Authorization", "Bearer YOUR_TOKEN") .header("Content-Type", "application/json") .POST(HttpRequest.BodyPublishers.ofString(body)) .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());System.out.println(response.body());Exemples de réponse
Section intitulée « Exemples de réponse »Le champ status est un entier : 0 = tout OK, 1 = partiel (certains passés, certains rejetés), 2 = tout rejeté.
Succès (status 0)
{ "status": 0, "operationId": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "errors": {}, "passed": ["ART-001"]}Partiel (status 1) — un article valide, un rejeté
{ "status": 1, "operationId": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "errors": { "ART-002": [ { "code": "104", "description": "Ressource rejetée car présence de caractères pour [articleReference] non autorisés : [ART-002]" } ] }, "passed": ["ART-001"]}Tout rejeté (status 2) — plusieurs erreurs sur un même article
{ "status": 2, "operationId": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "errors": { "ART-001": [ { "code": "201", "description": "Ressource rejetée car donnée obligatoire [longArticleDescription] manquante : [ART-001]" }, { "code": "201", "description": "Ressource rejetée car donnée obligatoire [netWeightPerUVC] manquante : [ART-001]" } ] }, "passed": []}