TutorialWMSintegrationREST API

Guía de integración WMS: REST, webhooks y WebSockets para un mapa de almacén en vivo

¿REST, webhook o WebSocket? Cómo llevar datos del WMS a un mapa 3D de almacén: polling REST, carga de archivos y la API de escritura de tablas.

11 min de lecturaPublicado Actualizado Por Spatial Map team
Acme Warehouse en vista previa 3D: ubicaciones de rack con cantidades, marcadores de operarios, muelles con camiones y extintores — el mapa en vivo que alimenta una integración con el WMS

La respuesta corta

REST, webhook o WebSocket: qué estás eligiendo de verdad

Busca “integración WMS” y acabarás en un debate de protocolos. Para un mapa de almacén en vivo, la pregunta útil es más concreta: ¿cómo entrega datos tu WMS y cuánta frescura necesita el mapa? El WMS puede exponer endpoints REST, disparar webhooks, publicar en una cola o emitir por un socket. Spatial Map acepta tres tipos de entrada: consulta endpoints REST, importa archivos y recibe envíos push como escrituras en la API de una tabla. Entonces, ¿necesitas webhooks o WebSockets? Tu WMS puede emitirlos; Spatial Map los recibe como escrituras en la API de tablas, enviadas por un relay que controlas tú.

Dónde nacen los datos del WMS → camino de entrada a Spatial MapLos endpoints que admiten GET entran por la integración REST API o por el Pull from a REST API de una tabla en el servidor; los eventos empujados (webhooks, colas, sockets) pasan por tu relay hacia la API de escritura de la tabla; las exportaciones entran por Upload file. Todo termina en filas que un data link dibuja en el mapa.
Dato del almacénFrescura necesariaCamino hacia Spatial Map
Ocupación y stock por ubicaciónalrededor de un minutoTabla con Pull from a REST API (cada 30 s o más) o envíos del relay al cambiar
Eventos de picking, movimiento y devoluciónsegundosRelay → `POST /rows/bulk` cada pocos segundos
Cambios de estado de ubicación (bloqueada, reservada, en picking)segundosRelay → `PATCH /rows/bulk` sobre filas existentes
Posiciones de carretillas u operarios desde un RTLSpocos segundosEl relay acumula el flujo y envía lotes — nunca una petición por cada posición
Conteo cíclico o foto de cierre de díadiariaUpload file y Re-import, o un script nocturno contra la API de tablas
Datos maestros (SKU, zonas, muelles)cuando cambianUpload file o una escritura bulk puntual

Las cuatro formas de entrada

Abre Integrations → Add integration y verás tres opciones: REST API, Upload file y Table. Una tabla añade además una cuarta vía — su propia API de escritura — y un poller opcional en el servidor. Se diferencian sobre todo en dónde se ejecutan.

CaminoDónde se ejecutaFrescuraCuidado con
Integración REST APIEn el navegador de quien tenga un mapa (o la pantalla Integrations) abierto. Sincroniza Manually, When a map opens u On a timerEn cada sincronización; el temporizador solo se repite mientras haya un mapa abiertoLa API del WMS debe permitir el origen de la app (CORS); si no, verás “Your browser is blocked from this API”
Tabla · Pull from a REST APIEn los servidores de Spatial Map, configurado en la pestaña API & access de la tablaIntervalo de 30 s o más; el poller revisa una vez por minuto, así que cuenta con un minuto aprox.Hasta 1.000 filas, 10 MB y 30 s por consulta; la URL debe ser accesible desde internet
Upload fileTú, en el diálogo de importación (File, Mode, Match, Mapping, Preview)Cada vez que reimportasCSV, Excel, JSON o GeoJSON: ideal para fotos fijas, no para eventos
API de escritura de tablasTus sistemas llaman a `https://app.spatialmap.io/api/v1/public/tables/…` con una clave `sgv_tbl_`Segundos: cada escritura refresca los mapas abiertos60 peticiones por minuto por clave (ráfaga de 30); hasta 1.000 filas por llamada bulk

Qué camino encaja con tu WMS

No necesitas un conector específico de fabricante: Spatial Map no tiene ninguno. Lo que importa es el tipo de interfaz que ofrece tu WMS. Revisa la documentación de integración de tu versión; estos patrones valen para la mayoría de productos.

Tipo de WMSLo que suele exponerCamino que encaja
Suite empresarial con capa de eventos o integraciónAPIs de lectura (REST u OData) y eventos de negocio publicados en una plataforma de integración o bus de mensajesPull from a REST API en el servidor para el estado que cambia despacio; un relay suscrito a los eventos escribe los cambios con `/rows/bulk`
WMS en la nube con REST y webhooks salientesEndpoints REST y un webhook por tipo de evento (tarea completada, ubicación bloqueada, pedido liberado)Apunta los webhooks a tu relay (basta una función serverless) y agrupa en la API de tablas; usa consultas REST para conciliar
WMS on‑premise detrás de un firewallAPIs accesibles solo en la red internaEjecuta el relay dentro de la red: solo necesita HTTPS saliente hacia la API de tablas. El polling desde el servidor no llega a una URL interna
Legacy o desarrollo propioUna base de datos, exportaciones planas programadas, a veces una capa REST mínimaUpload file con Re-import para las exportaciones, o un script programado que lee la base de datos y escribe en la API de tablas

