/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/pingGénérée à partir de openapi.yaml : toujours à jour avec l'API. Pour tester un appel, utilisez l'onglet « Essayer un appel » de l'espace équipe.
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é>"