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.


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ú.
| Dato del almacén | Frescura necesaria | Camino hacia Spatial Map |
|---|---|---|
| Ocupación y stock por ubicación | alrededor de un minuto | Tabla 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ón | segundos | Relay → `POST /rows/bulk` cada pocos segundos |
| Cambios de estado de ubicación (bloqueada, reservada, en picking) | segundos | Relay → `PATCH /rows/bulk` sobre filas existentes |
| Posiciones de carretillas u operarios desde un RTLS | pocos segundos | El 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ía | diaria | Upload file y Re-import, o un script nocturno contra la API de tablas |
| Datos maestros (SKU, zonas, muelles) | cuando cambian | Upload 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.
| Camino | Dónde se ejecuta | Frescura | Cuidado con |
|---|---|---|---|
| Integración REST API | En el navegador de quien tenga un mapa (o la pantalla Integrations) abierto. Sincroniza Manually, When a map opens u On a timer | En cada sincronización; el temporizador solo se repite mientras haya un mapa abierto | La 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 API | En los servidores de Spatial Map, configurado en la pestaña API & access de la tabla | Intervalo 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 file | Tú, en el diálogo de importación (File, Mode, Match, Mapping, Preview) | Cada vez que reimportas | CSV, Excel, JSON o GeoJSON: ideal para fotos fijas, no para eventos |
| API de escritura de tablas | Tus sistemas llaman a `https://app.spatialmap.io/api/v1/public/tables/…` con una clave `sgv_tbl_` | Segundos: cada escritura refresca los mapas abiertos | 60 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 WMS | Lo que suele exponer | Camino que encaja |
|---|---|---|
| Suite empresarial con capa de eventos o integración | APIs de lectura (REST u OData) y eventos de negocio publicados en una plataforma de integración o bus de mensajes | Pull 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 salientes | Endpoints 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 firewall | APIs accesibles solo en la red interna | Ejecuta 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 propio | Una base de datos, exportaciones planas programadas, a veces una capa REST mínima | Upload 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.
- 1Crea 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.
- 2Crea 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.
- 3Convierte 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.
- 4Enví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[]`.
- 5Reintenta 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.
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"}}'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"}}
]}'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"}'// 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.
- 1Estado 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.
- 2Eventos 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.
- 3Fotos 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.
- 4Dibú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.
- 5Comprueba 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.


Los errores que más vemos
Siguientes pasos
- Tables: esquema, registros y la pestaña API & access.
- Integrations: integraciones REST API, carga de archivos y estado.
- Enviar filas con la API de escritura de tablas: ejemplo completo con claves y curl.
- Consultar un endpoint REST con calendario: polling en el servidor de principio a fin.
- Introducción a los data links: cómo las filas se convierten en marcadores, tintes e indicadores.
- Spatial Map para almacenes y gemelo digital de almacén vs WMS.
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
- TutorialDashboards de KPI de almacén con mapa 3D en vivo: tutorialUn gráfico dice que el 66% de las ubicaciones está ocupado; un mapa dice dónde. Este tutorial recorre el asistente guiado de 12–13 pasos para reunir ambos en un dashboard de almacén, con el informe Rack Inventory real de nuestro almacén de demostración.
- TutorialDe la hoja de cálculo al mapa: convierte tu CSV de inventario por ubicación en un mapa de racks en vivoUn CSV en una carpeta compartida no ayuda a nadie en el almacén. El mismo CSV pintado sobre tus racks es una reunión de turno.
- TutorialDe un plano CAD o PDF a un mapa 3D en el navegador, paso a pasoElige la hoja o las capas, confirma la escala o las unidades, suelta el plano en el mapa y alinéalo. El dibujo llega como una imagen a tamaño real; el edificio 3D es lo que calcas encima. Este es el camino completo, con lo que hace y lo que no.