Puentear webhooks, colas y sockets con un pequeño relay

Un relay es cualquier programa pequeño entre el WMS y Spatial Map: una función serverless detrás del webhook del WMS, un consumidor de la cola de mensajes o un proceso que mantiene abierto el socket del RTLS. Su trabajo es siempre el mismo: convertir cada evento en una fila de tabla y enviar las filas por lotes.

  1. 1
    Crea la tabla

    En Tables, crea una tabla por tipo de cosa (ubicaciones, eventos de picking, operarios) y elige su tipo: Marker / POI, Asset (mobile), Shipment, Polygon / area, etc. Cada campo tiene una API key, como `bin_code` o `status`: son las claves del payload que envía el relay. Consulta Tables.

  2. 2
    Crea una clave

    En la pestaña API & access de la tabla, un Owner o Admin crea una clave. Empieza por `sgv_tbl_` y solo se muestra una vez. Una clave escribe en una sola tabla, así que la URL no lleva id de tabla. Da a cada sistema su propia clave para poder revocar una sin romper las demás, y copia la URL base exacta de esa misma pestaña.

  3. 3
    Convierte cada evento en una fila

    Elige un `entityKey` estable: el código de ubicación, el id del evento, el id de la tarjeta. Las filas se hacen upsert por esa clave, así que una entrega repetida sobrescribe en lugar de duplicar.

  4. 4
    Envía lotes, no eventos sueltos

    Acumula unos segundos y envía un `POST /rows/bulk` (filas completas) o un `PATCH /rows/bulk` (solo campos cambiados) con hasta 1.000 filas. Las filas válidas se confirman aunque otras fallen; las rechazadas vuelven en `errors[]`.

  5. 5
    Reintenta los errores adecuados

    `429` significa que la clave superó las 60 peticiones por minuto; `401`, que la clave es incorrecta o está revocada; `400`, que una fila incumple el esquema de la tabla (campo obligatorio o único). Guarda las filas no enviadas y reintenta en el siguiente ciclo.

bash·Upsert de una fila: un nuevo evento de picking en 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 de un lote con POST /rows/bulk (hasta 1.000 filas)
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·Cambiar campos de una ubicación existente en 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 relay mínimo de webhook a tabla (boceto)
// 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);

Ejemplo práctico: Acme Warehouse

El almacén de demostración Acme Warehouse tiene 17 racks con 314 ubicaciones y tablas como Rack Inventory (una fila por ubicación, con clave `bin_code` del tipo `A-B01-L1` y campos `status`, `sku` y `quantity`), Inventory Items, Pick Events y Warehouse Workers. Un flujo típico desde el WMS usa tres de los cuatro caminos.

  1. 1
    Estado de ubicaciones por polling

    Si el WMS tiene un endpoint de inventario por ubicación, abre Rack Inventory → API & access → Pull from a REST API: la URL, un intervalo de 30 s o más, Row key field in the response = `bin_code`, Where the items are (JSON path) si la lista viene dentro de un sobre, cabeceras de autenticación y un mapeo de campos. Pulsa Start polling; la primera ejecución llega en menos de un minuto. Receta completa: consultar un endpoint REST con calendario.

  2. 2
    Eventos por push

    Apunta los webhooks de picking confirmado y de estado de ubicación del WMS a tu relay. Los picks confirmados se convierten en filas nuevas de Pick Events (`POST /rows/bulk`); los cambios de estado actualizan la ubicación correspondiente de Rack Inventory (`PATCH /rows/bulk`). Paso a paso: enviar filas con la API de escritura.

  3. 3
    Fotos fijas por carga

    La exportación nocturna del conteo cíclico entra por Upload file, y Re-import en la tarjeta de la fuente la actualiza, sin código.

  4. 4
    Dibújalo en el mapa

    En el editor, abre Data → Manage data links → New link. Un enlace Color a shape tiñe cada ubicación según `status` con reglas de estilo; un enlace Live location marker sitúa a los operarios en su latitud y longitud. Mira la introducción a los data links.

  5. 5
    Comprueba que fluye

    La pestaña Health de Integrations lista cada tabla con la última vez que tus sistemas escribieron en ella. Cada escritura por API queda además en el History de la fila, que un enlace Historical movement puede reproducir sobre el mapa.

Create new table: elige qué describe cada registro
Formulario Create new table con el campo Table name y los tipos Polygon / area, Circle, Marker / POI (seleccionado), Asset (mobile), Camera, Sensor, Shipment, RFID tag y Streaming / batch replay, sobre la lista de campos que empieza por External code y Longitude
Formulario Create new table con el campo Table name y los tipos Polygon / area, Circle, Marker / POI (seleccionado), Asset (mobile), Camera, Sensor, Shipment, RFID tag y Streaming / batch replay, sobre la lista de campos que empieza por External code y Longitude

Los errores que más vemos

Siguientes pasos

Prueba la plataforma que tus datos merecen.

Spatial Map convierte hojas de cálculo, sensores y planos CAD en una vista 3D en vivo de tus instalaciones — sin instalar nada, prueba gratuita de siete días.

Velo en vivo

Sigue leyendo