Nouveau : le pare-feu IA surveille chaque module et explique chaque incident en termes simples. Découvrez comment ça marche

Bases de l’API REST

Chemins, conventions JSON, listes avec pagination, tri et filtres, contrôles de concurrence, dates et identifiants : les règles que suit chaque route REST de Hermetry.

Cette page explique les conventions suivies par l’API REST de gestion. Les routes elles-mêmes sont listées par domaine sur les pages de référence liées à la fin.

Chemins

Chaque chemin de gestion est limité à votre organisation :

https://<your host>/tenant/<tenantId>/api/<resource>

Sur les pages de référence, les chemins sont écrits à partir de /api/... ; placez /tenant/<tenantId> devant. Par exemple /api/iot/devices signifie https://<votre hôte>/tenant/<tenantId>/api/iot/devices.

Envoyez Authorization: Bearer <API key> à chaque appel. Voir Authentification.

Requêtes

  • Les corps de requête sont en JSON : envoyez Content-Type: application/json. La seule exception est l’envoi d’un firmware, qui utilise multipart/form-data.
  • La plupart des corps sont stricts : un champ que la route ne connaît pas est refusé avec 400, il n’est jamais ignoré silencieusement. Vérifiez l’orthographe lorsque vous recevez un 400 pour un champ qui semble correct.
  • PATCH ne modifie que les champs que vous envoyez. PUT remplace l’ensemble (les règles d’alarme d’un profil, un placement, une section de paramètres).
  • Un champ défini à null est vidé, lorsque le champ accepte null.
  • Les identifiants sont des UUID (6f1c0a2e-…). Un identifiant mal formé dans un chemin renvoie en général un 400 ou un 404.

Réponses

  • Les réponses sont en JSON. Un enregistrement unique est enveloppé sous son nom : { "device": {...} }, { "alarm": {...} }.
  • Une liste est renvoyée sous forme de tableau accompagné du nombre total. Le nom du tableau dépend de la route : { "devices": [...], "total": 42 }, { "items": [...], "total": 7 }, ou { "data": [...], "total": 3 }. Chaque page de référence indique le nom.
  • Une réponse qui contient un secret (un nouveau jeton d’appareil, une nouvelle clé d’API, un secret de signature de webhook) est envoyée avec Cache-Control: no-store et c’est le seul endroit où le secret apparaît.

Dates et heures

Deux formats sont utilisés. Chaque page de référence indique lequel.

FormatOùExemple
Texte ISO 8601, UTCChamps des enregistrements (createdAt, lastActivityAt), la plupart des filtres, charges utiles des webhooks"2026-11-05T10:00:00.000Z"
Millisecondes depuis le 1er janvier 1970, UTCTélémétrie (ts, from, to), heures d’alarme (startTs, openedAt)1762336800000

Les filtres de plage de dates de la forme createdFrom=2026-10-01&createdTo=2026-10-15 prennent des jours entiers, AAAA-MM-JJ, en UTC, les deux jours inclus.

Listes

Les listes sont paginées côté serveur. Deux styles de pagination existent :

Stylepage commence àUtilisé par (exemples)
11Appareils, profils d’appareils, alarmes, sites et actifs, clés d’API, webhooks et leurs envois
00Passerelles et appareils LoRaWAN, historique des commandes d’un appareil avec page, tâches et références de paramètres d’appareils, applications connectées MCP

Les pages de référence indiquent la base de chaque liste. Les paramètres communs :

ParamètreSignificationLimites
pageNuméro de pagejusqu’à 10 000 ou 100 000 selon la liste
pageSizeLignes par page20 par défaut, 100 au maximum (certaines listes autorisent 200 ou 500, comme indiqué)
searchTexte libre, recherché dans les noms et champs similairesjusqu’à 128 ou 200 caractères
sortfield:asc ou field:desc, jusqu’à trois, séparés par des virgulesseulement les champs listés par la route ; tout autre champ renvoie 400
filtresNommés par routevoir ci-dessous

