/api/ping
sans clé Réponses
Exemple
{
"statut": "ok",
"service": "cacaomatic-api",
"heure": "2026-10-24T09:00:00+00:00"
}Exemple curl
curl https://cacaomatic.alt4b.fr/api/pingFichier autonome, généré le 24/10/2026 à 22:26 : il fonctionne sans connexion
(aucune image, police ni script externe). Le serveur de l'API est https://cacaomatic.alt4b.fr.
Faites la phase 0 · Concevoir avant de construire : elle n'a besoin d'aucun outil, seulement de ce document. Rendez vos réponses (document texte, PDF ou photo lisible) à l'enseignant : elles font partie de la note. Dès que les outils sont de nouveau disponibles, vous réaliserez dans n8n ce que vous avez conçu.
Les liens vers n8n et l'API ne fonctionneront qu'avec une connexion.
Cacaomatic est une entreprise fictive qui fabrique du chocolat. Deux systèmes doivent travailler ensemble sans se connaître :
sku, cartons ou pièces, dates jj/mm/aaaa) ;aaaa-mm-jj).Votre équipe construit, dans n8n, les workflows qui font dialoguer les deux : lire les commandes de la boutique, les traduire,
les passer à l'ERP, puis renvoyer le résultat à la boutique. Les deux systèmes sont des API (https://cacaomatic.alt4b.fr/api).
Chaque équipe (A à H) dispose de sa clé d'API et de ses propres données : vous ne pouvez pas perturber les autres équipes.
/api/ping (sans clé).Authorization ; Value : Bearer <votre clé d'équipe> (avec l'espace après Bearer).https://cacaomatic.alt4b.fr/api.Le même credential sert pour la boutique et pour l'ERP.
GET, URL https://cacaomatic.alt4b.fr/api/boutique/commandes, credential de l'étape 2. Execute step : vous voyez les commandes de la boutique.GET https://cacaomatic.alt4b.fr/api/stocks/TAB-001. Vous obtenez stock_unites, reserve et disponible.TAB tablette, BAR barre, BTE boîte, PRA praliné, SAC sachet, POU poudre, PAT pâte à tartiner, CAL calendrier) et un numéro. La liste complète est dans l'onglet Stocks.La boutique publie ses commandes au fil du temps : relancez la lecture régulièrement (a_venir dit combien restent à venir). Une commande ressemble à :
{
"id": 1,
"id_commande_web": "WEB-2026-0001",
"passee_le": "24/10/2026 09:12",
"client": {"nom": "Épicerie Fictive du Port", "email": "achats@epicerie-port.example"},
"livraison_souhaitee": "15/12/2026",
"articles": [
{"sku": "CHOC-LAIT-100", "designation": "Tablette Lait Onctueux", "quantite": 2, "conditionnement": "carton"},
{"sku": "BARRE-CEREALES-40", "designation": "Barre Croquante aux Céréales", "quantite": 10, "conditionnement": "piece"}
],
"statut": "nouvelle"
}
Pour la passer à l'ERP, il faut traduire : le sku en code_article (table ci-dessous), piece en unite, la date en aaaa-mm-jj,
id_commande_web en reference_client, client.nom en client.
| sku (boutique) | Désignation | code_article (ERP) |
|---|---|---|
CHOC-NOIR-70-100 | Tablette Noir Intense 70 % | TAB-001 |
CHOC-LAIT-100 | Tablette Lait Onctueux | TAB-002 |
CHOC-BLANC-100 | Tablette Blanc Vanille | TAB-003 |
CHOC-NOISETTE-100 | Tablette Lait Noisettes Entières | TAB-004 |
BARRE-CARAMEL-45 | Barre Caramel Fondant | BAR-001 |
BARRE-CEREALES-40 | Barre Croquante aux Céréales | BAR-002 |
COFFRET-TRUFFES-250 | Coffret de Truffes Assorties | BTE-001 |
COFFRET-PRALINES-500 | Grand Coffret de Pralinés | PRA-001 |
PEPITES-NOIR-200 | Pépites de Chocolat Noir | SAC-001 |
CACAO-POUDRE-250 | Cacao en Poudre | POU-001 |
PATE-TARTINER-350 | Pâte à Tartiner Chocolat-Noisette | PAT-001 |
ROCHERS-PRALINES-1KG | Rochers Pralinés (vrac 1 kg) | PRA-002 |
CALENDRIER-AVENT | Calendrier de l'Avent | CAL-001 |
OEUFS-FOURRES-200 | Oeufs Fourrés Assortis | SAC-002 |
COUVERTURE-NOIR-1KG-PRO | Chocolat de Couverture Noir 1 kg (pro) | SAC-003 |
{
"CHOC-NOIR-70-100": "TAB-001",
"CHOC-LAIT-100": "TAB-002",
"CHOC-BLANC-100": "TAB-003",
"CHOC-NOISETTE-100": "TAB-004",
"BARRE-CARAMEL-45": "BAR-001",
"BARRE-CEREALES-40": "BAR-002",
"COFFRET-TRUFFES-250": "BTE-001",
"COFFRET-PRALINES-500": "PRA-001",
"PEPITES-NOIR-200": "SAC-001",
"CACAO-POUDRE-250": "POU-001",
"PATE-TARTINER-350": "PAT-001",
"ROCHERS-PRALINES-1KG": "PRA-002",
"CALENDRIER-AVENT": "CAL-001",
"OEUFS-FOURRES-200": "SAC-002",
"COUVERTURE-NOIR-1KG-PRO": "SAC-003"
}
Un sku absent de cette table est une anomalie à signaler, pas à deviner.
Avant d'ouvrir n8n, on raisonne sur le papier (ou dans un document) : quels appels, dans quel ordre, avec quelles données, et que faire quand ça se passe mal ? Cette phase ne demande ni n8n ni l'API : elle se fait sans connexion avec ce sujet et la documentation. Elle sert aussi de plan de secours : si les outils sont indisponibles pendant la séance, c'est le TP du jour, et ce que vous concevez ici se réalise ensuite dans n8n.
Extrait du catalogue de l'ERP (stock initial et unités par carton). Chaque équipe démarre avec les mêmes stocks.
| code_article | Libellé | Stock initial (unités) | Unités par carton |
|---|---|---|---|
TAB-001 | Tablette chocolat noir 70 % 100 g | 400 | 20 |
TAB-002 | Tablette chocolat au lait 100 g | 500 | 20 |
TAB-003 | Tablette chocolat blanc 100 g | 180 | 20 |
TAB-004 | Tablette chocolat noisettes 100 g | 60 | 20 |
BAR-001 | Barre chocolatée caramel 45 g | 300 | 36 |
BAR-002 | Barre croquante céréales 40 g | 720 | 36 |
BTE-001 | Boîte de truffes assorties 250 g | 96 | 12 |
PRA-001 | Boîte de pralinés 500 g | 48 | 8 |
SAC-001 | Sachet de pépites de chocolat noir 200 g | 240 | 24 |
POU-001 | Cacao en poudre 250 g | 150 | 12 |
PAT-001 | Pâte à tartiner chocolat-noisette 350 g | 120 | 6 |
PRA-002 | Rochers pralinés en vrac 1 kg | 35 | 10 |
CAL-001 | Calendrier de l'Avent chocolaté | 0 | 6 |
SAC-002 | Oeufs fourrés assortis 200 g | 90 | 15 |
SAC-003 | Chocolat de couverture noir 1 kg (pro) | 25 | 10 |
Les 8 commandes que la boutique publie, dans l'ordre d'arrivée (à traiter dans cet ordre, les stocks se consomment au fur et à mesure) :
| Commande | Client | Livraison | Articles (sku × quantité) |
|---|---|---|---|
WEB-2026-0001 | Épicerie Fictive du Port | 15/12/2026 | CHOC-LAIT-100 × 2 cartonsBARRE-CEREALES-40 × 10 pièces |
WEB-2026-0002 | Biscuiterie Imaginaire | 20/12/2026 | CHOC-NOIR-70-100 × 5 cartons |
WEB-2026-0003 | Café du Marché | 10/12/2026 | BARRE-CARAMEL-45 × 300 pièces |
WEB-2026-0004 | Boutique Les Délices Fictifs | 18/12/2026 | CHOC-NOISETTE-100 × 61 pièces |
WEB-2026-0005 | Hôtel Fictif des Alpes | 22/12/2026 | CALENDRIER-AVENT × 6 cartonsCHOC-BLANC-100 × 1 carton |
WEB-2026-0006 | Épicerie Fictive du Port | 19/12/2026 | SAISON-NOEL-2025 × 1 pièce |
WEB-2026-0002 | Biscuiterie Imaginaire | 20/12/2026 | CHOC-NOIR-70-100 × 5 cartons |
WEB-2026-0008 | Traiteur Fictif Chocolat Pro | 23/12/2026 | COFFRET-PRALINES-500 × 4 cartonsCACAO-POUDRE-250 × 2 cartonsPEPITES-NOIR-200 × 30 pièces |
[
{
"id_commande_web": "WEB-2026-0001",
"client": {
"nom": "Épicerie Fictive du Port",
"email": "achats@epicerie-port.example"
},
"livraison_souhaitee": "15/12/2026",
"articles": [
{
"sku": "CHOC-LAIT-100",
"quantite": 2,
"conditionnement": "carton"
},
{
"sku": "BARRE-CEREALES-40",
"quantite": 10,
"conditionnement": "piece"
}
]
},
{
"id_commande_web": "WEB-2026-0002",
"client": {
"nom": "Biscuiterie Imaginaire",
"email": "commandes@biscuiterie.example"
},
"livraison_souhaitee": "20/12/2026",
"articles": [
{
"sku": "CHOC-NOIR-70-100",
"quantite": 5,
"conditionnement": "carton"
}
]
},
{
"id_commande_web": "WEB-2026-0003",
"client": {
"nom": "Café du Marché",
"email": "cafe@marche.example"
},
"livraison_souhaitee": "10/12/2026",
"articles": [
{
"sku": "BARRE-CARAMEL-45",
"quantite": 300,
"conditionnement": "piece"
}
]
},
{
"id_commande_web": "WEB-2026-0004",
"client": {
"nom": "Boutique Les Délices Fictifs",
"email": "contact@delices.example"
},
"livraison_souhaitee": "18/12/2026",
"articles": [
{
"sku": "CHOC-NOISETTE-100",
"quantite": 61,
"conditionnement": "piece"
}
]
},
{
"id_commande_web": "WEB-2026-0005",
"client": {
"nom": "Hôtel Fictif des Alpes",
"email": "direction@hotel-alpes.example"
},
"livraison_souhaitee": "22/12/2026",
"articles": [
{
"sku": "CALENDRIER-AVENT",
"quantite": 6,
"conditionnement": "carton"
},
{
"sku": "CHOC-BLANC-100",
"quantite": 1,
"conditionnement": "carton"
}
]
},
{
"id_commande_web": "WEB-2026-0006",
"client": {
"nom": "Épicerie Fictive du Port",
"email": "achats@epicerie-port.example"
},
"livraison_souhaitee": "19/12/2026",
"articles": [
{
"sku": "SAISON-NOEL-2025",
"quantite": 1,
"conditionnement": "piece"
}
]
},
{
"id_commande_web": "WEB-2026-0002",
"client": {
"nom": "Biscuiterie Imaginaire",
"email": "commandes@biscuiterie.example"
},
"livraison_souhaitee": "20/12/2026",
"articles": [
{
"sku": "CHOC-NOIR-70-100",
"quantite": 5,
"conditionnement": "carton"
}
]
},
{
"id_commande_web": "WEB-2026-0008",
"client": {
"nom": "Traiteur Fictif Chocolat Pro",
"email": "cuisine@traiteur.example"
},
"livraison_souhaitee": "23/12/2026",
"articles": [
{
"sku": "COFFRET-PRALINES-500",
"quantite": 4,
"conditionnement": "carton"
},
{
"sku": "CACAO-POUDRE-250",
"quantite": 2,
"conditionnement": "carton"
},
{
"sku": "PEPITES-NOIR-200",
"quantite": 30,
"conditionnement": "piece"
}
]
}
]
Réponses réelles, à connaître pour concevoir les tests de votre workflow. Toutes les erreurs ont le même format {"erreur", "message", "details"}.
POST /api/commandes (cartons déjà convertis en unités par l'ERP){"id": 21, "reference_client": "WEB-2026-0002", "client": "Biscuiterie Imaginaire",
"date_livraison_souhaitee": "2026-12-20", "statut": "recue",
"lignes": [{"code_article": "TAB-001", "quantite": 5, "unite": "carton", "quantite_unites": 100}]}
POST /api/reservations{"id": 13, "reference_commande": "WEB-2026-0002", "lignes": [{"code_article": "TAB-001", "quantite": 100}]}
POST /api/reservations : stock insuffisant (rien n'est réservé){"erreur": "stock_insuffisant", "message": "Stock insuffisant : aucune réservation n'a été enregistrée.",
"details": {"lignes": [{"code_article": "TAB-004", "demande": 61, "disponible": 60, "suffisant": false}]}}
POST /api/commandes : référence déjà utilisée{"erreur": "commande_existante", "message": "Une commande avec la référence client « WEB-2026-0002 » existe déjà.",
"details": {"reference_client": "WEB-2026-0002"}}
{"erreur": "validation_echouee", "message": "Les données envoyées sont invalides.",
"details": {"champs": {"lignes.0.unite": ["La valeur du champ lignes.0.unite est invalide (valeurs acceptées : unite, carton)."]}}}
Retry-After: 30){"erreur": "service_indisponible", "message": "Panne simulée : le service est indisponible pendant encore 30 seconde(s).",
"details": {"secondes_restantes": 30}}
POST /api/ordres-fabrication et POST /api/boutique/commandes/{id}/statut (200){"id": 7, "code_article": "TAB-004", "quantite": 1, "reference_commande": "WEB-2026-0004", "statut": "planifie"}
POST /api/commandes correspondant à la commande WEB-2026-0001 (sku, conditionnement, date, noms de champs). Quelles transformations avez-vous dû faire ?| Commande | Appels dans l'ordre | Réponses attendues | Stock après | Statut renvoyé |
|---|---|---|---|---|
WEB-2026-0001 | ||||
WEB-2026-0002 | ||||
WEB-2026-0003 | ||||
WEB-2026-0004 | ||||
WEB-2026-0005 | ||||
WEB-2026-0006 | ||||
WEB-2026-0002 | ||||
WEB-2026-0008 |
401 non_authentifie alors que la clé semble correcte ;422 avec lignes.0.unite invalide pour une ligne « piece » de la boutique ;WEB-2026-0002 répond 409 commande_existante au deuxième passage de votre workflow : est-ce un bug ? que faire ?503 avec Retry-After: 30 alors que la boutique répond normalement.WEB-2026-0002 ?Un workflow (ou plusieurs) qui traite toutes les commandes de la boutique. Les 8 commandes ne se ressemblent pas : chacune cache un cas à gérer.
GET /api/boutique/commandes?statut=nouvelle. Une commande déjà traitée n'y figure plus.POST /api/commandes. Les quantités en carton sont converties par l'ERP.reference_client ne peut être utilisée qu'une fois : la boutique peut renvoyer une commande. Traitez le 409 sans réserver deux fois.details.POST /api/reservations. Elle est « tout ou rien » : un 409 stock_insuffisant détaille les lignes en cause.POST /api/ordres-fabrication pour la quantité manquante.POST /api/notifications (adv, production ou client) : refus, rupture, anomalie.POST /api/boutique/commandes/{id}/statut avec acceptee, refusee ou en_attente_fabrication (et un motif pour un refus).POST /api/panne, ou par l'enseignant) : l'ERP répond 503 avec Retry-After.
La boutique, elle, continue de répondre. Configurez les nouvelles tentatives (Retry On Fail) et une branche d'erreur : aucune commande ne doit être perdue.Les modalités exactes (date, format, barème) sont précisées par l'enseignant.
| Symptôme | Que faire |
|---|---|
401 non_authentifie | Vérifiez le credential : nom Authorization, valeur Bearer suivi de la clé, sans espace en trop. |
| « Connection refused » ou délai dépassé | Vérifiez l'URL (https://cacaomatic.alt4b.fr/api/…), puis testez /api/ping dans le navigateur. |
| La liste de la boutique est incomplète | Normal : la boutique publie ses commandes au fil du temps (a_venir). Relancez plus tard ou demandez à l'enseignant de tout libérer. |
| 422 | Le corps JSON est incomplet ou mal typé : lisez details dans la réponse. |
| 503 | Panne simulée de l'ERP sur votre équipe : attendez la durée de Retry-After (visible dans l'espace équipe) ou gérez-la dans le workflow. |
| 429 | Plus de 120 requêtes par minute : attendez une minute et vérifiez qu'une boucle ne tourne pas. |
| Workflow coupé | Il a dépassé 5 minutes : simplifiez-le. |
| Autre erreur | Faites une capture d'écran du message (et du Journal) et appelez l'enseignant. |
Facultatif, une fois le travail principal terminé : faites classer ou résumer par un modèle local les messages que vos workflows envoient.
http://ollama:11434 (sans espace ni « / » final).gemma4:e4b-it-q4_K_M.Classe ce message dans une seule rubrique parmi : adv, production, client.
Réponds uniquement par le nom de la rubrique.
Message : {{ $json.chatInput }}
Idée : utilisez la rubrique renvoyée comme destinataire de POST /api/notifications.
Utilisez uniquement le modèle gemma4:e4b-it-q4_K_M. Tous les groupes le partagent : si la réponse est lente, patientez avant de relancer.
Symptômes : « Connection refused » → vérifiez l'URL ; modèle absent de la liste → sauvegardez le credential, rouvrez le node et rechargez la page.
Adresse de base : https://cacaomatic.alt4b.fr/api
API du pseudo-ERP fictif de Cacaomatic, une entreprise qui fabrique du chocolat. Elle sert de support aux TP d'interopérabilité (n8n, Postman, curl…). Toutes les données sont fictives.
Authentification : une clé d'API par équipe, dans l'en-tête Authorization: Bearer <clé>.
Les données de chaque équipe sont isolées.
Limite : 120 requêtes par minute et par clé (réponse 429).
Erreurs : toutes les erreurs ont le même format {"erreur": "code_machine", "message": "…", "details": {…}}.
Quantités : le stock, les réservations et les ordres de fabrication sont exprimés en unités.
Une commande peut être passée en carton : un carton contient N unités selon l'article.
Les exemples curl ci-dessous se tapent dans un terminal (pas dans le navigateur). Ils montrent les informations à reporter dans n8n ou Postman : méthode, adresse, en-têtes et corps JSON. Pour essayer un appel depuis le navigateur, utilisez l'onglet « Essayer un appel » de l'espace équipe.
Dans n8n : nœud HTTP Request → Authentication « Generic Credential Type » → Header Auth,
nom Authorization, valeur Bearer <votre clé>. Pour un corps JSON : Send Body → JSON.
Codes HTTP utilisés : 401, 404, 409, 422, 429, 503. Le corps est toujours :
{"erreur": "stock_insuffisant", "message": "texte en français", "details": {}}
/api/ping
sans clé {
"statut": "ok",
"service": "cacaomatic-api",
"heure": "2026-10-24T09:00:00+00:00"
}curl https://cacaomatic.alt4b.fr/api/ping/api/commandes
| Nom | Où | Type | Description |
|---|---|---|---|
reference_client |
requête | string | Ne renvoie que les commandes ayant cette référence client (liste vide si aucune). |
{
"donnees": [
{
"id": 1,
"reference_client": "texte",
"client": "texte",
"date_livraison_souhaitee": "2026-12-01",
"statut": "recue",
"cree_le": "2026-10-24T09:00:00+00:00",
"lignes": [
{
"code_article": "texte",
"quantite": 1,
"unite": "unite",
"quantite_unites": 1
}
]
}
]
}{
"erreur": "non_authentifie",
"message": "Clé d'API manquante : ajoutez l'en-tête « Authorization: Bearer <clé> ».",
"details": []
}Retry-After.
{
"erreur": "stock_insuffisant",
"message": "texte",
"details": {}
}Retry-After.
{
"erreur": "stock_insuffisant",
"message": "texte",
"details": {}
}curl https://cacaomatic.alt4b.fr/api/commandes \
-H "Authorization: Bearer <votre clé>"/api/commandes
| Champ | Type | Description |
|---|---|---|
reference_clientobligatoire |
string | Unique par équipe. |
clientobligatoire |
string | |
date_livraison_souhaitee |
string | (peut être nul) |
lignes[]obligatoire |
liste d'objets | |
lignes[].code_articleobligatoire |
string | |
lignes[].quantiteobligatoire |
integer | (min 1) |
lignes[].uniteobligatoire |
string | (valeurs : unite, carton) |
{
"reference_client": "CMD-2026-001",
"client": "Épicerie Fictive du Port",
"date_livraison_souhaitee": "2026-12-01",
"lignes": [
{
"code_article": "TAB-001",
"quantite": 5,
"unite": "carton"
},
{
"code_article": "TAB-002",
"quantite": 10,
"unite": "unite"
}
]
}
{
"id": 1,
"reference_client": "texte",
"client": "texte",
"date_livraison_souhaitee": "2026-12-01",
"statut": "recue",
"cree_le": "2026-10-24T09:00:00+00:00",
"lignes": [
{
"code_article": "texte",
"quantite": 1,
"unite": "unite",
"quantite_unites": 1
}
]
}{
"erreur": "non_authentifie",
"message": "Clé d'API manquante : ajoutez l'en-tête « Authorization: Bearer <clé> ».",
"details": []
}reference_client existe déjà pour votre équipe.
{
"erreur": "commande_existante",
"message": "Une commande avec la référence client « CMD-2026-001 » existe déjà.",
"details": {
"reference_client": "CMD-2026-001"
}
}{
"erreur": "validation_echouee",
"message": "Les données envoyées sont invalides.",
"details": {
"champs": {
"lignes.0.quantite": [
"Le champ lignes.0.quantite doit être supérieur ou égal à 1."
]
}
}
}Retry-After.
{
"erreur": "stock_insuffisant",
"message": "texte",
"details": {}
}Retry-After.
{
"erreur": "stock_insuffisant",
"message": "texte",
"details": {}
}curl -X POST https://cacaomatic.alt4b.fr/api/commandes \
-H "Authorization: Bearer <votre clé>" \
-H "Content-Type: application/json" \
-d '{"reference_client":"CMD-2026-001","client":"Épicerie Fictive du Port","date_livraison_souhaitee":"2026-12-01","lignes":[{"code_article":"TAB-001","quantite":5,"unite":"carton"},{"code_article":"TAB-002","quantite":10,"unite":"unite"}]}'/api/commandes/{id}
| Nom | Où | Type | Description |
|---|---|---|---|
idobligatoire |
chemin | integer |
{
"id": 1,
"reference_client": "texte",
"client": "texte",
"date_livraison_souhaitee": "2026-12-01",
"statut": "recue",
"cree_le": "2026-10-24T09:00:00+00:00",
"lignes": [
{
"code_article": "texte",
"quantite": 1,
"unite": "unite",
"quantite_unites": 1
}
]
}{
"erreur": "non_authentifie",
"message": "Clé d'API manquante : ajoutez l'en-tête « Authorization: Bearer <clé> ».",
"details": []
}{
"erreur": "stock_insuffisant",
"message": "texte",
"details": {}
}Retry-After.
{
"erreur": "stock_insuffisant",
"message": "texte",
"details": {}
}Retry-After.
{
"erreur": "stock_insuffisant",
"message": "texte",
"details": {}
}curl https://cacaomatic.alt4b.fr/api/commandes/<id> \
-H "Authorization: Bearer <votre clé>"/api/stocks/{code_article}
| Nom | Où | Type | Description |
|---|---|---|---|
code_articleobligatoire |
chemin | string | Exemple : TAB-001 |
disponible = stock_unites − reserve.
{
"code_article": "TAB-001",
"stock_unites": 400,
"reserve": 0,
"disponible": 400
}{
"erreur": "non_authentifie",
"message": "Clé d'API manquante : ajoutez l'en-tête « Authorization: Bearer <clé> ».",
"details": []
}{
"erreur": "stock_insuffisant",
"message": "texte",
"details": {}
}Retry-After.
{
"erreur": "stock_insuffisant",
"message": "texte",
"details": {}
}Retry-After.
{
"erreur": "stock_insuffisant",
"message": "texte",
"details": {}
}curl https://cacaomatic.alt4b.fr/api/stocks/<code_article> \
-H "Authorization: Bearer <votre clé>"/api/reservations
Les quantités sont en unités. Une réservation est acceptée si, pour chaque article, la quantité demandée est inférieure ou égale au disponible (égalité acceptée). Si une ligne est insuffisante, aucune ligne n'est réservée (409).
| Champ | Type | Description |
|---|---|---|
reference_commandeobligatoire |
string | |
lignes[]obligatoire |
liste d'objets | |
lignes[].code_articleobligatoire |
string | |
lignes[].quantiteobligatoire |
integer | En unités. (min 1) |
{
"reference_commande": "CMD-2026-001",
"lignes": [
{
"code_article": "TAB-001",
"quantite": 100
}
]
}
{
"id": 1,
"reference_commande": "texte",
"cree_le": "2026-10-24T09:00:00+00:00",
"lignes": [
{
"code_article": "texte",
"quantite": 1
}
]
}{
"erreur": "non_authentifie",
"message": "Clé d'API manquante : ajoutez l'en-tête « Authorization: Bearer <clé> ».",
"details": []
}details.lignes donne le détail par ligne.
{
"erreur": "stock_insuffisant",
"message": "Stock insuffisant : aucune réservation n'a été enregistrée.",
"details": {
"lignes": [
{
"code_article": "TAB-001",
"demande": 10,
"disponible": 400,
"suffisant": true
},
{
"code_article": "TAB-004",
"demande": 61,
"disponible": 60,
"suffisant": false
}
]
}
}{
"erreur": "validation_echouee",
"message": "Les données envoyées sont invalides.",
"details": {
"champs": {
"lignes.0.quantite": [
"Le champ lignes.0.quantite doit être supérieur ou égal à 1."
]
}
}
}Retry-After.
{
"erreur": "stock_insuffisant",
"message": "texte",
"details": {}
}Retry-After.
{
"erreur": "stock_insuffisant",
"message": "texte",
"details": {}
}curl -X POST https://cacaomatic.alt4b.fr/api/reservations \
-H "Authorization: Bearer <votre clé>" \
-H "Content-Type: application/json" \
-d '{"reference_commande":"CMD-2026-001","lignes":[{"code_article":"TAB-001","quantite":100}]}'/api/ordres-fabrication
| Champ | Type | Description |
|---|---|---|
code_articleobligatoire |
string | |
quantiteobligatoire |
integer | (min 1) |
reference_commandeobligatoire |
string |
{
"code_article": "CAL-001",
"quantite": 120,
"reference_commande": "CMD-2026-001"
}
{
"id": 1,
"code_article": "texte",
"quantite": 1,
"reference_commande": "texte",
"statut": "planifie",
"cree_le": "2026-10-24T09:00:00+00:00"
}{
"erreur": "non_authentifie",
"message": "Clé d'API manquante : ajoutez l'en-tête « Authorization: Bearer <clé> ».",
"details": []
}{
"erreur": "validation_echouee",
"message": "Les données envoyées sont invalides.",
"details": {
"champs": {
"lignes.0.quantite": [
"Le champ lignes.0.quantite doit être supérieur ou égal à 1."
]
}
}
}Retry-After.
{
"erreur": "stock_insuffisant",
"message": "texte",
"details": {}
}Retry-After.
{
"erreur": "stock_insuffisant",
"message": "texte",
"details": {}
}curl -X POST https://cacaomatic.alt4b.fr/api/ordres-fabrication \
-H "Authorization: Bearer <votre clé>" \
-H "Content-Type: application/json" \
-d '{"code_article":"CAL-001","quantite":120,"reference_commande":"CMD-2026-001"}'/api/notifications
{
"donnees": [
{
"id": 1,
"destinataire": "adv",
"sujet": "texte",
"message": "texte",
"cree_le": "2026-10-24T09:00:00+00:00"
}
]
}{
"erreur": "non_authentifie",
"message": "Clé d'API manquante : ajoutez l'en-tête « Authorization: Bearer <clé> ».",
"details": []
}Retry-After.
{
"erreur": "stock_insuffisant",
"message": "texte",
"details": {}
}Retry-After.
{
"erreur": "stock_insuffisant",
"message": "texte",
"details": {}
}curl https://cacaomatic.alt4b.fr/api/notifications \
-H "Authorization: Bearer <votre clé>"/api/notifications
Aucun e-mail n'est envoyé : les notifications sont consultables avec GET /notifications.
| Champ | Type | Description |
|---|---|---|
destinataireobligatoire |
string | (valeurs : adv, production, client) |
sujetobligatoire |
string | (longueur max 200) |
messageobligatoire |
string | (longueur max 2000) |
{
"destinataire": "adv",
"sujet": "texte",
"message": "texte"
}
{
"id": 1,
"destinataire": "adv",
"sujet": "texte",
"message": "texte",
"cree_le": "2026-10-24T09:00:00+00:00"
}{
"erreur": "non_authentifie",
"message": "Clé d'API manquante : ajoutez l'en-tête « Authorization: Bearer <clé> ».",
"details": []
}{
"erreur": "validation_echouee",
"message": "Les données envoyées sont invalides.",
"details": {
"champs": {
"lignes.0.quantite": [
"Le champ lignes.0.quantite doit être supérieur ou égal à 1."
]
}
}
}Retry-After.
{
"erreur": "stock_insuffisant",
"message": "texte",
"details": {}
}Retry-After.
{
"erreur": "stock_insuffisant",
"message": "texte",
"details": {}
}curl -X POST https://cacaomatic.alt4b.fr/api/notifications \
-H "Authorization: Bearer <votre clé>" \
-H "Content-Type: application/json" \
-d '{"destinataire":"adv","sujet":"texte","message":"texte"}'Boutique en ligne fictive : le système source qui reçoit les commandes des clients, dans son propre format
(sku, cartons ou pièces, dates jj/mm/aaaa). Votre workflow lit ces commandes, les traduit pour l'ERP (commandes,
réservations, fabrication), puis renvoie à la boutique le résultat avec POST /boutique/commandes/{id}/statut.
Les commandes sont publiées au fil du temps : relisez régulièrement la liste (a_venir indique combien
restent à venir). La boutique n'est pas touchée par la panne simulée de l'ERP.
/api/boutique/commandes
Commandes déjà publiées pour votre équipe, de la plus ancienne à la plus récente. Une commande renvoyée par la
boutique (doublon) porte le même id_commande_web mais un id différent.
Le sku n'est pas le code article de l'ERP : utilisez la table de correspondance donnée dans le sujet du TP.
| Nom | Où | Type | Description |
|---|---|---|---|
statut |
requête | string | Ne renvoie que les commandes ayant ce statut (nouvelle = pas encore traitée). Exemple : nouvelle |
{
"donnees": [
{
"id": 1,
"id_commande_web": "WEB-2026-0001",
"passee_le": "24/10/2026 09:12",
"client": {
"nom": "Épicerie Fictive du Port",
"email": "achats@epicerie-port.example"
},
"livraison_souhaitee": "15/12/2026",
"articles": [
{
"sku": "CHOC-LAIT-100",
"designation": "Tablette Lait Onctueux",
"quantite": 2,
"conditionnement": "carton"
}
],
"statut": "nouvelle",
"reference_erp": "texte",
"motif": "texte"
}
],
"a_venir": 5
}{
"erreur": "non_authentifie",
"message": "Clé d'API manquante : ajoutez l'en-tête « Authorization: Bearer <clé> ».",
"details": []
}{
"erreur": "validation_echouee",
"message": "Les données envoyées sont invalides.",
"details": {
"champs": {
"lignes.0.quantite": [
"Le champ lignes.0.quantite doit être supérieur ou égal à 1."
]
}
}
}Retry-After.
{
"erreur": "stock_insuffisant",
"message": "texte",
"details": {}
}curl https://cacaomatic.alt4b.fr/api/boutique/commandes \
-H "Authorization: Bearer <votre clé>"/api/boutique/commandes/{id}
| Nom | Où | Type | Description |
|---|---|---|---|
idobligatoire |
chemin | integer | Identifiant technique (id) |
{
"id": 1,
"id_commande_web": "WEB-2026-0001",
"passee_le": "24/10/2026 09:12",
"client": {
"nom": "Épicerie Fictive du Port",
"email": "achats@epicerie-port.example"
},
"livraison_souhaitee": "15/12/2026",
"articles": [
{
"sku": "CHOC-LAIT-100",
"designation": "Tablette Lait Onctueux",
"quantite": 2,
"conditionnement": "carton"
}
],
"statut": "nouvelle",
"reference_erp": "texte",
"motif": "texte"
}{
"erreur": "non_authentifie",
"message": "Clé d'API manquante : ajoutez l'en-tête « Authorization: Bearer <clé> ».",
"details": []
}{
"erreur": "stock_insuffisant",
"message": "texte",
"details": {}
}Retry-After.
{
"erreur": "stock_insuffisant",
"message": "texte",
"details": {}
}curl https://cacaomatic.alt4b.fr/api/boutique/commandes/<id> \
-H "Authorization: Bearer <votre clé>"/api/boutique/commandes/{id}/statut
Peut être rappelé : le dernier statut remplace le précédent.
| Nom | Où | Type | Description |
|---|---|---|---|
idobligatoire |
chemin | integer | Identifiant technique (id). Exemple : 1 |
| Champ | Type | Description |
|---|---|---|
statutobligatoire |
string | (valeurs : acceptee, refusee, en_attente_fabrication) |
reference_erp |
string | Référence de la commande côté ERP (facultatif). (longueur max 100) |
motif |
string | Explication, notamment pour un refus (facultatif). (longueur max 500) |
{
"statut": "acceptee",
"reference_erp": "WEB-2026-0001"
}
{
"id": 1,
"id_commande_web": "WEB-2026-0001",
"passee_le": "24/10/2026 09:12",
"client": {
"nom": "Épicerie Fictive du Port",
"email": "achats@epicerie-port.example"
},
"livraison_souhaitee": "15/12/2026",
"articles": [
{
"sku": "CHOC-LAIT-100",
"designation": "Tablette Lait Onctueux",
"quantite": 2,
"conditionnement": "carton"
}
],
"statut": "nouvelle",
"reference_erp": "texte",
"motif": "texte"
}{
"erreur": "non_authentifie",
"message": "Clé d'API manquante : ajoutez l'en-tête « Authorization: Bearer <clé> ».",
"details": []
}{
"erreur": "stock_insuffisant",
"message": "texte",
"details": {}
}{
"erreur": "validation_echouee",
"message": "Les données envoyées sont invalides.",
"details": {
"champs": {
"lignes.0.quantite": [
"Le champ lignes.0.quantite doit être supérieur ou égal à 1."
]
}
}
}Retry-After.
{
"erreur": "stock_insuffisant",
"message": "texte",
"details": {}
}curl -X POST https://cacaomatic.alt4b.fr/api/boutique/commandes/<id>/statut \
-H "Authorization: Bearer <votre clé>" \
-H "Content-Type: application/json" \
-d '{"statut":"acceptee","reference_erp":"WEB-2026-0001"}'Panne propre à votre équipe. Tant qu'elle est active, tous vos autres appels répondent 503 avec Retry-After.
/api/panne
{
"active": true,
"fin": "2026-10-24T09:00:00+00:00",
"secondes_restantes": 1
}{
"erreur": "non_authentifie",
"message": "Clé d'API manquante : ajoutez l'en-tête « Authorization: Bearer <clé> ».",
"details": []
}Retry-After.
{
"erreur": "stock_insuffisant",
"message": "texte",
"details": {}
}curl https://cacaomatic.alt4b.fr/api/panne \
-H "Authorization: Bearer <votre clé>"/api/panne
| Champ | Type | Description |
|---|---|---|
duree_secondes |
integer | (min 1 ; max 600 ; défaut 120) |
{
"duree_secondes": 1
}
{
"active": true,
"fin": "2026-10-24T09:00:00+00:00",
"secondes_restantes": 1
}{
"erreur": "non_authentifie",
"message": "Clé d'API manquante : ajoutez l'en-tête « Authorization: Bearer <clé> ».",
"details": []
}{
"erreur": "validation_echouee",
"message": "Les données envoyées sont invalides.",
"details": {
"champs": {
"lignes.0.quantite": [
"Le champ lignes.0.quantite doit être supérieur ou égal à 1."
]
}
}
}Retry-After.
{
"erreur": "stock_insuffisant",
"message": "texte",
"details": {}
}curl -X POST https://cacaomatic.alt4b.fr/api/panne \
-H "Authorization: Bearer <votre clé>" \
-H "Content-Type: application/json" \
-d '{"duree_secondes":1}'/api/panne
{
"active": true,
"fin": "2026-10-24T09:00:00+00:00",
"secondes_restantes": 1
}{
"erreur": "non_authentifie",
"message": "Clé d'API manquante : ajoutez l'en-tête « Authorization: Bearer <clé> ».",
"details": []
}Retry-After.
{
"erreur": "stock_insuffisant",
"message": "texte",
"details": {}
}curl -X DELETE https://cacaomatic.alt4b.fr/api/panne \
-H "Authorization: Bearer <votre clé>"Réservé à la clé enseignant.
/api/admin/equipes
{
"donnees": [
{
"code": "texte",
"nom": "texte",
"session": {
"promotion": "texte",
"annee": 1,
"groupe": "texte"
},
"scenario": "texte",
"panne_active": true,
"panne_fin": "2026-10-24T09:00:00+00:00",
"commandes": 1,
"reservations": 1,
"ordres_fabrication": 1,
"notifications": 1,
"appels": 1
}
]
}{
"erreur": "non_authentifie",
"message": "Clé d'API manquante : ajoutez l'en-tête « Authorization: Bearer <clé> ».",
"details": []
}Retry-After.
{
"erreur": "stock_insuffisant",
"message": "texte",
"details": {}
}curl https://cacaomatic.alt4b.fr/api/admin/equipes \
-H "Authorization: Bearer <votre clé>"/api/admin/equipes/{code}/reinitialiser
Remet les stocks, commandes, réservations, ordres de fabrication, notifications, journal et panne de l'équipe à l'état initial.
| Nom | Où | Type | Description |
|---|---|---|---|
codeobligatoire |
chemin | string | Exemple : A |
{
"code": "A",
"message": "L'équipe A a été réinitialisée."
}{
"erreur": "non_authentifie",
"message": "Clé d'API manquante : ajoutez l'en-tête « Authorization: Bearer <clé> ».",
"details": []
}{
"erreur": "stock_insuffisant",
"message": "texte",
"details": {}
}Retry-After.
{
"erreur": "stock_insuffisant",
"message": "texte",
"details": {}
}curl -X POST https://cacaomatic.alt4b.fr/api/admin/equipes/<code>/reinitialiser \
-H "Authorization: Bearer <votre clé>"