TutorielWMSintegrationREST API

Guide d’intégration WMS : REST, webhooks et WebSockets pour une carte d’entrepôt en direct

REST, webhook ou WebSocket ? Alimenter une carte 3D d’entrepôt depuis le WMS : polling REST, import de fichiers et API d’écriture des tables.

11 min de lecturePublié Mis à jour Par Spatial Map team
Acme Warehouse en aperçu 3D : emplacements de racks avec quantités, marqueurs d’opérateurs, quais avec camions et extincteurs — la carte en direct qu’alimente une intégration WMS

La réponse courte

REST, webhook ou WebSocket : ce que vous choisissez vraiment

Cherchez « intégration WMS » et vous tomberez sur un débat de protocoles. Pour une carte d’entrepôt en direct, la vraie question est plus étroite : comment votre WMS met‑il ses données à disposition, et quelle fraîcheur la carte exige‑t‑elle ? Le WMS peut exposer des endpoints REST, déclencher des webhooks, publier dans une file ou diffuser sur un socket. Spatial Map accepte trois types d’entrée : il interroge des endpoints REST, il importe des fichiers et il reçoit le push sous forme d’écritures dans l’API d’une table. Alors, faut‑il des webhooks ou des WebSockets ? Votre WMS peut en émettre ; Spatial Map les reçoit comme des écritures dans l’API de table, envoyées par un relais qui vous appartient.

Origine des données WMS → chemin d’entrée dans Spatial MapLes endpoints interrogeables en GET passent par l’intégration REST API ou par le Pull from a REST API d’une table côté serveur ; les événements poussés (webhooks, files, sockets) passent par votre relais vers l’API d’écriture de la table ; les exports passent par Upload file. Tout finit en lignes qu’un data link dessine sur la carte.
Donnée d’entrepôtFraîcheur requiseChemin vers Spatial Map
Occupation et stock par emplacementune minute environTable avec Pull from a REST API (toutes les 30 s ou plus), ou push du relais à chaque changement
Événements de prélèvement, transfert et retoursecondesRelais → `POST /rows/bulk` toutes les quelques secondes
Changements de statut d’emplacement (bloqué, réservé, en préparation)secondesRelais → `PATCH /rows/bulk` sur les lignes existantes
Positions de chariots ou d’opérateurs issues d’un RTLSquelques secondesLe relais met le flux en tampon et envoie des lots — jamais une requête par position
Inventaire tournant ou photo de fin de journéequotidienUpload file et Re-import, ou un script nocturne qui appelle l’API de table
Données de référence (SKU, zones, quais)quand elles changentUpload file ou une écriture bulk ponctuelle

Les quatre portes d’entrée

Ouvrez Integrations → Add integration : trois choix s’offrent à vous, REST API, Upload file et Table. Une table ajoute ensuite une quatrième voie — sa propre API d’écriture — ainsi qu’un poller optionnel côté serveur. La grande différence tient à l’endroit où chacun s’exécute.

CheminOù il s’exécuteFraîcheurPoints d’attention
Intégration REST APIDans le navigateur de la personne qui a une carte (ou l’écran Integrations) ouverte. Synchro Manually, When a map opens ou On a timerÀ chaque synchro ; le minuteur ne se répète que tant qu’une carte est ouverteL’API du WMS doit autoriser l’origine de l’app (CORS), sinon le message « Your browser is blocked from this API » s’affiche
Table · Pull from a REST APISur les serveurs de Spatial Map, réglé dans l’onglet API & access de la tableIntervalle de 30 s ou plus ; le poller passe une fois par minute, comptez donc environ une minuteJusqu’à 1 000 lignes, 10 Mo et 30 s par interrogation ; l’URL doit être joignable depuis internet
Upload fileVous, dans la boîte d’import (File, Mode, Match, Mapping, Preview)À chaque réimportCSV, Excel, JSON ou GeoJSON : parfait pour des instantanés, pas pour des événements
API d’écriture de tableVos systèmes appellent `https://app.spatialmap.io/api/v1/public/tables/…` avec une clé `sgv_tbl_`Secondes : chaque écriture rafraîchit les cartes ouvertes60 requêtes par minute et par clé (rafale de 30) ; jusqu’à 1 000 lignes par appel bulk

Quel chemin pour votre WMS

Inutile d’avoir un connecteur propre à un éditeur : Spatial Map n’en a aucun. Ce qui compte, c’est le type d’interface qu’offre votre WMS. Consultez la documentation d’intégration de votre version ; les schémas ci‑dessous valent pour la plupart des produits.