Plusieurs listes à partir de 0 acceptent aussi limit à la place de pageSize et q à la place de search, pour les anciens clients.

Tri

GET /api/iot/devices?sort=lastSeen:desc
GET /api/iot/lorawan/gateways?sort=status:asc,name:asc

Un champ inconnu est refusé avec 400, par exemple « Cannot sort by « x ». Sortable fields: name, connection, lastSeen, createdAt. » Sur les listes à partir de 0, les égalités sont départagées par identifiant, ce qui rend la pagination stable.

Filtres

TypeFormeExemple
Une valeur d’un ensembleliste séparée par des virgulesstatus=OPEN,ACKNOWLEDGED
Identifiantsliste d’UUID séparés par des virgules, 100 au maximumdeviceId=…,…
Indicateurtrue ou falseonline=true
Plage de jours<name>From, <name>TocreatedFrom=2026-11-01
Plage numérique<name>Min, <name>Maxlorsqu’une route en propose une

Omettez un paramètre plutôt que de l’envoyer vide : la plupart des listes ignorent un paramètre vide, mais certaines le refusent.

Parcourir toutes les pages

// Node.js 18+: read every device, 100 at a time (a 1-based list)
const base = `https://${host}/tenant/${tenant}/api/iot/devices`;
const all = [];
for (let page = 1; ; page++) {
  const res = await fetch(`${base}?page=${page}&pageSize=100&sort=createdAt:asc`, {
    headers: { Authorization: `Bearer ${key}` },
  });
  if (res.status === 429) { await new Promise((r) => setTimeout(r, Number(res.headers.get('Retry-After') ?? 60) * 1000)); page--; continue; }
  const { devices, total } = await res.json();
  all.push(...devices);
  if (all.length >= total || devices.length === 0) break;
}

Triez sur un champ qui ne change pas (createdAt) lorsque vous parcourez une liste que d’autres modifient.

Modifications faites par un autre utilisateur

Certaines écritures vérifient que l’enregistrement n’a pas changé depuis votre lecture :

OùCommentEn cas de conflit
Profils d’appareilsEnvoyez le version du profil sous forme de expectedVersion dans le corps de la requête PATCH409, details.reason = stale_profile
Sections de paramètres d’appareilsEnvoyez l’ETag de la section dans un en-tête If-Match412, details.reason = rev_mismatch ; 428 sans If-Match

Les règles d’alarme d’un profil n’ont pas de contrôle de ce type : un PUT remplace l’ensemble complet, relisez donc les règles juste avant de les modifier.

Relisez, appliquez votre modification à la copie récente et renvoyez-la.

Introuvable et non autorisé

Un enregistrement d’une autre organisation, ou que vous n’avez pas le droit de lire, renvoie 404, comme un enregistrement inexistant. Une route que vous ne pouvez pas utiliser du tout renvoie 403. Voir Erreurs et limites de débit pour le corps d’erreur et tous les codes d’état.

Autorisations

Chaque route indique l’autorisation dont elle a besoin, la même que celle que vérifie l’application. Les pages de référence la listent pour chaque route, par exemple iot_device.devices.read. Accordez à une clé cette autorisation dans Autorisations du module. Une autorisation que seul le rôle Propriétaire possède ne peut pas être accordée à une clé.

Références des routes

DomainePage
Appareils, identifiants, connexion, journal, profils d’appareilsAPI appareils et profils
Dernières valeurs, historique, attributsAPI télémétrie et attributs
Commandes et catalogue des commandesAPI commandes
Alarmes, règles d’alarme, mises en sourdineAPI alarmes
Sites, actifs, placement, relationsAPI sites et actifs
Paquets firmware, déploiements, paramètres d’appareilsAPI firmware et paramètres d’appareils
Passerelles LoRaWAN, appareils, appairage, tramesAPI LoRaWAN
WebhooksWebhooks
Clés d’APIAuthentification
Codecs LoRaWANAPI des codecs