API REST de Reglova. Authentification : Authorization: Bearer <jeton>, soit un jeton de session (POST /api/auth/login), soit une clé d'API gmao_… créée par un administrateur pour une intégration (ERP, supervision, BI) ; la clé agit au nom de son compte (rôle et usines).
Webhooks : chaque événement du journal d'audit (work_order.create, work_order.transition, purchase.receive, inspection.result…) peut être poussé en POST JSON vers une URL. En-têtes X-GMAO-Event, X-GMAO-Delivery et X-GMAO-Signature: sha256=<HMAC-SHA256 du corps avec le secret du webhook>. Trois tentatives (immédiate, +5 s, +30 s). Corps : schéma WebhookPayload.
Rapports et Power BI : GET /api/reports renvoie les indicateurs calculés côté serveur sur tout l'historique, pour une période en jours UTC entiers. Pour Power BI ou un entrepôt de données, interroger cette route (JSON) avec une clé d'API dans l'en-tête Authorization: Bearer gmao_… ; éviter ?token=, qui finit dans les journaux des serveurs. Les exports CSV préfixent d'une apostrophe les textes qui ressemblent à des formules : préférer le JSON pour un traitement automatique.
Temps réel : WebSocket GET /api/live?token=… (deltas et KPI).
Hors ligne : l'application terrain met chaque geste en file sur l'appareil et le rejoue au retour du réseau. Les commandes de terrain acceptent at, l'heure du geste : 48 h au plus dans le passé, un léger futur est ramené à l'heure du serveur, au-delà d'un jour dans le futur refus (code clock). Les contrôles de sécurité (consignation, permis, habilitations, surveillance incendie) sont évalués à cette heure. Rejouer un même geste est sans effet ; les créations portent une client_ref. Chaque refus porte un code stable. L'audit garde at, received_at et deferred.
Spécification brute : /api/openapi.json (OpenAPI 3.1, à importer dans Postman, Insomnia ou un générateur de client).
Système
GET /api/health — Santé de l'API public
Réponse
objectAuthentification
POST /api/auth/login — Connexion e-mail / mot de passe → jeton de session (12 h). Double authentification active : 401 « mfa_required » sans `code`, puis code TOTP à 6 chiffres. 5 échecs (mot de passe ou code) en 15 minutes bloquent l'adresse e-mail, 50 échecs bloquent l'adresse IP : 429 `rate_limited`, en-tête `Retry-After` (secondes) et `retry_after` dans le corps public
Corps
email* :stringpassword* :stringcode:string
Réponse
token:stringuser:object
GET /api/auth/options — Ce que la page de connexion propose : comptes de démonstration (`demo`, si le tenant de démonstration existe) et connexion unique d'entreprise (`sso.label`, ou null) public
Réponse
demo:booleansso:object
POST /api/auth/logout — Se déconnecter : le jeton de la session est refusé jusqu'à son échéance. `everywhere` : toutes les sessions du compte, sur tous les appareils
Corps
everywhere:boolean
Réponse
204 No ContentPOST /api/auth/forgot — Mot de passe oublié : 202, que l'adresse existe ou non. Un compte actif reçoit par e-mail un lien d'une heure (`/acces#gmaolink_…`), un compte invité un nouveau lien d'invitation. 5 demandes par adresse et par quart d'heure (429) public
Corps
email* :stringlocale:string
Réponse
204 No ContentPOST /api/auth/link — À qui est un lien d'accès (réinitialisation, invitation ou activation d'un essai `gmaotrial_…`) : adresse, nom, motif, entreprise de l'essai, échéance. 410 si le lien est échu, déjà utilisé ou falsifié public
Corps
token* :string
Réponse
email:stringname:stringpurpose:reset|invite|trialcompany:stringexpires_at:integer
POST /api/auth/reset — Choisir son mot de passe par un lien d'accès (10 caractères au moins). Le lien ne sert qu'une fois ; les sessions ouvertes du compte tombent. Lien d'activation d'un essai (`gmaotrial_…`) : l'espace du client est créé à cet instant, essai de 30 jours. 410 si le lien n'est plus valable public
Corps
token* :stringpassword* :string
Réponse
email:string
POST /api/auth/renew — Prolonger une session encore valide (écran d'atelier, poste partagé) : nouveau jeton de 12 h, rôle et nom relus dans le compte ; au plus 7 jours après la connexion (401 ensuite : se reconnecter) ; 400 pour une clé d'API, qui n'expire pas
Réponse
token:stringuser:object
GET /api/auth/oidc — Connexion unique d'entreprise : activée ? libellé du bouton public
Réponse
enabled:booleanlabel:string
GET /api/auth/oidc/start — Redirige vers le fournisseur d'identité (OpenID Connect, code + PKCE) public
Réponse
204 No ContentGET /api/auth/oidc/callback — Retour du fournisseur : vérifie le jeton d'identité et redirige vers le front avec la session (#sso=…) public
Réponse
204 No ContentPOST /api/me/mfa/setup — Double authentification : nouveau secret TOTP et adresse otpauth:// à scanner
Réponse
secret:stringotpauth_url:string
POST /api/me/mfa/enable — Activer la double authentification avec un premier code
Corps
code* :string
Réponse
204 No ContentPOST /api/me/mfa/disable — Désactiver la double authentification (code requis)
Corps
code* :string
Réponse
204 No ContentGET /api/me — Utilisateur courant (dont `reminders` : reçoit les rappels par e-mail)
Réponse
objectPUT /api/me/reminders — Recevoir ou non le rappel du matin et le récapitulatif du lundi (pour soi seulement)
Corps
on* :boolean
Réponse
reminders:boolean
Comptes
GET /api/security — Administrateur : double authentification imposée par le client (`off`, `privileged` = administrateurs et responsables, `all`) et nombre de comptes actifs qui devront l'activer selon la politique
Réponse
mfa_policy:off|privileged|allwithout_mfa:privileged:integerall:integer
PUT /api/security — Administrateur : imposer la double authentification. Un compte visé qui ne l'a pas encore activée ne peut plus que l'activer (403 `mfa_setup_required` ailleurs) ; une session de connexion unique d'entreprise en est dispensée ; la désactiver devient impossible (422 `mfa_required`)
Corps
mfa_policy* :off|privileged|all
Réponse
mfa_policy:stringwithout_mfa:privileged:integerall:integer
POST /api/users/{id}/access-link — Administrateur : (ré)envoie l'invitation d'un compte invité (7 jours, la précédente est périmée) ou un lien de réinitialisation de 24 h pour un compte actif. Le lien est aussi rendu, à transmettre si l'e-mail n'est pas configuré
Corps
locale:stringsend:boolean
Réponse
url:stringpurpose:reset|inviteexpires_at:integeremailed:boolean
GET /api/users/{id}/personal-data — RGPD art. 15 : export des données d'un utilisateur (compte, OT, temps, messages, absences, journal d'audit)
Réponse
objectPOST /api/users/{id}/erase — RGPD art. 17 : pseudonymise l'utilisateur dans tout l'historique, anonymise et désactive le compte (journal d'audit conservé)
Réponse
204 No ContentPOST /api/privacy/erase — RGPD : effacement d'un demandeur sans compte (nom et e-mail)
Corps
name* :stringemail:string
Réponse
204 No ContentDonnées
GET /api/snapshot — État complet du tenant (filtré par usines autorisées)
Réponse
SnapshotGET /api/export/work-order-analysis.csv — Analyse prévu / réel des OT d'une période en CSV (une ligne par OT ; mêmes paramètres que GET /api/work-orders/analysis)
Réponse
204 No ContentPOST /api/import/assets — Import d'équipements, CSV ou classeur Excel .xlsx (tout ou rien)
Corps
stringRéponse
objectPOST /api/import/work-orders — Reprise de l'historique des interventions, CSV ou .xlsx (tout ou rien) : OT clôturés avec compte rendu et temps passés. Codes ISO 14224 facultatifs (failure_mode, mechanism, cause_code, activity, detection) : un code inconnu rejette la ligne, une ligne sans code est reprise telle quelle. Réponse : imported, et uncoded (correctifs sans mode ni cause, « non renseignés »)
Corps
stringRéponse
imported:integeruncoded:integer
GET /api/import/work-orders/template — Modèle CSV de l'historique
Réponse
204 No ContentGET /api/export/assets.csv — Export CSV des équipements
Réponse
204 No ContentGET /api/export/work-orders.csv — Export CSV des OT, avec leurs codes ISO 14224 (même vocabulaire que la reprise d'historique)
Réponse
204 No ContentGET /api/sites/{id}/audit-dossier.pdf — Dossier d'audit PDF d'une usine (query : standard=ifs|brcgs|iatf, from, to en ms) : synthèse, interventions, réparations temporaires, levées d'hygiène, contrôles et étalonnages, consignations, permis, signatures ; empreinte SHA-256 journalisée
Réponse
204 No ContentGET /api/export/plans.csv — Export CSV des plans préventifs
Réponse
204 No ContentGET /api/export/audit.csv — Export CSV complet du journal d'audit
Réponse
204 No ContentGET /api/export/all.zip — Export complet du compte en .zip : LISEZMOI.txt, donnees.json (toutes les données des usines autorisées, sans les adresses des demandeurs), equipements.csv, interventions.csv, preventif.csv, controles.csv, pieces.csv, journal-audit.csv (droit d'audit) et fichiers/ (pièces jointes, 300 Mo au plus, les autres listées). Reste ouvert après la fin d'un essai
Réponse
204 No ContentÉquipements
GET /api/assets/{id} — Fiche équipement
Réponse
AssetPATCH /api/assets/{id} — Corriger la fiche (droit d'implantation) : nom, fabricant, modèle, année (0 : inconnue), criticité, ligne (`null` : hors ligne), numéro de série, fournisseur, valeur, dates AAAA-MM-JJ. Le code et la classe ne changent pas. Chaque champ changé est tracé dans le fil de l'équipement
Corps
name:stringmanufacturer:stringmodel:stringyear:integercriticality:A|B|Cline_id:stringserial_no:stringsupplier:stringcost_eur:integercommissioned_on:stringwarranty_until:string
Réponse
204 No ContentPOST /api/assets/{id}/retire — Retirer du parc (rebut, vente) : plus de demande, d'OT ni de portail QR, plans préventifs désactivés, hors indicateurs ; historique gardé. 422 open_work tant qu'un OT est ouvert sur l'équipement
Corps
note:string
Réponse
204 No ContentPOST /api/assets/{id}/reinstate — Remettre au parc un équipement retiré par erreur (ses plans restent à réactiver)
Réponse
204 No ContentPOST /api/assets/{id}/restart — Remise en service d'une machine arrêtée (rôle d'exécution) : l'arrêt finit pour les OT qui la tenaient à l'heure du geste (`at`), qui restent ouverts ; une panne « machine arrêtée » déclarée après ce geste tient toujours la machine arrêtée. 422 si la machine n'est pas arrêtée (not_stopped), sous consignation (lockout_active), en cours d'intervention (in_progress) ou en attente de levée d'hygiène (hygiene_pending), ou si l'heure du geste précède l'arrêt (order)
Corps
at:integer— Heure du geste (ms epoch), saisie hors ligne : 48 h au plus dans le passé ; un léger futur est ramené à l'heure du serveur. Absent : heure de réception
Réponse
204 No ContentPOST /api/assets/{id}/public-token — Nouveau QR code (gestion des usines) : un nouveau jeton remplace l'ancien, qui n'ouvre plus le portail de demande (QR perdu, déclarations abusives). Journalisé sans le jeton
Réponse
AssetPOST /api/assets/{id}/model — Modèle 3D depuis un lien (fichier glTF/GLB stocké en pièce jointe, ou fiche produit / image → recette générée par l'IA), une description (`prompt`) ou une pièce jointe glTF de l'équipement. `same_model` : tous les équipements du même fabricant et modèle. 413 fichier trop gros, 415 contenu non reconnu, 502 lien ou IA en échec, 503 IA non configurée
Corps
url:stringprompt:stringattachment_id:stringsame_model:boolean
Réponse
ModelResultDELETE /api/assets/{id}/model — Retour au modèle procédural du type (`?same_model=true` : tous les équipements du même modèle)
Réponse
ModelResultPUT /api/assets/{id}/anchors — Ancrages 3D des points d'isolement et des points de mesure de l'équipement (tout ou rien ; null retire l'ancrage)
Corps
AnchorsInputRéponse
AssetUsines
POST /api/assets — Poser un équipement depuis le catalogue de l'éditeur (mêmes champs et règles qu'une ligne d'import ; x/z absents : zone d'attente)
Corps
site_code* :stringline_code:stringcode* :stringname* :stringkind* :stringmanufacturer:stringmodel:stringyear:integercriticality* :A|B|Cx:numberz:numberlength:numberserial_no:stringsupplier:stringcost_eur:integercommissioned_on:stringwarranty_until:string
Réponse
AssetPOST /api/sites — Créer une usine (responsable, administrateur) : place libre sur la vue réseau, équipes et canal de maintenance créés
Corps
SiteInputRéponse
SitePATCH /api/sites/{id} — Modifier une usine (identifiant et place sur la vue réseau inchangés)
Corps
SiteInputRéponse
SitePUT /api/sites/{id}/layout — Enregistrer le plan (tout ou rien) : emprise facultative, positions et rotations (radians) ; cour de 40 m autour du bâtiment
Corps
width:numberdepth:numberplacements: [asset_id* :stringx* :numberz* :numberrotation:number
Réponse
LayoutResultPOST /api/sites/{id}/auto-layout — Implantation automatique : une rangée par ligne selon le flux, utilités au nord, silos dehors à l'ouest, allée principale au sud ; bâtiment redimensionné
Réponse
LayoutResultPATCH /api/sites/{id}/settings — Administrateur : mode petite structure (`simple` : barre courte, clôture d'une phrase, codes de panne facultatifs) et rappels par e-mail (`reminders` : rappel du matin à 7 h et récapitulatif du lundi aux administrateurs et responsables)
Corps
simple:booleanreminders:boolean
Réponse
objectGET /api/sites/{id}/digest-preview — Récapitulatif du lundi tel qu'il partirait maintenant, groupé par urgence (en retard, cette semaine, plus tard) avec un lien par fiche : objet, texte, HTML, `empty` (rien à signaler : il ne partirait pas), `reminders`
Réponse
subject:stringbody:stringhtml:stringempty:booleanreminders:boolean
POST /api/lines — Créer une ligne de production (code unique dans l'usine)
Corps
LineInputRéponse
ProductionLinePATCH /api/lines/{id} — Modifier une ligne
Corps
LineInputRéponse
ProductionLineAgenda
GET /api/calendars — Agendas visibles : personnels du compte, d'usine et d'équipe des usines autorisées
Réponse
[Calendar]POST /api/calendars — Créer un agenda : personnel (tout compte, propriétaire), d'usine ou d'équipe (droit `plan`) ; fuseau de l'usine par défaut
Corps
kind* :personal|site|teamsite_id:stringteam_id:stringname* :stringtz:stringdefault_reminders: [integer]
Réponse
CalendarPATCH /api/calendars/{id} — Renommer, changer de fuseau, rappels par défaut, archiver (propriétaire, ou `plan` et usine)
Corps
name:stringtz:stringdefault_reminders: [integer]archived:boolean
Réponse
204 No ContentGET /api/calendar/occurrences — Occurrences de [from, to) (ms, 400 jours au plus) : événements visibles dépliés (répétition RFC 5545, exceptions, dérogations) et calques demandés (`layers` : work_orders, inspections, contracts, absences, on_call, preventive, qualifications, deliveries, activities, holidays, ou all). Un OT apparaît sur son jour sans heure ; un contrôle échu est « overdue » et son suivant projeté ; le motif d'une absence n'est donné qu'au droit `plan`. `no_holidays` : usines dont le pays n'a pas de fériés connus. Réponse `no-store`
Réponse
items: [Occurrence]more:booleanno_holidays: [string]
POST /api/calendar/preview — Aperçu sans enregistrement : dix premières occurrences, conflits, règle en phrase dans la langue de l'usine
Corps
EventInputRéponse
occurrences: [[integer]]conflicts: [Conflict]describe:string
POST /api/calendar/events — Créer un événement (`schedule` pour un agenda d'usine ou d'équipe, propriétaire pour un agenda personnel). La première occurrence doit suivre la règle. Conflits (absence, chevauchement, charge du jour au-delà de 7 h, machine prise par un OT programmé) : 409 `conflicts` avec leur liste, sauf `accept_conflicts` ; ils restent dans l'audit
Corps
EventInputRéponse
PATCH /api/calendar/events/{id} — Modifier (`scope` : all, this ou following, `occurrence` : clé « @2026-11-18T07:30 ») : une occurrence devient une dérogation ; « et les suivantes » coupe la série (COUNT partagé ou UNTIL une seconde avant, nouvel UID, `split_from`) ; un nouvel horaire de série emmène ses exceptions. 409 comme à la création
Corps
title:stringdescription:stringlocation:stringwhen:object— Horaire : {kind: timed, start: AAAA-MM-JJTHH:MM:SS (heure murale), tz: fuseau IANA, minutes} ou {kind: all_day, start: AAAA-MM-JJ, days}rule:stringattendees: [object]reminders: [integer]busy:booleanlinks: [object]cancelled:booleanaccept_conflicts:boolean
Réponse
conflicts: [Conflict]
POST /api/calendar/events/{id}/cancel — Annuler un événement (organisateur, ou droit d'écriture de l'agenda)
Réponse
204 No ContentPOST /api/calendar/events/{id}/rsvp — Réponse du compte invité
Corps
partstat* :accepted|declined|tentative|needs_action
Réponse
204 No ContentGET /api/calendar/events/{id}/event.ics — Fichier iCalendar (RFC 5545) d'un événement visible, série complète (`text/calendar`)
Réponse
204 No ContentGET /api/calendars/{id}/export.ics — Fichier iCalendar d'un agenda visible : ses événements, 30 jours en arrière et un an devant (`text/calendar`)
Réponse
204 No ContentGET /api/me/calendar-feeds — Flux d'agenda du compte ; `all=true` : ceux du tenant (`manage_users`)
Réponse
[id:stringuser_id:stringprefix:stringscope:objectcreated_at_ms:integer— Horodatage en millisecondes (epoch)last_fetched_ms:integer— Horodatage en millisecondes (epoch)revoked:boolean
POST /api/me/calendar-feeds — Créer un flux d'abonnement : calques, agendas (absent : tous ceux que le compte voit), « occupé seulement ». Le jeton `gmaocal_…` n'est rendu qu'une fois ; seule son empreinte est gardée
Corps
layers: [string]calendars: [string]busy_only:boolean
Réponse
feed:id:stringuser_id:stringprefix:stringscope:objectcreated_at_ms:integer— Horodatage en millisecondes (epoch)last_fetched_ms:integer— Horodatage en millisecondes (epoch)revoked:boolean
token:stringpath:string
DELETE /api/me/calendar-feeds/{id} — Révoquer un flux (le sien ; tout flux du tenant avec `manage_users`) : sa lecture répond 404
Réponse
204 No ContentGET /api/ical/{token}/agenda.ics — Lecture d'un flux par Outlook, Thunderbird ou un téléphone, sans session : droits **actuels** du compte recalculés à chaque appel (404 si le flux est révoqué ou le compte désactivé), `ETag` et 304, `Cache-Control: private, max-age=300`, 60 lectures par heure (429). Le jeton n'ouvre aucune autre route et n'apparaît pas dans la trace public
Réponse
204 No ContentCalculs
PUT /api/assets/{id}/specs — Caractéristiques de la plaque de l'équipement (droit implantation) : remplacent les précédentes ; 422 sur une clé inconnue ou une valeur hors bornes. Elles pré-remplissent les calculateurs
Corps
objectRéponse
204 No ContentPUT /api/parts/{id}/specs — Caractéristiques techniques de l'article (droit stock), par ex. un roulement : d, D, B, C, C0, f0
Corps
objectRéponse
204 No ContentGET /api/calc — Catalogue des calculateurs (tout compte connecté, commun à tous les tenants) : entrées (clé, unité, bornes comprises, défaut, choix, condition d'affichage), sorties (clé, unité, décimales), avertissements, refus, formule, référence, calcul de sécurité, suites possibles
Réponse
[object]POST /api/calc/{id} — Calcule sans rien enregistrer (tout compte connecté). Corps : les entrées `{clé: nombre | texte | booléen | liste}`, les absentes prennent leur défaut. 422 `out_of_range` avec `field`, `min`, `max` ; 404 sur un calculateur inconnu
Corps
objectRéponse
CalcOutcomePOST /api/work-orders/{id}/calculations — Joint un calcul à l'OT (rôle d'exécution, usine de l'OT) : le serveur refait le calcul avec sa version des formules, garde les entrées et les sorties, et avec `add_step` ajoute l'étape à cocher (clé `calc:<id>`, 50 étapes au plus) dans la langue de l'usine ; tracé dans le fil. 20 calculs au plus par OT. Idempotent par `client_ref`. 422 `calc_version` si la version diffère, `out_of_range` sur une entrée hors bornes, `closed` sur un OT clôturé
Corps
calc_id* :stringversion* :integerinputs* :objectadd_step:booleanclient_ref:string— Référence de l'appareil (UUID, 8 à 64 caractères [A-Za-z0-9_-]) : un envoi rejoué renvoie l'enregistrement déjà crééat:integer— Heure du geste (ms epoch), saisie hors ligne : 48 h au plus dans le passé ; un léger futur est ramené à l'heure du serveur. Absent : heure de réception
Réponse
CalcRecordStock
GET /api/parts/{id}/reorder — Point de commande proposé : sorties des 365 derniers jours (moyenne et écart type journaliers), délai moyen des commandes reçues (14 j par défaut), z 1,645 (2,326 pour une pièce critique) ; SS = z·σd·√L, PC = d·L + SS arrondi à l'unité. `min_qty` n'est pas modifié
Réponse
part_id:stringwindow_days:integerissued:numberdaily_demand:numberdemand_sd:numberlead_time_days:numberlead_time_measured:booleanz:numbersafety_stock:numberreorder_point:numbercurrent_min:number
POST /api/assets/{id}/bom/{part} — Ligne de nomenclature (qty = 0 la retire)
Corps
qty* :number
Réponse
204 No ContentPOST /api/work-orders/{id}/parts/{part} — Ajouter un besoin à l'OT : réservé (défaut ; 422 code shortage si le disponible ne suffit pas, avec la liste des manques « not enough stock: CODE missing 4 kg; … ») ou seulement prévu (`reserve: false`, pièce à approvisionner). Un kit est éclaté en ses composants. `unit` : unité de gestion, conditionnement (paquet) ou multiple usuel (g pour un article en kg)
Corps
qty* :numberunit:stringreserve:boolean
Réponse
204 No ContentDELETE /api/work-orders/{id}/parts/{part} — Libérer une réservation ou un besoin prévu (kit : tous ses composants) ; ce qui est déjà sorti reste imputé, la ligne est soldée
Réponse
204 No ContentPOST /api/work-orders/{id}/parts/{part}/issue — Sortir du stock sur l'OT : une partie (`qty`) ou tout le reste de la ligne ; un kit sort composant par composant, par différence de cumuls (n sorties d'un paquet = la sortie globale, au gramme près) ; au-delà du prévu, l'écart est gardé. `lot` : lot ou numéro de série tracé sur le mouvement ; `kit_id` : ligne d'un composant de kit. Saisie hors ligne : `at` (heure du geste) et `client_ref` (référence de l'appareil : la même sortie rejouée ne sort rien de plus)
Corps
qty:numberunit:stringlot:stringkit_id:stringat:integer— Heure du geste (ms epoch), saisie hors ligne : 48 h au plus dans le passé ; un léger futur est ramené à l'heure du serveur. Absent : heure de réceptionclient_ref:string— Référence de l'appareil (UUID, 8 à 64 caractères [A-Za-z0-9_-]) : un envoi rejoué renvoie l'enregistrement déjà créé
Réponse
204 No ContentPOST /api/work-orders/{id}/reserve — « Réserver » : tous les besoins prévus de l'OT, tout ou rien (422 avec la liste des manques)
Réponse
204 No ContentPOST /api/work-orders/{id}/issue — « Sortir les réservations » : tout le reste réservé de l'OT sort du stock, un mouvement par ligne
Réponse
204 No ContentGET /api/parts/{id}/explode — Besoins pour une quantité d'article (`qty`, `unit` en paramètres) : un kit est éclaté en ses composants, quantités exactes, disponible et manque de chacun
Réponse
ExplosionPOST /api/parts — Créer un article ou un kit (`components`, `kit_base`), avec un conditionnement facultatif (`pack`)
Corps
objectRéponse
PartPATCH /api/parts/{id} — Modifier un article (`components` absent : composition inchangée)
Corps
objectRéponse
204 No ContentPOST /api/parts/{id}/receive — Réception (coût moyen pondéré). `unit` : conditionnement ou multiple usuel, le coût unitaire est alors celui de cette unité ; `lot` tracé sur le mouvement. Refusée sur un kit (pas de stock propre)
Corps
qty* :numberunit:stringunit_cost:numberlot:stringnote:string
Réponse
204 No ContentPOST /api/parts/{id}/count — Inventaire
Corps
qty* :numbernote:string
Réponse
204 No ContentSécurité
PUT /api/assets/{id}/isolation-points — Procédure de consignation
Corps
[energy:stringlabel:string
Réponse
204 No ContentPUT /api/technicians/{id}/qualifications — Remplacer les habilitations d'un technicien (BR, BC, ATEX, CATEC, HAUTEUR) — contrôlées à l'affectation, au planning et à la consignation
Corps
[code* :BR|BC|ATEX|CATEC|HAUTEURobtained_at* :integer— Horodatage en millisecondes (epoch)expires_at* :integer— Horodatage en millisecondes (epoch)issuer:string
Réponse
204 No ContentPOST /api/work-orders/{id}/permits — Demander un permis de travail (hot_work, confined_space, height, atex) — exigé avant de démarrer selon les dangers de l'équipement
Corps
kind* :hot_work|confined_space|height|atexat:integer— Heure du geste (ms epoch), saisie hors ligne : 48 h au plus dans le passé ; un léger futur est ramené à l'heure du serveur. Absent : heure de réception
Réponse
204 No ContentPOST /api/work-orders/{id}/permits/{permit}/issue — Délivrer un permis (admin, responsable, qualité ; pas le demandeur) : toutes les précautions confirmées, 1 à 12 h
Corps
confirmed* : [string]hours* :integer
Réponse
204 No ContentPOST /api/work-orders/{id}/permits/{permit}/close — Clôturer un permis (les permis ouverts sont clôturés avec l'OT) ; `at` facultatif : la surveillance incendie part de l'heure du geste
Corps
at:integer— Heure du geste (ms epoch), saisie hors ligne : 48 h au plus dans le passé ; un léger futur est ramené à l'heure du serveur. Absent : heure de réception
Réponse
204 No ContentPOST /api/work-orders/{id}/permits/{permit}/fire-watch — Confirmer la fin de la surveillance incendie (1 h après la clôture d'un permis de feu) ; l'OT ne se clôture pas avant ; `at` facultatif, sans tolérance sur l'heure
Corps
at:integer— Heure du geste (ms epoch), saisie hors ligne : 48 h au plus dans le passé ; un léger futur est ramené à l'heure du serveur. Absent : heure de réception
Réponse
204 No ContentPOST /api/work-orders/{id}/lockout/{point}/{action} — Consigner (lock), vérifier (verify) ou déconsigner (unlock) un point. Corps facultatif : `at` (heure du geste, ordre de la procédure respecté, habilitation évaluée à cette heure), `energy` et `label` du point vu par le technicien — si la procédure a changé, 422 procedure_changed
Corps
at:integer— Heure du geste (ms epoch), saisie hors ligne : 48 h au plus dans le passé ; un léger futur est ramené à l'heure du serveur. Absent : heure de réceptionenergy:stringlabel:string
Réponse
204 No ContentPOST /api/work-orders/{id}/hygiene-release — Signer la levée d'hygiène (admin, responsable, qualité) : toujours par une autre personne que celle qui a clôturé ou pointé sur l'OT, quelle que soit la zone (422 sinon)
Corps
note:string
Réponse
204 No ContentInterventions
POST /api/work-orders — Créer une demande d'intervention (rejouée avec la même `client_ref` : même OT renvoyé)
Corps
asset_id* :stringtitle* :stringpriority* :stringclient_ref:string— Référence de l'appareil (UUID, 8 à 64 caractères [A-Za-z0-9_-]) : un envoi rejoué renvoie l'enregistrement déjà crééat:integer— Heure du geste (ms epoch), saisie hors ligne : 48 h au plus dans le passé ; un léger futur est ramené à l'heure du serveur. Absent : heure de réceptionmachine_stopped:boolean— La panne arrête la machine : elle passe « En panne » à l'heure du geste (`at`)
Réponse
WorkOrderPOST /api/work-orders/done — Intervention déjà faite, saisie après coup : OT créé clôturé, daté du travail (`done_at`, un an au plus dans le passé ; défaut : maintenant), avec son temps passé (1 à 1 440 min) ; codes de défaillance facultatifs (un correctif sans mode : mode lu dans la phrase, marqué `report.inferred`), un mode saisi doit convenir à la classe ; `technician_id` : le technicien de l'usine qui a fait le travail (défaut : la personne qui saisit)
Corps
asset_id* :stringkind:corrective|preventive|improvementtitle* :stringremedy:stringminutes* :integerdone_at:integer— Horodatage en millisecondes (epoch)downtime_minutes:integerfailure_mode: FailureModetechnician_id:string
Réponse
WorkOrderPATCH /api/work-orders/{id} — Modifier titre, priorité, état kanban, notes. `base_notes` : notes sur lesquelles la saisie a été faite ; si elles ont changé entre-temps, 422 (code notes_changed) au lieu d'écraser
Corps
title:stringpriority:stringkanban_state:stringnotes:stringbase_notes:string
Réponse
204 No ContentPUT /api/work-orders/{id}/checklist/{index} — Cocher ou décocher une case (idempotent ; refusé sur un OT clôturé). `failed` : true, étape faite et non conforme ; false, l'échec est retiré ; absent, seule la case change (la décocher retire aussi l'échec)
Corps
done* :booleanfailed:booleanat:integer— Heure du geste (ms epoch), saisie hors ligne : 48 h au plus dans le passé ; un léger futur est ramené à l'heure du serveur. Absent : heure de réception
Réponse
204 No ContentPOST /api/work-orders/{id}/checklist/{index}/escalate — « Réparation urgente » depuis une étape de checklist (rôle d'exécution) : l'étape passe faite et non conforme, un correctif priorité haute est créé au statut « Demande » sur le même équipement, titré du libellé de l'étape, lié dans les deux sens (`escalated_from`, `escalated_to`) et tracé dans les deux fils ; sans effet sur l'état de la machine. Idempotent : étape déjà escaladée ou même `client_ref` → même OT. 422 sur un OT clôturé (closed)
Corps
client_ref:string— Référence de l'appareil (UUID, 8 à 64 caractères [A-Za-z0-9_-]) : un envoi rejoué renvoie l'enregistrement déjà crééat:integer— Heure du geste (ms epoch), saisie hors ligne : 48 h au plus dans le passé ; un léger futur est ramené à l'heure du serveur. Absent : heure de réception
Réponse
WorkOrderPUT /api/work-orders/{id}/operations — Remplacer la gamme d'opérations (ordre de la liste). Une opération gardée (même `seq`) conserve son état ; sans `seq`, elle est numérotée à la dizaine suivante ; une opération qui a des temps passés ne peut pas être retirée (422). Changer le temps prévu ou le métier d'une opération, ou en retirer une, demande le droit de planifier (403 sinon) ; le fil trace « phase:minutes:métier » avant et après. L'avancement de l'OT suit le temps prévu des opérations faites
Corps
[seq:integertitle* :stringtrade* :mechanic|electrician|automationplanned_minutes:integer
Réponse
204 No ContentPOST /api/work-orders/{id}/children — Créer un sous-OT (arrêt technique, révision) : même usine, nature et échéance que le parent, validé d'office si le parent l'est ; équipement facultatif (celui du parent), gamme facultative (validée avant la création : un refus ne crée rien). Trois niveaux au plus. Le parent ne se clôture pas tant qu'un sous-OT est ouvert (422, code children_open)
Corps
title* :stringasset_id:stringtrade:mechanic|electrician|automationpriority:stringoperations: [title:stringtrade:stringplanned_minutes:integer
Réponse
WorkOrderGET /api/work-orders/{id}/rollup — Cumul de l'OT et de tout son arbre : sous-OT ouverts, avancement, temps prévu et passé, coût réel (main-d'œuvre, pièces sorties, sous-traitance) et engagé (pièces réservées)
Réponse
RollupGET /api/work-orders/windows — Dates au plus tôt / au plus tard des OT ouverts (query `site_id` facultatif) : depuis l'échéance et le temps prévu restant, appro au plus tard, pièces attendues et leur commande, attente appro et retard prévu
Réponse
[Window]GET /api/work-orders/{id}/window — Dates au plus tôt / au plus tard d'un OT (null s'il est clôturé)
Réponse
WindowPUT /api/work-orders/{id}/due — Échéance de l'OT (null : aucune) ; les sous-OT qui suivaient l'ancienne échéance suivent la nouvelle. Une commande passée avec une livraison annoncée après l'appro au plus tard d'un OT écrit une alerte (supply_late) dans son fil
Corps
due_at* :object
Réponse
204 No ContentGET /api/work-orders/{id}/analysis — Analyse prévu / réel de l'OT : main-d'œuvre par opération (minutes et coût), temps hors gamme, pièces prévues, réservées et consommées, sous-traitance (devis contre montant final), écarts
Réponse
AnalysisGET /api/work-orders/analysis — Analyse prévu / réel des OT actifs sur la période (créés avant sa fin, ouverts ou clôturés depuis son début) : totaux, main-d'œuvre par métier, une ligne par OT. Mêmes paramètres et droits que GET /api/reports ; seuls comptent les OT gardés en mémoire (ouverts et derniers clôturés de chaque usine)
Réponse
AnalysisSummaryPOST /api/work-orders/{id}/operations/{seq}/status — État d'une opération : todo, in_progress, done (faite : auteur et heure gardés). `at` : heure du geste (saisie hors ligne)
Corps
status* :todo|in_progress|doneat:integer— Heure du geste (ms epoch), saisie hors ligne : 48 h au plus dans le passé ; un léger futur est ramené à l'heure du serveur. Absent : heure de réception
Réponse
204 No ContentPOST /api/work-orders/{id}/timer/start — Démarrer le minuteur, éventuellement sur une opération de la gamme (`operation` : son numéro, qui passe en cours). Corps facultatif `at` (saisie hors ligne) : pas avant la vérification de la consignation, le dernier changement d'étape ni la fin du temps précédent de la personne ; rejouer le même geste est sans effet
Corps
at:integer— Heure du geste (ms epoch), saisie hors ligne : 48 h au plus dans le passé ; un léger futur est ramené à l'heure du serveur. Absent : heure de réceptionoperation:integer
Réponse
204 No ContentPOST /api/work-orders/{id}/timer/stop — Arrêter le minuteur (corps facultatif `at`, pas avant le démarrage ; rejeu sans effet)
Corps
at:integer— Heure du geste (ms epoch), saisie hors ligne : 48 h au plus dans le passé ; un léger futur est ramené à l'heure du serveur. Absent : heure de réception
Réponse
204 No ContentPOST /api/work-orders/{id}/transition — Changer d'étape. « in_progress » exige, comme le démarrage du minuteur, une consignation vérifiée de chaque point d'isolement (422 lockout) et des permis valables (422 permit). « done » est toujours refusé (422 close_with_report, ou hygiene_checks en zone d'hygiène) : un OT se clôture par POST /close, qui contrôle compte rendu, codes, déconsignation, signature et surveillance incendie
Corps
status* :stringassignee_id:string
Réponse
204 No ContentPOST /api/work-orders/{id}/cancel — Annuler l'OT, ou refuser la demande s'il n'est pas validé (droit plan) : doublon (`duplicate_of`, un OT de la même usine), fausse alerte, plus nécessaire, ou autre motif écrit (422 note_required). Le technicien, les réservations et l'arrêt déclaré sont libérés ; l'OT n'entre pas dans les rapports ; le demandeur est prévenu. Refusé sous consignation (lockout_active), avec un permis délivré (permit_open) ou un sous-OT ouvert (children_open)
Corps
reason* :duplicate|false_alarm|not_needed|othernote:stringduplicate_of:string
Réponse
204 No ContentGET /api/work-orders/{id}/suggested-codes — Codes proposés à la clôture de l'OT : modes admis pour la classe, codes fréquents (appris des seules usines autorisées), détection déduite, codes hérités d'une réparation temporaire
Réponse
CodesPOST /api/work-orders/{id}/close — Clôturer avec compte rendu. Correctif : mode de défaillance admis pour la classe de l'équipement et cause obligatoires (422 sinon) ; mécanisme et activité complétés par le serveur ; détection enregistrée si saisie ou déductible de l'origine. Réparation définitive : codes repris de l'OT d'origine. Préventif : codes facultatifs. Sécurité : sur un équipement à points d'isolement, chaque point a été condamné puis vérifié (422 lockout_missing) et levé (422 lockout_active) ; chaque permis exigé par les dangers a été délivré à l'heure du geste (422 permit). Parent : tous ses sous-OT clôturés (422 children_open). `at` : heure du geste (saisie hors ligne) pour le compte rendu, l'historique et l'arrêt des minuteurs ; rejeu par le même auteur sans effet, sinon 422 closed. `amended` : clôture refusée puis complétée sur l'appareil, la signature et les contrôles d'hygiène prennent l'heure de réception
Corps
at:integer— Heure du geste (ms epoch), saisie hors ligne : 48 h au plus dans le passé ; un léger futur est ramené à l'heure du serveur. Absent : heure de réceptionamended:boolean— Clôture complétée après un refus : signature et contrôles d'hygiène horodatés à la réceptionproblem:stringcause:stringremedy* :stringfailure_mode: FailureModedowntime_minutes:['integer', 'null']— Arrêt de production déclaré, en minutes. Absent ou null : la part de l'arrêt mesuré imputée à l'OT (panne déclarée « machine arrêtée ») est reprise ; 0 : la machine n'a pas été arrêtéehygiene:objecttemporary_days:integermechanism:string— Tableau B.2 ; par défaut, le mécanisme type du modecause_code:string— Tableau B.3 ; obligatoire sur un correctifactivity:string— Tableau B.5 ; par défaut, l'activité type du modedetection: DetectionMethodsignature:signer* :stringimage* :string— data:image/png;base64,… (60 000 caractères au plus) ; obligatoire si l'OT est sous-traité
Réponse
204 No ContentPOST /api/work-orders/{id}/schedule — Planifier l'OT (technicien et jour, sans le lancer)
Corps
technician_id:stringat:integer— Horodatage en millisecondes (epoch)
Réponse
204 No ContentGET /api/assets/{id}/report-suggestions — Descriptions proposées en puces pour signaler une panne (6 au plus) : pannes déclarées sur la même classe d'équipement (hors préventif, réparation définitive, sous-OT, réparation urgente et réserve de contrôle), dans les usines autorisées de même langue que celle de l'équipement, normalisées (casse, accents, espaces, ponctuation finale) et comptées, puis symptômes types de la classe dans la langue de l'usine. Rôle déclarant (pas « external »)
Réponse
suggestions: [ReportSuggestion]
GET /api/assets/{id}/suggested-codes — Codes ISO 14224 les plus fréquents de l'équipement (mode admis pour la classe, mécanisme, cause, activité), appris des seules usines autorisées
Réponse
CodesPOST /api/micro-stops — Déclarer un micro-arrêt (refusé pendant un arrêt déclaré : déjà compté avec la panne)
Corps
asset_id* :stringminutes* :integerreason* :stringclient_ref:string— Référence de l'appareil (UUID, 8 à 64 caractères [A-Za-z0-9_-]) : un envoi rejoué renvoie l'enregistrement déjà crééat:integer— Heure du geste (ms epoch), saisie hors ligne : 48 h au plus dans le passé ; un léger futur est ramené à l'heure du serveur. Absent : heure de réception
Réponse
objectÉquipe
POST /api/technicians — Créer la fiche d'un technicien (droit plan) : nom unique dans l'entreprise (422 name_taken), usine, métier, coût horaire chargé (défaut : celui du métier). Il rejoint l'équipe de son métier
Corps
site_id* :stringname* :stringtrade* :mechanic|electrician|automationhourly_rate:number
Réponse
objectPATCH /api/technicians/{id} — Corriger un technicien, le changer d'usine, le faire partir (`active: false`) ou revenir. Parti : plus affecté (422 tech_left), planifié ni d'astreinte, ses absences à venir tombent. Changement d'usine et départ refusés tant qu'il a des OT ouverts (422 tech_has_work)
Corps
name:stringtrade:mechanic|electrician|automationhourly_rate:numbersite_id:stringactive:boolean
Réponse
204 No ContentIoT
POST /api/ingest/readings — Relevés capteurs poussés par une passerelle (clé d'API, droit exécuter) : chaque tag est rattaché à un point de mesure ; filtrage par zone morte et intervalle minimal, seuils toujours évalués, OT conditionnel si dépassement. Réponse : relevés enregistrés, filtrés, tags inconnus, OT ouverts
Corps
samples* : [tag* :stringvalue* :numberat:integer— Horodatage en millisecondes (epoch)
Réponse
objectPréventif
POST /api/points — Créer un point de mesure (maintenance conditionnelle) : équipement, nom, unité, seuil bas et/ou haut, tag capteur
Corps
asset_id* :stringname* :stringunit:stringlow:numberhigh:numbertag:stringvibration:object— Classe vibratoire ISO 20816-3 de la machine (point en « mm/s » seulement, sinon 422) ; à la modification, absent : inchangée, null : retirée ; un changement d'unité la retire
Réponse
objectPATCH /api/points/{id} — Modifier un point de mesure (mêmes champs qu'à la création, `vibration` comprise)
Corps
asset_id* :stringname* :stringunit:stringlow:numberhigh:numbertag:stringactive:booleanvibration:object— Classe vibratoire ISO 20816-3 de la machine (point en « mm/s » seulement, sinon 422) ; à la modification, absent : inchangée, null : retirée ; un changement d'unité la retire
Réponse
204 No ContentPOST /api/points/{id}/readings — Saisir un relevé ; hors seuil, un OT préventif conditionnel est ouvert (un seul à la fois par point). `at` : relevé saisi hors ligne, replacé dans le temps
Corps
value* :numberat:integer— Heure du geste (ms epoch), saisie hors ligne : 48 h au plus dans le passé ; un léger futur est ramené à l'heure du serveur. Absent : heure de réception
Réponse
204 No ContentPOST /api/plans — Créer des plans préventifs (plusieurs équipements). `operations` : gamme type recopiée dans chaque OT généré (phases 10, 20, 30…)
Corps
asset_ids* : [string]title* :stringinterval_hours:numberinterval_days:integerinstructions:stringchecklist: [string]operations: [OperationTemplate]
Réponse
[object]PATCH /api/plans/{id} — Modifier un plan (`operations` absent : gamme inchangée)
Corps
title:stringinterval_hours:numberinterval_days:integerinstructions:stringchecklist: [string]active:booleanoperations: [OperationTemplate]
Réponse
204 No ContentPOST /api/plans/{id}/generate — Générer l'OT d'un plan
Réponse
WorkOrderPlanning
POST /api/roster — Déclarer une absence (leave, sick, training) ou une astreinte (on_call) — sans chevauchement ; un absent n'est ni affecté ni planifié
Corps
technician_id* :stringkind* :leave|sick|training|on_callstart* :integer— Horodatage en millisecondes (epoch)end* :integer— Horodatage en millisecondes (epoch)note:string
Réponse
objectPOST /api/roster/{id}/cancel — Annuler une absence ou une astreinte
Réponse
204 No ContentContrats
POST /api/work-orders/{id}/subcontract — Confier l'OT à un prestataire. `cost` : montant facturé ; `quote` : devis (coût prévu de l'analyse), modifiable tant que l'OT est ouvert — absent : inchangé (aucun pour un nouveau prestataire), `null` : retiré
Corps
vendor_id:stringcost:numberquote:['number', 'null']
Réponse
204 No ContentPOST /api/vendors — Créer un prestataire
Corps
objectRéponse
VendorPATCH /api/vendors/{id} — Modifier un prestataire
Corps
objectRéponse
204 No ContentPOST /api/contracts — Créer un contrat
Corps
objectRéponse
ContractPATCH /api/contracts/{id} — Modifier un contrat
Corps
objectRéponse
204 No ContentAchats
POST /api/purchases — Demande d'achat
Corps
site_id* :stringsupplier:stringlines* : [part_id:stringqty:numberunit_cost:number
work_order_id:stringnote:string
Réponse
PurchasePOST /api/purchases/reorder — Réapprovisionnement automatique d'une usine
Corps
site_id* :string
Réponse
[Purchase]POST /api/purchases/{id}/lines/{part} — Ligne d'un brouillon
Corps
qty:numberunit_cost:number
Réponse
204 No ContentPOST /api/purchases/{id}/order — Passer la commande
Corps
supplier:stringexpected_at:integer— Horodatage en millisecondes (epoch)
Réponse
204 No ContentPOST /api/purchases/{id}/receive — Réceptionner une livraison
Corps
[part_id:stringqty:number
Réponse
204 No ContentPOST /api/purchases/{id}/cancel — Annuler
Réponse
204 No ContentContrôles
POST /api/inspections — Créer un contrôle réglementaire / étalonnage
Corps
objectRéponse
InspectionGET /api/inspections/library — Bibliothèque des contrôles usuels d'un atelier en France (VGP chariots et levage, presses, équipements sous pression, électricité, extincteurs, portes, ventilation, fluides frigorigènes, arrêts d'urgence) : classes concernées, périodicité, texte de référence indicatif, classes cochées d'office (`primary`) et mots du nom qui le font cocher (`keywords`)
Réponse
[code:stringasset_kinds: [string]kind:stringtitle:stringreference:stringbody:stringinterval_days:integernote:stringprimary: [string]keywords: [string]
POST /api/inspections/library — Responsable : pose des contrôles de la bibliothèque. `last_at` (date du dernier contrôle) fixe la prochaine échéance ; inconnue, échéance dans 30 jours. Un contrôle déjà suivi (même intitulé, actif) n'est pas doublé ; un code inconnu ou un contrôle qui ne convient pas à la classe refuse tout le lot (2 000 au plus)
Corps
items* : [code* :stringasset_id* :stringlast_at:integer— Horodatage en millisecondes (epoch)
Réponse
created:integerskipped:integer
PATCH /api/inspections/{id} — Modifier un contrôle
Corps
objectRéponse
204 No ContentPOST /api/inspections/{id}/results — Saisir un résultat (réserves → OT de levée)
Corps
result* :compliant|reserves|non_compliantinspector:stringcertificate:stringnote:stringat:integer— Horodatage en millisecondes (epoch)
Réponse
204 No ContentCollaboration
POST /api/threads/{model}/{id}/messages — Message ou note interne
Corps
body* :stringkind:stringclient_ref:string— Référence de l'appareil (UUID, 8 à 64 caractères [A-Za-z0-9_-]) : un envoi rejoué renvoie l'enregistrement déjà crééat:integer— Heure du geste (ms epoch), saisie hors ligne : 48 h au plus dans le passé ; un léger futur est ramené à l'heure du serveur. Absent : heure de réception
Réponse
objectPOST /api/activities — Planifier une activité
Corps
objectRéponse
objectGET /api/attachments/{model}/{id} — Pièces jointes d'un enregistrement (`work_order`, `asset`, `inspection`) ; un compte limité à ses usines ne voit que celles de ses usines, même pour une fiche qui n'est plus en mémoire
Réponse
[object]POST /api/attachments/{model}/{id} — Ajouter une photo ou un document (corps brut, en-têtes `content-type` et `x-filename`) à un OT, un équipement ou un contrôle (le PV de l'organisme, droit de planifier ; cité dans le dossier d'audit). Photo prise hors ligne : `client_id` (att-<référence>, un envoi rejoué renvoie la même pièce) et `at` (heure de la prise de vue) en paramètres
Réponse
objectRapports
GET /api/reports — Rapport de maintenance sur tout l'historique (EN 15341) : disponibilité R1, MTBF, MTTR, taux de codification ISO 14224 (correctifs clôturés avec mode et cause), part du préventif, conformité, backlog, coûts, Pareto, tendance et comparatif entre usines. Une réparation définitive n'est pas une nouvelle défaillance (ni dans le compte, ni dans le Pareto). Rôles admin, manager, qualité ; usines autorisées seulement
Réponse
ReportGET /api/export/reports.csv — Une table du rapport en CSV (UTF-8 avec BOM, clés anglaises) : table=indicators|assets|series|sites. Les cellules texte qui commencent par = + - @ sont préfixées d'une apostrophe
Réponse
204 No ContentGET /api/export/reports.xlsx — Rapport en classeur Excel : Indicateurs (avec formules), Équipements, Tendance, Usines en vue réseau
Réponse
204 No ContentAdministration
GET /api/audit — Journal d'audit
Réponse
[object]GET /api/notifications — E-mails envoyés aux demandeurs
Réponse
[object]Intégrations
GET /api/api-keys — Clés d'API (administrateur)
Réponse
[object]POST /api/api-keys — Créer une clé (le jeton n'est affiché qu'une fois)
Corps
name* :stringuser_email* :string
Réponse
key:objecttoken:string
DELETE /api/api-keys/{id} — Révoquer une clé
Réponse
204 No ContentGET /api/webhooks — Webhooks
Réponse
[object]POST /api/webhooks — Créer un webhook (le secret n'est affiché qu'une fois)
Corps
url* :stringevents: [string]
Réponse
webhook:objectsecret:string
PATCH /api/webhooks/{id} — Modifier un webhook
Corps
url:stringevents: [string]active:boolean
Réponse
204 No ContentDELETE /api/webhooks/{id} — Supprimer un webhook
Réponse
204 No ContentPOST /api/webhooks/{id}/ping — Envoyer un événement de test
Réponse
204 No ContentGET /api/webhooks/deliveries — Dernières livraisons
Réponse
[object]Portail public
GET /api/public/{tenant}/assets/{token} — Équipement scanné (QR), sans compte : OT ouverts et descriptions fréquentes de sa classe (apprises de sa seule usine) public
Réponse
PublicAssetPOST /api/public/{tenant}/assets/{token}/requests — Demande sans compte (5 / 10 min) ; `machine_stopped` : la machine passe « En panne » aussitôt public
Corps
title* :stringrequester* :stringurgent:booleanemail:stringmachine_stopped:boolean
Réponse
code:stringreference:string
GET /api/public/{tenant}/requests/{reference} — Suivi d'une demande (aussi pour un OT clos qui n'est plus en mémoire) public
Réponse
PublicTrackingPOST /api/public/{tenant}/requests/{reference}/followups — Relancer une demande ouverte depuis le lien de suivi : 3 relances au plus, une heure après la demande puis après la relance précédente (422 followup_too_soon, followup_limit ; closed si la demande est close). Message facultatif de 300 caractères, tracé dans le fil de l'OT au nom du demandeur, diffusé (écart « relancée » dans le jumeau et la cloche) et envoyé par e-mail aux comptes responsables qui voient l'usine (lien vers la fiche de l'OT). 5 appels / 10 min par référence (429) public
Corps
message:string
Réponse
204 No ContentPOST /api/public/{tenant}/requests/{reference}/rating — Noter la réponse à une demande close : une note de 1 à 5, une seule fois (rating_done), dans les 30 jours après la clôture (rating_expired), avant la clôture refusée (rating_open) ; commentaire facultatif de 500 caractères, gardé sur l'OT seul. Une demande close sortie de la mémoire est notée en base d'un seul geste (deux appels simultanés : une seule note). Comptée au taux de satisfaction de l'usine (rapports). 5 appels / 10 min par référence (429) public
Corps
score* :integercomment:string
Réponse
204 No ContentLanding
POST /api/public/demo-requests — Demande de présentation déposée sur la landing commerciale, sans compte : 201 et sa référence (`DP-` suivi de 10 caractères), seule donnée écrite dans les journaux. Globale à la plateforme (aucun tenant). 422 : un code stable par champ. 5 demandes par adresse e-mail et 30 pour toute la plateforme par tranche de 10 minutes (429 rate_limited). Champ piège `website` rempli : réponse 201 ordinaire, rien n'est gardé ni compté. Si `DEMO_REQUESTS_TO` et `SMTP_URL` sont définis, l'équipe reçoit un e-mail en texte public
Corps
DemoRequestInputRéponse
reference* :string
POST /api/public/unsubscribe — Lien personnel de désabonnement d'un mail de rappel (`/desabonnement#gmaounsub_…`, en-tête List-Unsubscribe) : coupe les rappels de cette personne seulement. 410 si le lien est falsifié ; limite par adresse IP public
Corps
token* :string
Réponse
email:stringname:string
POST /api/public/signup — Essai gratuit de 30 jours sans rendez-vous (`SIGNUP=on` et SMTP configuré, sinon 404) : rien n'est créé tant que l'adresse n'est pas vérifiée ; un lien d'activation de 7 jours (`/acces#gmaotrial_…`) part à l'adresse, l'espace s'ouvre au choix du mot de passe (`/api/auth/reset`) et l'équipe commerciale est prévenue (`DEMO_REQUESTS_TO`). Toujours 202, que l'adresse ait déjà un compte ou non ; champ piège `website` ; limite par adresse IP (429). À la fin de l'essai, le compte passe en lecture seule (402 `trial_ended` sur toute écriture ; consultation et export restent ouverts) ; sans souscription, il est effacé 90 jours après la fin de l'essai, au plus tôt 7 jours après l'avertissement des administrateurs. Trois liens d'activation par adresse et par jour au plus ; nom et entreprise sans caractère de contrôle (422) public
Corps
company* :stringname* :stringemail* :stringphone:stringlocale:stringwebsite:string
Réponse
204 No ContentÉditeur
GET /api/platform/tenants — Clients de l'instance (usines, comptes). Jeton de l'éditeur `PLATFORM_TOKEN` en `Authorization: Bearer` ; sans PLATFORM_TOKEN configuré, la route n'existe pas (404)
Réponse
[id:stringname:stringsites:integerusers:integer
POST /api/platform/tenants — Créer un client sans redémarrer : tenant vide (identifiant de 3 à 40 caractères a-z, 0-9 et tirets) et son premier administrateur, invité : il choisit son mot de passe par un lien de 7 jours, envoyé par e-mail et rendu une seule fois. 409 si l'identifiant ou l'adresse existe
Corps
id* :stringname* :stringadmin_email* :stringadmin_name* :stringlocale:string
Réponse
tenant:id:stringname:string
admin:id:stringemail:stringinvite:object
PATCH /api/platform/tenants/{id}/trial — Prolonger l'essai d'un client (`trial_ends_at` en ms) ou le passer sous contrat (`null`). 404 si le client n'existe plus (essai effacé entre-temps)
Corps
trial_ends_at:object
Réponse
204 No ContentSchémas
Error
error* :stringcode* :string— Code stable du refus (closed, children_open, too_old, clock, permit, lockout, lockout_active, lockout_missing (clôture d'un OT jamais consigné ni vérifié), qualification, procedure_changed, notes_changed, fire_watch, order, timer_running, no_timer, not_planned, codes (mode ou cause de défaillance manquant), mode_class (mode non admis pour la classe de l'équipement), hygiene_checks, signature, close_with_report, machine_stopped (micro-arrêt pendant un arrêt déjà compté), not_stopped (remise en service d'une machine non arrêtée), in_progress (remise en service pendant une intervention), hygiene_pending (remise en service avant la levée d'hygiène), shortage, nothing_planned, nothing_to_issue, tech_busy, tech_absent, no_technician (affectation : technicien occupé, absent, aucun de libre), followup_limit, followup_too_soon, rating_open, rating_done, rating_expired (portail QR : relance et note), escalated (étape déjà escaladée dont la réparation n'est plus en mémoire), calc_version (calcul joint fait avec une autre version des formules), out_of_range (entrée de calcul hors bornes : `field`, `min`, `max`), rate_limited, not_found, forbidden, invalid, too_large, rejected…). shortage : `error` liste les manques « not enough stock: CODE missing 4 kg; … »
FailureMode
breakdown | leak | noise | overheating | electrical | sensor | blockage | wear | adjustment | otherDetectionMethod
periodic_maintenance | functional_test | inspection | periodic_condition_monitoring | continuous_condition_monitoring | production_interference | casual_observation | corrective_maintenance | on_demand | otherCodes
failure_mode: FailureModemechanism:string— Mécanisme ISO 14224 (tableau B.2)cause:string— Cause ISO 14224 (tableau B.3)activity:string— Activité ISO 14224 (tableau B.5)detection:object— Déduite de l'origine de l'OT (réserve de contrôle, mesure, portail QR, panne, plan), jamais d'une fréquence ; null si inconnueinherited:boolean— Réparation définitive : codes complets repris de la réparation temporaireallowed_modes: [FailureMode] — Modes admis pour la classe de l'équipement, du plus au moins probabletypical:object— Par mode admis : mécanisme et activité complétés par le serveur à la clôture
WorkOrder
id:stringcode:stringsite_id:stringasset_id:stringkind:stringpriority:low|medium|high|criticalstatus:requested|approved|planned|in_progress|donetitle:stringrequested_by:stringassignee_id:stringhistory: [status:stringat:integer— Horodatage en millisecondes (epoch)
report:objectparts: [PartUse]operations: [Operation]parent_id:['string', 'null']— OT parent (arborescence)kits: [kit_id:stringqty:number— Kits prévus ou réservés (cumul, unité de gestion du kit)issued:number— Kits sortis (cumul) : chaque sortie déstocke la différence entre deux cumuls de composants
time_entries: [who:stringstarted_at:integer— Horodatage en millisecondes (epoch)ended_at:integer— Horodatage en millisecondes (epoch)operation:integer— Numéro de l'opération visée (facultatif)
subcontract:objectlockout:objecthygiene:objectpermits: [object]checklist: [ChecklistItem]escalated_from:object— Réparation urgente créée depuis une étape de checklist en échec : OT et rang de l'étape (0 pour la première)followups: [integer] — Relances du demandeur sans compte (portail QR), heure de chacune ; absent si aucunecalculations: [CalcRecord] — Calculs joints (20 au plus), recalculés par le serveur ; absent si aucunsatisfaction:object— Note du demandeur sans compte, donnée après la clôture (absente sinon)stop:object— Panne déclarée « machine arrêtée » : l'OT tient la machine « En panne » tant qu'il est ouvert et que `until` est null. `minutes` : part de l'arrêt de la machine imputée à cet OT. Les arrêts des OT d'une machine qui se chevauchent forment un seul arrêt, mesuré une fois ; sa durée va à l'OT qui le termine (ou à l'ouvreur en cas de remise en service), moins ce que les autres OT en comptent déjà. Reprise au compte rendu si la clôture ne déclare pas d'arrêt
ChecklistItem
label* :stringdone* :booleanfailed:boolean— Étape faite mais non conforme (absent : conforme)escalated_to:['string', 'null']— Réparation urgente créée depuis l'étapekey:string— Clé stable de l'étape (`calc:<id>` pour l'étape d'un calcul joint) ; absente sinon
CalcRecord
id* :stringcalc_id* :stringversion* :integerinputs* :object— Entrées retenues (seules les clés du catalogue)values* : [[object]] — Sorties recalculées par le serveur, [clé, valeur] dans l'ordre du cataloguewarnings* : [string]step:string— Libellé de l'étape créée, dans la langue de l'usine (absent sans étape)by* :stringat* :integer— Horodatage en millisecondes (epoch)client_ref:string
CalcOutcome
id:stringversion:integervalues:object— Sorties, dans l'ordre du cataloguewarnings: [string]steps: [key:stringvalue:numberunit:string
ReportSuggestion
text* :stringcount* :integer— Pannes passées qui ont employé cette description (0 : symptôme du catalogue de la classe)
PublicAsset
code:stringname:stringsite:stringlocale:stringopen_requests: [string]suggestions: [string] — Descriptions fréquentes pour la classe de l'équipement (6 au plus), apprises de sa seule usine, dans sa langue
PublicTracking
code:stringtitle:stringasset:stringstatus:stringhistory: [status:stringat:integer— Horodatage en millisecondes (epoch)
remedy:['string', 'null']followups:integer— Relances déjà faitesfollowups_left:integer— Relances restantes (0 si la demande est close)next_followup_at:object— Heure à partir de laquelle une relance est admise (null : plus de relance possible)can_rate:boolean— Demande close, pas encore notée, dans les 30 joursrating:['integer', 'null']— Note déjà donnée (1 à 5)
Asset
id:stringsite_id:stringline_id:stringcode:stringname:stringkind:stringstatus:running|idle|degraded|down|maintenance— Déduit des faits : « maintenance » (intervention démarrée, machine consignée pour un OT ouvert ou levée d'hygiène en attente) > « down » (un OT ouvert tient la machine arrêtée) > « degraded » (point de mesure en alarme ou OT conditionnel ouvert) > « running ». Chaque changement est diffusé sur /api/live (restreint aux usines du compte). Il est journalisé (`asset.status`) quand il vient d'une commande, du portail QR, de l'IoT (acteur : « IoT » pour MQTT et OPC UA, « <compte> (IoT) » pour HTTP) ou du démarrage ; les pas du simulateur (démo) ne sont pas journalisésstopped_since:object— Début de l'arrêt en cours (null : machine non arrêtée)restarted_at:object— Fin du dernier arrêt (clôture ou remise en service)unassigned_requests:integer— OT « Demande » sans technicien (ni affecté ni planifié) : signe distinct, sans effet sur l'étatspecs:object— Caractéristiques (clés fermées de calc::specs : power_kw, speed_rpm, voltage_v, current_a, cos_phi, efficiency, poles, frequency_hz, ratio, bore_mm, rod_mm, flow_m3h, head_m, rotor_mass_kg, bearing_d_mm, bearing_od_mm, bearing_width_mm, bearing_c_kn, bearing_c0_kn, bearing_f0), bornées ; absent si videcriticality:A|B|Chealth:numberoee:numbermtbf_hours:numbermttr_minutes:numberbom: [part_id:stringqty:number
isolation_points: [IsolationPoint]hazards: [atex|confined_space|height]model3d:object— Modèle 3D propre (null : modèle procédural du type)
IsolationPoint
id:stringenergy:electrical|pneumatic|hydraulic|mechanical|thermal|chemicallabel:stringanchor:object— [x, y, z] en m dans le repère du modèle 3D, ou null
ModelPart
shape* :box|cylinder|sphere|lathesize: [number] — box : [largeur x, hauteur y, profondeur z] en mradius:number— box : rayon des arêtes (facultatif) ; cylinder : rayon du bas ; sphere : rayonradius_top:number— cylinder : rayon du haut (facultatif, = radius)height:number— cylinder : hauteur selon y localprofile: [[number]] — lathe : 2 à 32 points [rayon, y], révolution autour de y, origine en `at`at* : [number] — Centre de la pièce (lathe : origine du profil), en mrotation: [number] — Euler XYZ en radians (0 par défaut)color* :string— body | body_alt | steel | dark | accent | glass | glow | warning | wood | cardboard | #rrggbbpart:string— Sous-ensemble maintenable (motor, gearbox, hmi…), 40 caractères max
Recipe
name* :stringparts* : [ModelPart]
AssetModel
objectModelResult
asset_ids* : [string]model* :object
AnchorsInput
isolation:object— id du point d'isolement → [x, y, z] ou nullpoints:object— id du point de mesure → [x, y, z] ou null
Calendar
id:stringkind:personal|site|teamsite_id:stringowner_user_id:stringteam_id:stringname:stringtz:stringdefault_reminders: [integer]archived:boolean
EventInput
calendar_id* :stringtitle* :stringdescription:stringlocation:stringwhen* :object— Horaire : {kind: timed, start: AAAA-MM-JJTHH:MM:SS (heure murale), tz: fuseau IANA, minutes} ou {kind: all_day, start: AAAA-MM-JJ, days}rule:string— RRULE RFC 5545, sous-ensemble : FREQ DAILY à YEARLY, INTERVAL, COUNT ou UNTIL, BYDAY (rang en mensuel, en annuel avec BYMONTH), BYMONTHDAY, BYMONTH, WKST ; toute autre partie refusée avec son nom (422)exdates: [string]rdates: [string]attendees: [technician_id:stringuser_id:stringname:string
reminders: [integer]busy:booleanlinks: [kind:asset|work_orderid:string
accept_conflicts:boolean
Event
id:stringuid:stringcalendar_id:stringsite_id:stringsequence:integerstatus:confirmed|tentative|cancelledtitle:stringwhen:object— Horaire : {kind: timed, start: AAAA-MM-JJTHH:MM:SS (heure murale), tz: fuseau IANA, minutes} ou {kind: all_day, start: AAAA-MM-JJ, days}rule:stringexdates: [string]rdates: [string]overrides:objectorganizer:stringattendees: [object]reminders: [integer]busy:booleanlinks: [object]split_from:stringcreated_at:integer— Horodatage en millisecondes (epoch)updated_at:integer— Horodatage en millisecondes (epoch)
Occurrence
key:stringsource:stringrecord_id:stringcalendar_id:stringsite_id:stringtitle:stringstart:integer— Horodatage en millisecondes (epoch)end:integer— Horodatage en millisecondes (epoch)all_day:booleanlocal_date:stringtz:stringrecurring:booleanforecast:booleandeviation:overdue|movedmy_partstat:string
Conflict
kind:absent|overlap|overload|asset_busytechnician_id:stringstart:integer— Horodatage en millisecondes (epoch)reason:stringevent_id:stringdate:stringhours:numbercapacity:numberasset_id:stringwork_order_id:string
Part
id:stringsite_id:stringcode:stringname:stringunit:string— Unité de gestion (u, kg, g, L, m, paquet…)unit_cost:numberon_hand:numbermin_qty:numbermax_qty:numberlocation:stringsupplier:stringcritical:booleanlast_move_at:integer— Horodatage en millisecondes (epoch)specs:object— Caractéristiques (clés fermées de calc::specs : power_kw, speed_rpm, voltage_v, current_a, cos_phi, efficiency, poles, frequency_hz, ratio, bore_mm, rod_mm, flow_m3h, head_m, rotor_mass_kg, bearing_d_mm, bearing_od_mm, bearing_width_mm, bearing_c_kn, bearing_c0_kn, bearing_f0), bornées ; absent si videpack:object— Conditionnement d'achat ou de sortie : 1 `unit` = `factor` unités de gestion (1 paquet = 25 u) ; null : aucuncomponents: [part_id* :stringqty* :number
kit_base:number— Quantité de kit (unité de gestion) pour laquelle la composition est donnée (1 990 paquets de 25 = 49 750 u)
Operation
seq:integer— Numéro de phase (10, 20, 30…), identifiant stable dans l'OTtitle:stringtrade:mechanic|electrician|automationplanned_minutes:integerstatus:todo|in_progress|donedone_by:['string', 'null']done_at:integer— Horodatage en millisecondes (epoch)
OperationTemplate
title* :stringtrade* :mechanic|electrician|automationplanned_minutes:integer
Rollup
work_order_id:stringchildren:integer— Sous-OT de tous niveauxopen_children:integerprogress:number— Avancement de l'arbre pondéré par la charge prévue, en %planned_minutes:numberactual_minutes:numbercost:labor:numberparts:number— Pièces sorties (coût figé)external:numbertotal:number— Coût réel : main-d'œuvre + pièces sorties + sous-traitancecommitted:number— Engagé : pièces réservées pas encore sorties (hors total)
Window
work_order_id:stringremaining_minutes:integer— Temps prévu restant (opérations pas encore faites), en minutes ; durées mises bout à bout en temps continuearliest_start:integer— Début au plus tôt : maintenant (ou le démarrage réel), décalé par l'arrivée annoncée des pièces attenduesearliest_finish:integer— Fin au plus tôt (un parent ne finit pas avant ses sous-OT)latest_finish:object— Fin au plus tard : échéance de l'OT, sinon celle de son parentlatest_start:object— Début au plus tard : fin au plus tard − temps restantsupply_by:object— Appro au plus tard (= début au plus tard)supply_at:object— Arrivée annoncée de la dernière pièce attenduesupply: SupplyStateslack_minutes:['integer', 'null']— Marge : fin au plus tard − fin au plus tôt (négative : retard prévu)late:booleanheld_by:['string', 'null']— Sous-OT qui repousse la fin au plus tôt (il finit après le travail propre de l'OT)awaited: [part_id:stringcode:stringname:stringunit:stringqty:numberavailable:numberpurchase_id:['string', 'null']purchase_code:['string', 'null']expected_at:objectstate: SupplyState
Amounts
planned:numberactual:numbervariance:number— Écart : réel − prévu
Analysis
work_order_id:stringcode:stringtitle:stringsite_id:stringasset_id:stringkind:stringstatus:stringparent_id:['string', 'null']created_at:integer— Horodatage en millisecondes (epoch)closed_at:objectlabor_minutes: Amounts — Minutes : gamme (sinon estimation de charge) contre temps passéslabor_cost: Amounts — Euros : temps prévus × coût horaire moyen du métier dans l'usine, contre temps passés × coût horaire de la personneparts_cost: Amounts — Euros : quantités prévues au coût moyen, contre consommé au coût figé des sortiesexternal_cost: Amounts — Sous-traitance : devis (0 sans devis) contre montant facturétotal_cost: Amountsestimated:boolean— Pas de gamme : la main-d'œuvre prévue est l'estimation de charge (hors écarts comparables)unlogged:boolean— OT clôturé sans temps saisi : réel de main-d'œuvre inconnu (hors écarts comparables)external_quoted:boolean— Sous-traitance avec devis (sinon, hors écarts comparables)labor_rate_effect:number— Effet taux : coût réel − temps réel au taux prévu du métiervariance: Variancesoperations: []parts: [part_id:stringcode:stringname:stringunit:stringkit_code:['string', 'null']planned_qty:numberreserved_qty:numberconsumed_qty:numbercost: Amounts
Variances
labor_minutes:numberlabor_cost:numberparts_cost:numberexternal_cost:numbertotal_cost:number
AnalysisSummary
from:integer— Horodatage en millisecondes (epoch)to:integer— Horodatage en millisecondes (epoch)count:integerclosed:integerlabor_minutes: Amountslabor_cost: Amountsparts_cost: Amountsexternal_cost: Amountstotal_cost: Amountsrealized: Variances — Écart réalisé : OT clôturés de la périodeopen: Variances — OT ouverts : un écart négatif est un reste à consommerestimated:integer— OT sans gamme (main-d'œuvre estimée)unlogged:integer— OT clôturés sans temps saisiby_trade: []rows: [Analysis] — Une ligne par OT, sans le détail des opérations et des pièces
SupplyState
ready | in_stock | ordered | to_order | lateExplosion
part_id:stringqty:number— Quantité demandée en unité de gestionkit:booleanlines: [part_id:stringcode:stringname:stringunit:stringqty:number— Quantité exacte (au millième)available:number— En stock − réservé sur les OT ouvertsmissing:number
PartUse
part_id:stringqty:number— Quantité prévueunit_cost:numberreserved_by:stringissued_at:integer— Horodatage en millisecondes (epoch)issued_qty:number— Cumul des sorties (au-delà du prévu : écart)reserved:boolean— Faux : prévu, à approvisionnersettled:boolean— Reliquat libérékit_id:['string', 'null']— Kit dont la ligne est un composant
Purchase
id:stringcode:stringsite_id:stringsupplier:stringstatus:draft|ordered|partial|received|cancelledlines: [part_id:stringqty:numberunit_cost:numberreceived_qty:number
work_order_id:stringexpected_at:integer— Horodatage en millisecondes (epoch)
Inspection
id:stringsite_id:stringasset_id:stringkind:regulatory|calibration|functionaltitle:stringreference:stringbody:stringinterval_days:integerdue_at:integer— Horodatage en millisecondes (epoch)active:booleanhistory: [object]
Contract
id:stringsite_id:stringvendor_id:stringreference:stringtitle:stringkind:stringasset_ids: [string]start_at:integer— Horodatage en millisecondes (epoch)end_at:integer— Horodatage en millisecondes (epoch)notice_days:integerauto_renew:booleanresponse_hours:integerannual_amount:number
Vendor
id:stringname:stringkind:contractor|inspection_body|suppliercontact:stringemail:stringphone:stringactive:boolean
Snapshot
Site
id:stringcode:stringname:stringactivity:stringaddress:stringcity:stringcountry:stringtimezone:stringlocale:stringsector:agrifood|automotiveorigin:x:numberz:number
footprint:width:numberdepth:number
aisle_z:numberworkshop:x:numberz:number
SiteInput
code* :stringname* :stringactivity:stringaddress:stringcity:stringcountry* :string— ISO 3166-1 alpha-2timezone* :stringlocale* :stringsector* :agrifood|automotivewidth:number— Emprise du bâtiment en m (20 à 400, 60 par défaut)depth:number— En m (20 à 400, 40 par défaut)
ProductionLine
id:stringsite_id:stringcode:stringname:stringproduct:stringnominal_rate:integer
LineInput
site_id* :stringcode* :stringname* :stringproduct:stringnominal_rate:integer
Indicator
key* :availability|oee|mtbf|mttr|lead_time|coded_share|preventive_share_hours|preventive_share_count|pm_compliance|planned_share|backlog_weeks|labor_hours|cost_total|cost_to_rav|satisfaction— satisfaction : notes de 4 ou 5 ÷ notes reçues des demandeurs sans compte (portail QR), au jour de la notecode:['string', 'null']— Code EN 15341:2019+A1:2022 vérifié sur le texte de la norme (PHA6, PHA6 · R1), sinon nullvalue* :['number', 'null']— null : non calculable (voir missing)unit* :%|h|min|wk|EURnumerator* :numberdenominator* :numbermissing:['string', 'null']— production_counts, no_failure, no_repair, no_corrective, no_labor, no_work_order, no_plan_work_order, no_technician, no_replacement_value, no_asset, no_elapsed_time, no_rating
Report
from:integer— Horodatage en millisecondes (epoch)to:integer— Fin exclue ; bornes alignées sur des jours UTC entiersgenerated_at:integer— Horodatage en millisecondes (epoch)site_ids: [string]granularity:day|week|monthdays:integerrequired_hours:numberassets_in_scope:integertechnicians:integerindicators: [Indicator]closed:corrective:integerpreventive:integerimprovement:integer
failures:integer— Défaillances demandées sur la période : correctifs, hors réparation définitive (même défaillance que la réparation temporaire)failure_modes: [key:stringcount:integercumulative_pct:number
causes: [key:stringcount:integercumulative_pct:number
assets: [asset_id:stringsite_id:stringfailures:integerrepairs:integerdowntime_minutes:integermttr_minutes:numbermtbf_hours:numberavailability:numberlabor_hours:numbercost:object
costs:labor:numberparts:numberexternal:numbertotal:numberreplacement_value:number
backlog:open:integerhours:numberweeks:numbercapacity_hours_per_week:number
micro_stops:count:integerminutes:integerby_reason: [object]
series: [start:integer— Horodatage en millisecondes (epoch)closed:objectfailures:integerdowntime_minutes:integerlabor_hours:numbercost:number
by_site: [site_id:stringassets_in_scope:integertechnicians:integerclosed:objectfailures:integercosts:objectindicators: [Indicator]
assumptions:required_hours_per_day:numberweekly_hours_per_technician:numberday_boundary:objectpm_on_time_days:integer
DemoRequestInput
name* :string— Nom et prénom, 1 à 100 caractères après rognage (blancs d'une ligne réduits)company* :string— Société, 1 à 120 caractèresemail* :string— E-mail professionnel (messageries grand public admises) ; gardé en minusculesphone:['string', 'null']— Facultatif : 6 à 20 chiffres, « + » en tête, groupes séparés par une espace ou un pointsites* :1|2-3|4-10|10+— Nombre de sites : 1, 2 à 3, 4 à 10, plus de 10message:['string', 'null']— Facultatif : 2 000 caractères au plus (un saut de ligne compte pour un)consent* :boolean— Consentement au traitement de la demande : doit valoir truelocale* :fr|en|de|es— Langue de la page qui envoie la demandewebsite:string— Champ piège caché aux humains, à laisser vide : rempli, la demande est jetée (réponse 201 ordinaire)
DemoRequestErrors
error* :stringcode* :objecterrors* :object— Champ → code stable : required, invalid, too_long, consent_required
WebhookPayload
id:stringevent:stringtenant:stringat:integer— Horodatage en millisecondes (epoch)actor:stringtarget:stringdetail:objectdata:object— État courant de l'enregistrement (OT, achat, contrôle, article, contrat, équipement)