Type de WMSCe qu’il expose en généralChemin adapté
Suite d’entreprise avec couche d’événements ou d’intégrationAPIs de lecture (REST ou OData) et événements métier publiés sur une plateforme d’intégration ou un bus de messagesPull from a REST API côté serveur pour l’état qui bouge lentement ; un relais abonné aux événements écrit les changements via `/rows/bulk`
WMS cloud avec REST et webhooks sortantsEndpoints REST et un webhook par type d’événement (tâche terminée, emplacement bloqué, commande libérée)Pointez les webhooks vers votre relais (une fonction serverless suffit) et regroupez vers l’API de table ; gardez des interrogations REST pour réconcilier
WMS sur site derrière un pare‑feuAPIs joignables uniquement sur le réseau interneFaites tourner le relais dans le réseau : il n’a besoin que de HTTPS sortant vers l’API de table. Le polling côté serveur ne peut pas atteindre une URL interne
Ancien ou développé en interneUne base de données, des exports de fichiers plats planifiés, parfois une fine couche RESTUpload file avec Re-import pour les exports, ou un script planifié qui lit la base et écrit dans l’API de table

Relier webhooks, files et sockets avec un petit relais

Un relais, c’est n’importe quel petit programme placé entre le WMS et Spatial Map : une fonction serverless derrière le webhook du WMS, un consommateur de la file de messages, ou un processus qui garde ouvert le socket du RTLS. Son rôle ne change jamais : transformer chaque événement en ligne de table et envoyer les lignes par lots.

  1. 1
    Créer la table

    Dans Tables, créez une table par type d’objet (emplacements, événements de préparation, opérateurs) et choisissez son type : Marker / POI, Asset (mobile), Shipment, Polygon / area, etc. Chaque champ a une API key, par exemple `bin_code` ou `status` : ce sont les clés du payload que le relais envoie. Voir Tables.

  2. 2
    Créer une clé

    Dans l’onglet API & access de la table, un Owner ou un Admin crée une clé. Elle commence par `sgv_tbl_` et n’est affichée qu’une fois. Une clé écrit dans une seule table : l’URL ne contient donc pas d’identifiant de table. Donnez à chaque système sa propre clé pour pouvoir en révoquer une sans casser les autres, et copiez l’URL de base exacte depuis ce même onglet.

  3. 3
    Transformer chaque événement en ligne

    Choisissez un `entityKey` stable : le code d’emplacement, l’id d’événement, l’id de badge. Les lignes sont mises à jour ou créées (upsert) selon cette clé : une livraison en double écrase au lieu de dupliquer.

  4. 4
    Envoyer des lots, pas des événements isolés

    Accumulez quelques secondes, puis envoyez un `POST /rows/bulk` (lignes complètes) ou un `PATCH /rows/bulk` (champs modifiés uniquement) avec jusqu’à 1 000 lignes. Les lignes valides sont validées même si d’autres échouent ; les rejets reviennent dans `errors[]`.

  5. 5
    Réessayer les bonnes erreurs

    `429` : la clé a dépassé 60 requêtes par minute ; `401` : clé erronée ou révoquée ; `400` : une ligne viole le schéma de la table (champ obligatoire ou unique). Conservez les lignes non envoyées et réessayez au cycle suivant.

bash·Upsert d’une ligne : un nouvel événement de préparation dans Pick Events
curl -X POST https://app.spatialmap.io/api/v1/public/tables/rows \
  -H "Authorization: Bearer $SPATIALMAP_TABLE_KEY" \
  -H "Content-Type: application/json" \
  -d '{"entityKey":"EV-20261011-0412","payload":{"event_id":"EV-20261011-0412","event_type":"pick","item_id":"B-B86-L2-01","from_bin_code":"B-B86-L2","quantity":2,"worker_id":"W-04","ts":"2026-10-11T09:14:05Z"}}'
bash·Upsert d’un lot avec POST /rows/bulk (jusqu’à 1 000 lignes)
curl -X POST https://app.spatialmap.io/api/v1/public/tables/rows/bulk \
  -H "Authorization: Bearer $SPATIALMAP_TABLE_KEY" \
  -H "Content-Type: application/json" \
  -d '{"rows":[
        {"entityKey":"EV-20261011-0413","payload":{"event_id":"EV-20261011-0413","event_type":"pick","item_id":"A-B07-L1-02","from_bin_code":"A-B07-L1","quantity":1,"worker_id":"W-02","ts":"2026-10-11T09:14:09Z"}},
        {"entityKey":"EV-20261011-0414","payload":{"event_id":"EV-20261011-0414","event_type":"move","item_id":"B-B99-L1-03","from_bin_code":"B-B99-L1","to_bin_code":"B-B51-L1","quantity":1,"worker_id":"W-05","ts":"2026-10-11T09:14:11Z"}}
      ]}'
bash·Modifier des champs d’un emplacement existant dans Rack Inventory
curl -X PATCH https://app.spatialmap.io/api/v1/public/tables/rows/A-B01-L1 \
  -H "Authorization: Bearer $SPATIALMAP_TABLE_KEY" \
  -H "Content-Type: application/json" \
  -d '{"status":"blocked","hold_reason":"Damaged pallet"}'
js·relay.mjs : un relais minimal webhook → table (esquisse)
// relay.mjs (Node 18+) - receives bin-status webhooks from your WMS and
// forwards them in batches to the "Rack Inventory" table. A sketch, not a product.
import http from 'node:http';

const BASE = 'https://app.spatialmap.io/api/v1/public/tables'; // copy yours from API & access
const KEY = process.env.SPATIALMAP_TABLE_KEY;                  // sgv_tbl_... (this table's key)
const pending = new Map();                                     // bin_code -> latest changes

http.createServer((req, res) => {
  let body = '';
  req.on('data', (chunk) => (body += chunk));
  req.on('end', () => {
    try {
      // 1. Verify your WMS's webhook signature here (its docs say how).
      const e = JSON.parse(body);
      // 2. Map the WMS event onto your table's field keys.
      const prev = pending.get(e.bin_code)?.patch ?? {};
      pending.set(e.bin_code, {
        entityKey: e.bin_code,
        patch: { ...prev, status: e.status, sku: e.sku, quantity: e.quantity },
      });
      res.writeHead(202).end();
    } catch {
      res.writeHead(400).end();
    }
  });
}).listen(8080);

// 3. Flush every 5 s: one request instead of one per event (60 requests/min per key).
setInterval(async () => {
  const rows = [...pending.values()].slice(0, 1000);
  if (rows.length === 0) return;
  rows.forEach((r) => pending.delete(r.entityKey));
  try {
    const res = await fetch(BASE + '/rows/bulk', {
      method: 'PATCH', // merge changed fields onto existing bins
      headers: { Authorization: 'Bearer ' + KEY, 'Content-Type': 'application/json' },
      body: JSON.stringify({ rows }),
    });
    if (!res.ok) throw new Error('HTTP ' + res.status); // 401 key, 429 rate limit, 5xx
    const { errors } = await res.json();                 // rows the table rejected
    if (errors?.length) console.warn(errors);
  } catch (err) {
    // put the batch back without losing newer events; retry on the next tick
    rows.forEach((r) => {
      const newer = pending.get(r.entityKey);
      pending.set(r.entityKey, newer ? { ...newer, patch: { ...r.patch, ...newer.patch } } : r);
    });
    console.error(err);
  }
}, 5000);

Exemple concret : Acme Warehouse

L’entrepôt de démonstration Acme Warehouse compte 17 racks et 314 emplacements, avec des tables comme Rack Inventory (une ligne par emplacement, clé `bin_code` du type `A-B01-L1`, champs `status`, `sku` et `quantity`), Inventory Items, Pick Events et Warehouse Workers. Un flux WMS typique y emprunte trois des quatre chemins.

  1. 1
    L’état des emplacements par polling

    Si le WMS expose un endpoint d’inventaire par emplacement, ouvrez Rack Inventory → API & access → Pull from a REST API : l’URL, un intervalle de 30 s ou plus, Row key field in the response = `bin_code`, Where the items are (JSON path) si la liste est dans une enveloppe, des en‑têtes d’authentification et un mappage de champs. Cliquez sur Start polling ; la première exécution arrive en moins d’une minute. Recette complète : interroger un endpoint REST selon un planning.

  2. 2
    Les événements par push

    Pointez vers votre relais les webhooks « prélèvement confirmé » et « statut d’emplacement » du WMS. Les prélèvements confirmés deviennent de nouvelles lignes dans Pick Events (`POST /rows/bulk`) ; les changements de statut mettent à jour l’emplacement correspondant dans Rack Inventory (`PATCH /rows/bulk`). Pas à pas : pousser des lignes avec l’API d’écriture.

  3. 3
    Les instantanés par import

    L’export nocturne de l’inventaire tournant entre par Upload file, et Re-import sur la carte de la source le rafraîchit — sans une ligne de code.

  4. 4
    L’afficher sur la carte

    Dans l’éditeur, ouvrez Data → Manage data links → New link. Un lien Color a shape colore chaque emplacement selon `status` grâce à des règles de style ; un lien Live location marker place les opérateurs à leur latitude et longitude. Voir la présentation des data links.

  5. 5
    Vérifier que ça circule

    L’onglet Health d’Integrations liste chaque table avec la date de la dernière écriture de vos systèmes. Chaque écriture via l’API est aussi conservée dans l’History de la ligne, qu’un lien Historical movement peut rejouer sur la carte.

Create new table : choisir ce que décrit chaque enregistrement
Formulaire Create new table avec le champ Table name et les types Polygon / area, Circle, Marker / POI (sélectionné), Asset (mobile), Camera, Sensor, Shipment, RFID tag et Streaming / batch replay, au‑dessus de la liste des champs qui commence par External code et Longitude
Formulaire Create new table avec le champ Table name et les types Polygon / area, Circle, Marker / POI (sélectionné), Asset (mobile), Camera, Sensor, Shipment, RFID tag et Streaming / batch replay, au‑dessus de la liste des champs qui commence par External code et Longitude

Les pièges les plus fréquents

Pour aller plus loin

Essayez la plateforme que méritent vos données.

Spatial Map transforme les tableurs, les capteurs et les plans CAO en une vue 3D en direct de vos sites — rien à installer, essai gratuit de sept jours.

À voir en direct

À lire ensuite