Conecte Talavora con su ERP, su programa de nóminas, un cuadro de mando o un GMAO: lea fichajes, ausencias, personas, clientes, órdenes de trabajo con su parte, facturas y todo Mantenimiento (espacios, activos, incidencias, preventivo, contadores y órdenes), comunique incidencias y anote lecturas, conecte Power BI, Tableau o Metabase a las vistas de BI, mande las lecturas de sus sensores, pasarelas o BMS, y reciba avisos firmados cuando pasa algo.
Un administrador de la organización entra en Talavora y va a Configuración → API e integraciones (la sección aparece si la organización tiene la función API e integraciones).
Pulsa Nueva key, le pone un nombre que diga para qué es (por ejemplo, «ERP» o «Nóminas») y marca SOLO los permisos que necesita la integración.
La clave (tlv_pub_ y 40 letras y números) se enseña una sola vez: guárdela en el gestor de secretos de la integración, nunca en el código ni en un navegador.
Caduca al año (como mucho a los dos, si se elige otra fecha) y se puede revocar en cualquier momento desde la misma pantalla.
Compruebe que funciona: /v1/me devuelve la organización y los permisos de la clave.
Todas las rutas, salvo /v1/salud y las de Dispositivos, piden la cabecera Authorization: Bearer tlv_pub_…. Cada clave pertenece a una organización y el servidor filtra siempre por ella: no hay ningún parámetro con el que preguntar por otra. Una clave ve toda la organización (el alcance por centros es de las personas, no de las integraciones).
Permiso
Qué abre
empleados:read
Personas
fichajes:read
Fichajes
ausencias:read
Ausencias
clientes:read
Clientes
ordenes:read
Órdenes de trabajo y su parte
facturas:read
Facturas de venta
mantenimiento:read
Leer Mantenimiento
mantenimiento:write
Comunicar incidencias, anotar lecturas y dar de alta o cambiar activos y espacios (nunca borra)
mantenimiento:costes
Importes de Mantenimiento (coste de órdenes y materiales; coste de adquisición al escribir)
bi:read
Vistas de BI de Mantenimiento (`/v1/bi`), en JSON o CSV. Hay que pedirlo expresamente: el comodín `*` de las claves antiguas no lo abre
Lo de Mantenimiento necesita, además, que la organización tenga el módulo Mantenimiento activado. Las claves antiguas creadas con el comodín * solo leen: nunca escriben, ni ven importes, ni abren las vistas de BI (bi:read hay que pedirlo expresamente).
Las rutas de Dispositivos (/v1/dispositivos/…) son la excepción: no usan la clave de la organización sino la credencial propia de cada aparato (Authorization: Bearer tlv_dev_… o la cabecera X-Talavora-Dispositivo), que se da de alta, se rota y se revoca en Mantenimiento → Configuración → Dispositivos. Una clave de API no entra por ahí, ni la de un aparato en el resto de la API.
Paginación
Los listados devuelven { "data": [...], "next_cursor": "..." }, con un orden estable (la columna del listado y, para desempatar, el id). Pida hasta 1.000 filas por página con limit y la siguiente con cursor = el next_cursor recibido, con los MISMOS filtros. next_cursor: null = no hay más. La paginación es por clave, no por desplazamiento: si entran filas nuevas mientras recorre, no se repiten ni se saltan las ya vistas.
Para sincronizar Mantenimiento sin releerlo todo, los listados admiten updated_since (lo cambiado desde una fecha y hora).
Límites
600 peticiones por hora y clave. Al pasarse, 429 con los segundos que faltan en el texto. Para más volumen, use updated_since y páginas grandes antes que muchas llamadas pequeñas.
1.000 filas por página como mucho (limit).
Idempotency-Key: se recuerda 24 horas; hasta 200 caracteres A-Za-z0-9._:-.
Webhooks: se envían cada 15 minutos, con 10 s de espera por respuesta y hasta 5 intentos; tras 10 fallos seguidos el webhook se desactiva solo. Solo a URL https públicas; no se siguen redirecciones.
/v1/salud (sin clave) guarda su respuesta 20 s: llamarla más a menudo no da información nueva.
Dispositivos: hasta 500 lecturas y 256 KB por petición y el cupo de lecturas por minuto de cada aparato (600 por defecto); el de 600 peticiones por hora de las claves no aplica. Además, antes de tocar la base: 4 peticiones por segundo por IP (240 de golpe), 6 latidos y 60 envíos de lecturas por minuto por aparato, y una IP que acumula credenciales no válidas queda frenada unos minutos (todo con 429 y Retry-After).
Errores
Un error siempre es JSON: { "error": "texto para una persona" } y, cuando lo hay, un code estable para programar contra él (por ejemplo MNT_LECTURA_BAJA). Toda respuesta lleva la cabecera x-request-id: cítela si escribe a soporte. Puede mandar la suya (8 a 128 caracteres A-Za-z0-9._:-) para seguir una petición de punta a punta.
Código
Cuándo
400
Parámetro, cursor o cuerpo no válido. El texto dice cuál.
401
Falta la clave, no es válida, está revocada o ha caducado.
403
A la clave le falta el permiso, o la organización no tiene activado el módulo (Mantenimiento) o la función que pide la ruta (con codeFUNCION_APAGADA y su funcion, o un texto que la nombra).
404
La ruta no existe, o el recurso no existe o es de otra organización (nunca se distingue).
405
Método no admitido en esa ruta.
409
Conflicto: código repetido, referencia de otra organización, referencia externa que ya tiene otro (MNT_REF_EN_USO), regla de la base (con su code) o la misma Idempotency-Key aún en curso.
413
Solo en Dispositivos: el lote pasa de 256 KB; pártalo.
422
Esa Idempotency-Key ya se usó con otra petición.
429
Más de 600 peticiones en una hora con esta clave; en Dispositivos, el cupo de lecturas por minuto del aparato o los frenos de ráfaga por IP y por aparato (con Retry-After).
500
Error inesperado; queda registrado con su x-request-id.
503
/v1/salud: la plataforma no está en condiciones de atender. Dispositivos: la base no responde, reenvíe tras Retry-After (no duplica). BI: no se pudo comprobar la función; reintente.
Reintentos sin duplicar
En todas las altas y cambios (POST y PATCH) puede mandar la cabecera Idempotency-Key. Repetir la MISMA petición con la misma clave devuelve exactamente la misma respuesta, con Idempotent-Replayed: true, sin crear nada dos veces. La misma clave con otra petición (otro método, ruta o cuerpo) da 422; si la primera aún está en curso, 409 (reintente en unos segundos). Lo que acaba en 5xx no se guarda: el reintento vuelve a intentarlo.
Además, en las altas puede mandar su propio id (uuid): reenviar con el mismo id devuelve el mismo registro con repetido: true.
Los dispositivos no usan Idempotency-Key: su ingesta es idempotente por (dispositivo, punto, hora de la lectura), así que reenviar un lote entero no duplica nada.
Versiones
/v1 es estable: solo se AÑADEN campos y rutas. Su integración debe ignorar los campos que no conozca. Quitar un campo o cambiar su sentido sería /v2, con aviso. Cada webhook lleva la cabecera X-Talavora-Version-Evento (y los de Mantenimiento, datos.version).
Webhooks y su firma
En vez de preguntar cada poco, Talavora le avisa. En Configuración → API e integraciones, con Nuevo webhook, un administrador da de alta una URL https suya y elige los eventos. El secreto de firma se enseña una sola vez, al crearlo. El botón Test manda un test.ping firmado exactamente igual que un evento real.
Cada envío es un POST con el cuerpo { "evento": "...", "datos": { ... }, "enviado_en": "..." } y estas cabeceras:
X-Talavora-Evento: el evento.
X-Talavora-Version-Evento: la versión de su formato.
X-Talavora-Signature: t=<segundos unix>,v1=<hex>, con v1 = HMAC-SHA256(secreto, t + "." + cuerpo).
Para darlo por bueno: recalcule la firma sobre el cuerpo TAL CUAL llegó (antes de interpretar el JSON), compárela en tiempo constante y rechace un t de hace más de 5 minutos. Conteste 2xx en menos de 10 s y haga el trabajo después; un mismo evento puede llegar dos veces (use su datos.id para no procesarlo de nuevo).
Node.js
import crypto from 'node:crypto'
// cuerpo: el texto EXACTO recibido (sin volver a serializar el JSON)
function firmaValida(secreto, cuerpo, cabecera, toleranciaS = 300) {
const m = /^t=(\d+),v1=([0-9a-f]{64})$/.exec(cabecera || '')
if (!m) return false
const t = Number(m[1])
if (Math.abs(Date.now() / 1000 - t) > toleranciaS) return false
const esperada = crypto.createHmac('sha256', secreto).update(`${t}.${cuerpo}`).digest('hex')
return crypto.timingSafeEqual(Buffer.from(esperada), Buffer.from(m[2]))
}
Python
import hashlib, hmac, re, time
def firma_valida(secreto: str, cuerpo: bytes, cabecera: str, tolerancia_s: int = 300) -> bool:
m = re.fullmatch(r"t=(\d+),v1=([0-9a-f]{64})", cabecera or "")
if not m or abs(time.time() - int(m.group(1))) > tolerancia_s:
return False
firmado = m.group(1).encode() + b"." + cuerpo
esperada = hmac.new(secreto.encode(), firmado, hashlib.sha256).hexdigest()
return hmac.compare_digest(esperada, m.group(2))
La prueba del botón «Test» (firmada igual que un evento real)
mensaje
Los eventos no llevan datos personales que no hagan falta: los de Mantenimiento no dicen quién comunicó una incidencia ni qué técnico lleva una orden (solo con_tecnico).
Para vigilancia externa: no necesita clave y no devuelve datos de nadie. Responde 503 si la base de datos no responde, contesta con error o tarda más de 3 s. La respuesta se reutiliza 20 s (cacheada: true).
Personas de la organización (de alta y de baja), por nombre e id. Paginado por cursor.
Permiso: empleados:read
Parámetro
Dónde
Tipo
Descripción
limit
consulta
integer · 1 a 1000 · por defecto 1000
Filas por página (1 a 1000; por defecto 1000). Fuera de rango, 400.
cursor
consulta
string · patrón · ≤ 2048
El next_cursor de la respuesta anterior, para pedir la página siguiente CON LOS MISMOS FILTROS. Opaco; solo vale para el listado que lo dio (si no, 400).
Del más reciente al más antiguo (desempate por id). desde y hasta son días en UTC (00:00:00 y 23:59:59 UTC). Los marcajes anulados no salen (se archivan aparte; llega el webhook fichaje.anulado).
Permiso: fichajes:read
Parámetro
Dónde
Tipo
Descripción
desde
consulta
string (date)
Día inicial incluido (AAAA-MM-DD, desde las 00:00:00 UTC).
hasta
consulta
string (date)
Día final incluido (AAAA-MM-DD, hasta las 23:59:59 UTC).
empleado_id
consulta
string (uuid)
Solo los de esta persona.
limit
consulta
integer · 1 a 1000 · por defecto 1000
Filas por página (1 a 1000; por defecto 1000). Fuera de rango, 400.
cursor
consulta
string · patrón · ≤ 2048
El next_cursor de la respuesta anterior, para pedir la página siguiente CON LOS MISMOS FILTROS. Opaco; solo vale para el listado que lo dio (si no, 400).
Respuesta 200: data (lista) y next_cursor — 8 campos
Campo
Tipo
Descripción
id
string (uuid)
empleado_id
string (uuid)
tipo
una de: ENTRADA, SALIDA, PAUSA_INICIO, PAUSA_FIN
timestamp
string (date-time)
metodo
string · o null
Vía de registro.
validado
boolean · o null
lat
number · o null
lng
number · o null
Respuestas: 200 · 400 · 401 · 403 · 429 · 500
GET/v1/ausencias
Ausencias
Por fecha de inicio descendente (desempate por id). El campo motivo puede llevar datos sensibles: trátelo como tal.
Permiso: ausencias:read
Parámetro
Dónde
Tipo
Descripción
estado
consulta
string
Estado exacto.
limit
consulta
integer · 1 a 1000 · por defecto 1000
Filas por página (1 a 1000; por defecto 1000). Fuera de rango, 400.
cursor
consulta
string · patrón · ≤ 2048
El next_cursor de la respuesta anterior, para pedir la página siguiente CON LOS MISMOS FILTROS. Opaco; solo vale para el listado que lo dio (si no, 400).
Por nombre e id. Buscar por NIF es lo habitual para cruzar la ficha con la de un ERP.
Permiso: clientes:read
Parámetro
Dónde
Tipo
Descripción
nif
consulta
string
NIF exacto.
limit
consulta
integer · 1 a 1000 · por defecto 1000
Filas por página (1 a 1000; por defecto 1000). Fuera de rango, 400.
cursor
consulta
string · patrón · ≤ 2048
El next_cursor de la respuesta anterior, para pedir la página siguiente CON LOS MISMOS FILTROS. Opaco; solo vale para el listado que lo dio (si no, 400).
Por fecha prevista descendente (las que no tienen fecha, primero) e id.
Permiso: ordenes:read
Parámetro
Dónde
Tipo
Descripción
estado
consulta
string
Estado exacto de la orden.
cliente_id
consulta
string (uuid)
Solo las de este cliente.
desde
consulta
string (date)
fecha_prevista ≥ desde.
hasta
consulta
string (date)
fecha_prevista ≤ hasta.
limit
consulta
integer · 1 a 1000 · por defecto 1000
Filas por página (1 a 1000; por defecto 1000). Fuera de rango, 400.
cursor
consulta
string · patrón · ≤ 2048
El next_cursor de la respuesta anterior, para pedir la página siguiente CON LOS MISMOS FILTROS. Opaco; solo vale para el listado que lo dio (si no, 400).
Filas por página (1 a 1000; por defecto 1000). Fuera de rango, 400.
cursor
consulta
string · patrón · ≤ 2048
El next_cursor de la respuesta anterior, para pedir la página siguiente CON LOS MISMOS FILTROS. Opaco; solo vale para el listado que lo dio (si no, 400).
Por codigo ascendente e id. Cada uno con sus refs_externas. Con ref, solo los que tienen esa referencia externa EXACTA. Además del permiso, la organización tiene que tener Mantenimiento activado (si no, 403).
Permiso: mantenimiento:read
Parámetro
Dónde
Tipo
Descripción
padre_id
consulta
string (uuid)
Solo los hijos directos de este espacio.
raiz
consulta
una de: true
true = solo los espacios raíz (cualquier otro valor se ignora).
activo
consulta
boolean
true = solo los de alta; false = solo los de baja.
updated_since
consulta
string
Modificados desde (AAAA-MM-DD = 00:00 UTC, o fecha y hora ISO 8601).
ref
consulta
string · ≤ 200
Por referencia externa EXACTA: sistema:valor (rfid:E2801160600002084DBE9E71, ifc:2O2Fr$t4X7Zf8NOew3FLOH, inventario:INV-2024/7, erp:…, otro:…; catastro:… solo en espacios) o solo el valor (se busca en todos los sistemas en que tiene sentido). Se normaliza como al guardar (EPC en mayúsculas sin espacios; un GUID de 36 pasa a GlobalId de IFC). Sistema conocido sin valor o más de 200 caracteres: 400.
limit
consulta
integer · 1 a 1000 · por defecto 1000
Filas por página (1 a 1000; por defecto 1000). Fuera de rango, 400.
cursor
consulta
string · patrón · ≤ 2048
El next_cursor de la respuesta anterior, para pedir la página siguiente CON LOS MISMOS FILTROS. Opaco; solo vale para el listado que lo dio (si no, 400).
Respuesta 200: data (lista) y next_cursor — 24 campos
Campo
Tipo
Descripción
id
string (uuid)
padre_id
string (uuid) · o null
tipo_id
string (uuid) · o null
codigo
string
nombre
string
descripcion
string · o null
direccion
string · o null
lat
number · o null
lng
number · o null
responsable_id
string (uuid) · o null
ubicacion_id
string (uuid) · o null
cliente_centro_id
string (uuid) · o null
profundidad
integer
ruta
string
Ids desde la raíz, separados por /.
activo
boolean
created_at
string (date-time)
updated_at
string (date-time)
refs_externas
RefsExternas
Identificadores del activo o del espacio en otros sistemas, uno por sistema y únicos en la organización por sistema. ifc: GlobalId de IFC/BIM (22 caracteres 0-9A-Za-z_$, el primero de 0 a 3); rfid: EPC de la etiqueta (24 o 32 hexadecimales, en mayúsculas); catastro (solo espacios): 14 o 20 caracteres, con las letras de control comprobadas; inventario, erp y otro: texto de una línea de 1 a 80 caracteres. Vacío ({}) si no tiene ninguna.
refs_externas.ifc
string · patrón
refs_externas.rfid
string · patrón
refs_externas.inventario
string · ≤ 80
refs_externas.erp
string · ≤ 80
refs_externas.catastro
string · patrón
Solo espacios.
refs_externas.otro
string · ≤ 80
Respuestas: 200 · 400 · 401 · 403 · 429 · 500
POST/v1/espacios
Dar de alta un espacio
codigo obligatorio y único en la organización (si no, 409). Con id (uuid del integrador) es idempotente: repetirlo devuelve el mismo con repetido: true. Un espacio raíz puede colgar de un centro propio (ubicacion_id) o de un centro de cliente (cliente_centro_id), no de los dos. refs_externas (función mnt_referencias; si no, 403FUNCION_APAGADA): null = quitar una; si un valor ya es de otro activo o espacio, 409 con codeMNT_REF_EN_USO y el espacio no se crea. Además del permiso, la organización tiene que tener Mantenimiento activado (si no, 403).
Permiso: mantenimiento:write
Parámetro
Dónde
Tipo
Descripción
Idempotency-Key
cabecera
string · patrón
Repetir la petición con la misma clave (24 h, por clave de API) devuelve la misma respuesta sin hacer nada dos veces (Idempotent-Replayed: true). Con otra petición, 422; si la primera sigue en curso, 409.
Cuerpo (JSON)
Campo
Tipo
Descripción
id
string (uuid)
Solo en el alta; la hace idempotente.
nombre
string · ≤ 200
Obligatorio en el alta.
codigo
string · patrón
Obligatorio en el alta.
padre_id
string (uuid) · o null
Solo en el alta.
tipo_id
string (uuid) · o null
descripcion
string · ≤ 4000 · o null
direccion
string · ≤ 400 · o null
lat
number · -90 a 90 · o null
lng
number · -180 a 180 · o null
responsable_id
string (uuid) · o null
ubicacion_id
string (uuid) · o null
cliente_centro_id
string (uuid) · o null
refs_externas
RefsExternasEscritura
{ sistema: valor | null }: solo los sistemas que vienen; null o "" = quitarla. Se normaliza antes de guardar (un GUID de 36 pasa a GlobalId de IFC; la EPC, a mayúsculas sin espacios). Formato mal: 400. Necesita la función «Referencias externas» (mnt_referencias): si no, 403 con codeFUNCION_APAGADA. Un valor que ya tiene otro activo o espacio: 409 con codeMNT_REF_EN_USO y no cambia nada (en un alta, no se crea).
404 si no existe o es de otra organización. Con sus refs_externas. Además del permiso, la organización tiene que tener Mantenimiento activado (si no, 403).
Identificadores del activo o del espacio en otros sistemas, uno por sistema y únicos en la organización por sistema. ifc: GlobalId de IFC/BIM (22 caracteres 0-9A-Za-z_$, el primero de 0 a 3); rfid: EPC de la etiqueta (24 o 32 hexadecimales, en mayúsculas); catastro (solo espacios): 14 o 20 caracteres, con las letras de control comprobadas; inventario, erp y otro: texto de una línea de 1 a 80 caracteres. Vacío ({}) si no tiene ninguna.
Solo lo que se envía. padre_id no se cambia por la API (mover un espacio va por la aplicación). refs_externas (función mnt_referencias; si no, 403FUNCION_APAGADA): null = quitar una; si un valor ya es de otro activo o espacio, 409 con codeMNT_REF_EN_USO y no cambia nada (las referencias van primero). Además del permiso, la organización tiene que tener Mantenimiento activado (si no, 403).
Permiso: mantenimiento:write
Parámetro
Dónde
Tipo
Descripción
id *
ruta
string (uuid)
Idempotency-Key
cabecera
string · patrón
Repetir la petición con la misma clave (24 h, por clave de API) devuelve la misma respuesta sin hacer nada dos veces (Idempotent-Replayed: true). Con otra petición, 422; si la primera sigue en curso, 409.
Cuerpo (JSON)
Campo
Tipo
Descripción
id
string (uuid)
Solo en el alta; la hace idempotente.
nombre
string · ≤ 200
Obligatorio en el alta.
codigo
string · patrón
Obligatorio en el alta.
padre_id
string (uuid) · o null
Solo en el alta.
tipo_id
string (uuid) · o null
descripcion
string · ≤ 4000 · o null
direccion
string · ≤ 400 · o null
lat
number · -90 a 90 · o null
lng
number · -180 a 180 · o null
responsable_id
string (uuid) · o null
ubicacion_id
string (uuid) · o null
cliente_centro_id
string (uuid) · o null
refs_externas
RefsExternasEscritura
{ sistema: valor | null }: solo los sistemas que vienen; null o "" = quitarla. Se normaliza antes de guardar (un GUID de 36 pasa a GlobalId de IFC; la EPC, a mayúsculas sin espacios). Formato mal: 400. Necesita la función «Referencias externas» (mnt_referencias): si no, 403 con codeFUNCION_APAGADA. Un valor que ya tiene otro activo o espacio: 409 con codeMNT_REF_EN_USO y no cambia nada (en un alta, no se crea).
Identificadores del activo o del espacio en otros sistemas, uno por sistema y únicos en la organización por sistema. ifc: GlobalId de IFC/BIM (22 caracteres 0-9A-Za-z_$, el primero de 0 a 3); rfid: EPC de la etiqueta (24 o 32 hexadecimales, en mayúsculas); catastro (solo espacios): 14 o 20 caracteres, con las letras de control comprobadas; inventario, erp y otro: texto de una línea de 1 a 80 caracteres. Vacío ({}) si no tiene ninguna.
Por nombre ascendente e id. Cada uno con sus refs_externas. Con ref, solo los que tienen esa referencia externa EXACTA. Además del permiso, la organización tiene que tener Mantenimiento activado (si no, 403).
Permiso: mantenimiento:read
Parámetro
Dónde
Tipo
Descripción
espacio_id
consulta
string (uuid)
Activos ubicados directamente en este espacio.
categoria_id
consulta
string (uuid)
De esta categoría.
estado
consulta
una de: en_servicio, averiado, fuera_servicio, en_reparacion, baja
Estado del activo.
activo
consulta
boolean
true = solo los de alta; false = solo los de baja.
updated_since
consulta
string
Modificados desde (AAAA-MM-DD = 00:00 UTC, o fecha y hora ISO 8601).
ref
consulta
string · ≤ 200
Por referencia externa EXACTA: sistema:valor (rfid:E2801160600002084DBE9E71, ifc:2O2Fr$t4X7Zf8NOew3FLOH, inventario:INV-2024/7, erp:…, otro:…; catastro:… solo en espacios) o solo el valor (se busca en todos los sistemas en que tiene sentido). Se normaliza como al guardar (EPC en mayúsculas sin espacios; un GUID de 36 pasa a GlobalId de IFC). Sistema conocido sin valor o más de 200 caracteres: 400.
limit
consulta
integer · 1 a 1000 · por defecto 1000
Filas por página (1 a 1000; por defecto 1000). Fuera de rango, 400.
cursor
consulta
string · patrón · ≤ 2048
El next_cursor de la respuesta anterior, para pedir la página siguiente CON LOS MISMOS FILTROS. Opaco; solo vale para el listado que lo dio (si no, 400).
Respuesta 200: data (lista) y next_cursor — 35 campos
Campo
Tipo
Descripción
id
string (uuid)
codigo
string · o null
nombre
string
marca
string · o null
modelo
string · o null
num_serie
string · o null
padre_id
string (uuid) · o null
Activo del que es componente.
espacio_id
string (uuid) · o null
categoria_id
string (uuid) · o null
criticidad
una de: baja, media, alta, critica · o null
estado_activo
una de: en_servicio, averiado, fuera_servicio, en_reparacion, baja · o null
responsable_id
string (uuid) · o null
proveedor_id
string (uuid) · o null
cliente_id
string (uuid) · o null
centro_id
string (uuid) · o null
fecha_compra
string (date) · o null
coste_adquisicion
number · o null
instalado_el
string (date) · o null
garantia_hasta
string (date) · o null
ruta
string · o null
activo
boolean
created_at
string (date-time)
updated_at
string (date-time) · o null
lat
number · o null
Latitud PROPIA del activo (WGS84). Sin ella, el activo está donde su espacio.
lng
number · o null
Longitud propia (WGS84), siempre junto con lat.
posicion_precision_m
number · o null
Precisión de la posición en metros (la del GPS, si la hay).
posicion_origen
una de: manual, gps, importacion, api · o null
De dónde salió la posición: a mano, GPS del móvil, importación o API.
posicion_at
string (date-time) · o null
Cuándo se puso la posición.
refs_externas
RefsExternas
Identificadores del activo o del espacio en otros sistemas, uno por sistema y únicos en la organización por sistema. ifc: GlobalId de IFC/BIM (22 caracteres 0-9A-Za-z_$, el primero de 0 a 3); rfid: EPC de la etiqueta (24 o 32 hexadecimales, en mayúsculas); catastro (solo espacios): 14 o 20 caracteres, con las letras de control comprobadas; inventario, erp y otro: texto de una línea de 1 a 80 caracteres. Vacío ({}) si no tiene ninguna.
refs_externas.ifc
string · patrón
refs_externas.rfid
string · patrón
refs_externas.inventario
string · ≤ 80
refs_externas.erp
string · ≤ 80
refs_externas.catastro
string · patrón
Solo espacios.
refs_externas.otro
string · ≤ 80
Respuestas: 200 · 400 · 401 · 403 · 429 · 500
POST/v1/activos
Dar de alta un activo
Mismas reglas que la aplicación: nombre obligatorio (≤ 120), codigo único en la organización (409), estado distinto de baja, referencias de la organización. coste_adquisicion solo con mantenimiento:costes (sin él, 403). Con id es idempotente (200, repetido: true). refs_externas (función mnt_referencias; si no, 403FUNCION_APAGADA): null = quitar una; si un valor ya es de otro activo o espacio, 409 con codeMNT_REF_EN_USO y el activo no se crea. Posición propia con lat + lng (+ precision_m), origen api (función mnt_posicion_activos; si no, 403FUNCION_APAGADA). Además del permiso, la organización tiene que tener Mantenimiento activado (si no, 403).
Permiso: mantenimiento:write
Parámetro
Dónde
Tipo
Descripción
Idempotency-Key
cabecera
string · patrón
Repetir la petición con la misma clave (24 h, por clave de API) devuelve la misma respuesta sin hacer nada dos veces (Idempotent-Replayed: true). Con otra petición, 422; si la primera sigue en curso, 409.
Cuerpo (JSON)
Campo
Tipo
Descripción
id
string (uuid)
Solo en el alta; la hace idempotente.
nombre
string · ≤ 120
Obligatorio en el alta.
codigo
string · patrón · o null
marca
string · ≤ 120 · o null
modelo
string · ≤ 120 · o null
num_serie
string · ≤ 120 · o null
notas
string · ≤ 4000 · o null
padre_id
string (uuid) · o null
espacio_id
string (uuid) · o null
categoria_id
string (uuid) · o null
responsable_id
string (uuid) · o null
proveedor_id
string (uuid) · o null
criticidad
una de: baja, media, alta, critica · o null
estado_activo
una de: en_servicio, averiado, fuera_servicio, en_reparacion
instalado_el
string (date) · o null
garantia_hasta
string (date) · o null
fecha_compra
string (date) · o null
coste_adquisicion
number · 0 a … · o null
Requiere mantenimiento:costes.
refs_externas
RefsExternasEscritura
{ sistema: valor | null }: solo los sistemas que vienen; null o "" = quitarla. Se normaliza antes de guardar (un GUID de 36 pasa a GlobalId de IFC; la EPC, a mayúsculas sin espacios). Formato mal: 400. Necesita la función «Referencias externas» (mnt_referencias): si no, 403 con codeFUNCION_APAGADA. Un valor que ya tiene otro activo o espacio: 409 con codeMNT_REF_EN_USO y no cambia nada (en un alta, no se crea).
lat
number · -90 a 90 · o null
Posición propia, con lng (las dos o ninguna; las dos null = quitarla y vuelve a estar donde su espacio). 0, 0 no se admite. Origen api. Necesita la función «Posición propia de los activos» (mnt_posicion_activos): si no, 403 con codeFUNCION_APAGADA.
lng
number · -180 a 180 · o null
precision_m
number · 0 a 100000 · o null
Precisión de la posición en metros (se guarda como posicion_precision_m).
Los componentes son sus hijos directos; de los documentos vigentes, solo los metadatos (el fichero no se expone). Con sus refs_externas y su posición propia (lat, lng, posicion_*; vacía = está donde su espacio). Además del permiso, la organización tiene que tener Mantenimiento activado (si no, 403).
una de: en_servicio, averiado, fuera_servicio, en_reparacion, baja · o null
responsable_id
string (uuid) · o null
proveedor_id
string (uuid) · o null
cliente_id
string (uuid) · o null
centro_id
string (uuid) · o null
fecha_compra
string (date) · o null
coste_adquisicion
number · o null
instalado_el
string (date) · o null
garantia_hasta
string (date) · o null
ruta
string · o null
activo
boolean
created_at
string (date-time)
updated_at
string (date-time) · o null
lat
number · o null
Latitud PROPIA del activo (WGS84). Sin ella, el activo está donde su espacio.
lng
number · o null
Longitud propia (WGS84), siempre junto con lat.
posicion_precision_m
number · o null
Precisión de la posición en metros (la del GPS, si la hay).
posicion_origen
una de: manual, gps, importacion, api · o null
De dónde salió la posición: a mano, GPS del móvil, importación o API.
posicion_at
string (date-time) · o null
Cuándo se puso la posición.
refs_externas
RefsExternas
Identificadores del activo o del espacio en otros sistemas, uno por sistema y únicos en la organización por sistema. ifc: GlobalId de IFC/BIM (22 caracteres 0-9A-Za-z_$, el primero de 0 a 3); rfid: EPC de la etiqueta (24 o 32 hexadecimales, en mayúsculas); catastro (solo espacios): 14 o 20 caracteres, con las letras de control comprobadas; inventario, erp y otro: texto de una línea de 1 a 80 caracteres. Vacío ({}) si no tiene ninguna.
Solo lo que se envía. La baja va por la aplicación. Si el activo tiene garantías detalladas, garantia_hasta la calcula Talavora y cambiarla da 409. refs_externas (función mnt_referencias; si no, 403FUNCION_APAGADA): null = quitar una; si un valor ya es de otro activo o espacio, 409 con codeMNT_REF_EN_USO y no cambia nada (las referencias van primero). Posición propia con lat + lng (+ precision_m), origen api (función mnt_posicion_activos; si no, 403FUNCION_APAGADA). Las dos null = quitarla. Además del permiso, la organización tiene que tener Mantenimiento activado (si no, 403).
Permiso: mantenimiento:write
Parámetro
Dónde
Tipo
Descripción
id *
ruta
string (uuid)
Idempotency-Key
cabecera
string · patrón
Repetir la petición con la misma clave (24 h, por clave de API) devuelve la misma respuesta sin hacer nada dos veces (Idempotent-Replayed: true). Con otra petición, 422; si la primera sigue en curso, 409.
Cuerpo (JSON)
Campo
Tipo
Descripción
id
string (uuid)
Solo en el alta; la hace idempotente.
nombre
string · ≤ 120
Obligatorio en el alta.
codigo
string · patrón · o null
marca
string · ≤ 120 · o null
modelo
string · ≤ 120 · o null
num_serie
string · ≤ 120 · o null
notas
string · ≤ 4000 · o null
padre_id
string (uuid) · o null
espacio_id
string (uuid) · o null
categoria_id
string (uuid) · o null
responsable_id
string (uuid) · o null
proveedor_id
string (uuid) · o null
criticidad
una de: baja, media, alta, critica · o null
estado_activo
una de: en_servicio, averiado, fuera_servicio, en_reparacion
instalado_el
string (date) · o null
garantia_hasta
string (date) · o null
fecha_compra
string (date) · o null
coste_adquisicion
number · 0 a … · o null
Requiere mantenimiento:costes.
refs_externas
RefsExternasEscritura
{ sistema: valor | null }: solo los sistemas que vienen; null o "" = quitarla. Se normaliza antes de guardar (un GUID de 36 pasa a GlobalId de IFC; la EPC, a mayúsculas sin espacios). Formato mal: 400. Necesita la función «Referencias externas» (mnt_referencias): si no, 403 con codeFUNCION_APAGADA. Un valor que ya tiene otro activo o espacio: 409 con codeMNT_REF_EN_USO y no cambia nada (en un alta, no se crea).
lat
number · -90 a 90 · o null
Posición propia, con lng (las dos o ninguna; las dos null = quitarla y vuelve a estar donde su espacio). 0, 0 no se admite. Origen api. Necesita la función «Posición propia de los activos» (mnt_posicion_activos): si no, 403 con codeFUNCION_APAGADA.
lng
number · -180 a 180 · o null
precision_m
number · 0 a 100000 · o null
Precisión de la posición en metros (se guarda como posicion_precision_m).
una de: en_servicio, averiado, fuera_servicio, en_reparacion, baja · o null
responsable_id
string (uuid) · o null
proveedor_id
string (uuid) · o null
cliente_id
string (uuid) · o null
centro_id
string (uuid) · o null
fecha_compra
string (date) · o null
coste_adquisicion
number · o null
instalado_el
string (date) · o null
garantia_hasta
string (date) · o null
ruta
string · o null
activo
boolean
created_at
string (date-time)
updated_at
string (date-time) · o null
lat
number · o null
Latitud PROPIA del activo (WGS84). Sin ella, el activo está donde su espacio.
lng
number · o null
Longitud propia (WGS84), siempre junto con lat.
posicion_precision_m
number · o null
Precisión de la posición en metros (la del GPS, si la hay).
posicion_origen
una de: manual, gps, importacion, api · o null
De dónde salió la posición: a mano, GPS del móvil, importación o API.
posicion_at
string (date-time) · o null
Cuándo se puso la posición.
refs_externas
RefsExternas
Identificadores del activo o del espacio en otros sistemas, uno por sistema y únicos en la organización por sistema. ifc: GlobalId de IFC/BIM (22 caracteres 0-9A-Za-z_$, el primero de 0 a 3); rfid: EPC de la etiqueta (24 o 32 hexadecimales, en mayúsculas); catastro (solo espacios): 14 o 20 caracteres, con las letras de control comprobadas; inventario, erp y otro: texto de una línea de 1 a 80 caracteres. Vacío ({}) si no tiene ninguna.
Por created_at descendente e id. No incluye quién la comunicó. Además del permiso, la organización tiene que tener Mantenimiento activado (si no, 403).
Permiso: mantenimiento:read
Parámetro
Dónde
Tipo
Descripción
estado
consulta
una de: nueva, en_revision, aceptada, convertida, rechazada, duplicada, cerrada
Estado.
prioridad
consulta
una de: baja, normal, alta, urgente
Prioridad.
activo_id
consulta
string (uuid)
De este activo.
espacio_id
consulta
string (uuid)
De este espacio.
updated_since
consulta
string
Modificados desde (AAAA-MM-DD = 00:00 UTC, o fecha y hora ISO 8601).
limit
consulta
integer · 1 a 1000 · por defecto 1000
Filas por página (1 a 1000; por defecto 1000). Fuera de rango, 400.
cursor
consulta
string · patrón · ≤ 2048
El next_cursor de la respuesta anterior, para pedir la página siguiente CON LOS MISMOS FILTROS. Opaco; solo vale para el listado que lo dio (si no, 400).
Respuesta 200: data (lista) y next_cursor — 17 campos
Campo
Tipo
Descripción
id
string (uuid)
codigo
string · patrón
titulo
string
descripcion
string · o null
prioridad
una de: baja, normal, alta, urgente
espacio_id
string (uuid) · o null
activo_id
string (uuid) · o null
lat
number · o null
lng
number · o null
estado
una de: nueva, en_revision, aceptada, convertida, rechazada, duplicada, cerrada
motivo_rechazo
string · o null
origen
una de: interno, tecnico, portal_cliente, api, publico, proveedor
Por dónde entró: interno (una persona de la organización), tecnico (un técnico en campo), api, publico (el QR público, sin cuenta), proveedor (el portal del proveedor). portal_cliente está reservado.
ot_id
string (uuid) · o null
duplicada_de
string (uuid) · o null
resuelta_at
string (date-time) · o null
created_at
string (date-time)
updated_at
string (date-time)
Respuestas: 200 · 400 · 401 · 403 · 429 · 500
POST/v1/incidencias
Comunicar una incidencia
Nace en estado nueva, con origen = api, sin persona que la comunica y con código INC-AAAA-NNNN, y entra en la bandeja de la organización. Si se indica el activo y no el espacio, toma el espacio del activo. El activo y el espacio tienen que ser de la organización (si no, 409). Con id (uuid del integrador) es idempotente, también si dos peticiones con el mismo id llegan a la vez. Además del permiso, la organización tiene que tener Mantenimiento activado (si no, 403).
Permiso: mantenimiento:write
Parámetro
Dónde
Tipo
Descripción
Idempotency-Key
cabecera
string · patrón
Repetir la petición con la misma clave (24 h, por clave de API) devuelve la misma respuesta sin hacer nada dos veces (Idempotent-Replayed: true). Con otra petición, 422; si la primera sigue en curso, 409.
una de: nueva, en_revision, aceptada, convertida, rechazada, duplicada, cerrada
motivo_rechazo
string · o null
origen
una de: interno, tecnico, portal_cliente, api, publico, proveedor
Por dónde entró: interno (una persona de la organización), tecnico (un técnico en campo), api, publico (el QR público, sin cuenta), proveedor (el portal del proveedor). portal_cliente está reservado.
Por nombre e id. Si la instalación aún no tiene el módulo de preventivo, 404 con un mensaje explícito. Además del permiso, la organización tiene que tener Mantenimiento activado (si no, 403).
Permiso: mantenimiento:read
Parámetro
Dónde
Tipo
Descripción
updated_since
consulta
string
Modificados desde (AAAA-MM-DD = 00:00 UTC, o fecha y hora ISO 8601).
limit
consulta
integer · 1 a 1000 · por defecto 1000
Filas por página (1 a 1000; por defecto 1000). Fuera de rango, 400.
cursor
consulta
string · patrón · ≤ 2048
El next_cursor de la respuesta anterior, para pedir la página siguiente CON LOS MISMOS FILTROS. Opaco; solo vale para el listado que lo dio (si no, 400).
Contadores de los activos (horas, km, ciclos, kWh, m³…)
Por nombre e id, con la última lectura (valor_actual, leido_at). En uno acumulativo el valor nunca baja salvo un reinicio, que anota una persona con su motivo. Además del permiso, la organización tiene que tener Mantenimiento activado (si no, 403).
Permiso: mantenimiento:read
Parámetro
Dónde
Tipo
Descripción
activo_id
consulta
string (uuid)
De este activo.
activo
consulta
boolean
true = solo los de alta; false = solo los de baja.
updated_since
consulta
string
Modificados desde (AAAA-MM-DD = 00:00 UTC, o fecha y hora ISO 8601).
limit
consulta
integer · 1 a 1000 · por defecto 1000
Filas por página (1 a 1000; por defecto 1000). Fuera de rango, 400.
cursor
consulta
string · patrón · ≤ 2048
El next_cursor de la respuesta anterior, para pedir la página siguiente CON LOS MISMOS FILTROS. Opaco; solo vale para el listado que lo dio (si no, 400).
Una lectura PUNTUAL (no una serie de segundos: un dispositivo agrega en origen, como mucho una por contador y cuarto de hora). Idempotente por id: reenviar la misma devuelve 200 con repetido: true. La base la valida: en un contador acumulativo no puede ser menor que la anterior ni mayor que una posterior (409 con codeMNT_LECTURA_BAJA o MNT_LECTURA_SUPERA), ni del futuro (5 minutos de margen, 400 con codeMNT_LECTURA_FUTURA). Si llega al umbral de un preventivo por uso, la orden se crea en el acto. Un reinicio de contador no entra por la API. Además del permiso, la organización tiene que tener Mantenimiento activado (si no, 403).
Permiso: mantenimiento:write
Parámetro
Dónde
Tipo
Descripción
Idempotency-Key
cabecera
string · patrón
Repetir la petición con la misma clave (24 h, por clave de API) devuelve la misma respuesta sin hacer nada dos veces (Idempotent-Replayed: true). Con otra petición, 422; si la primera sigue en curso, 409.
Cuerpo (JSON)
Campo
Tipo
Descripción
id
string (uuid)
Lo pone el integrador: la hace idempotente.
contador_id *
string (uuid)
valor *
number o string
Hasta 3 decimales; |valor| ≤ 1e12. También como texto con punto decimal.
Por created_at descendente e id. Sin datos personales: ni el técnico (solo con_tecnico), ni quién la creó, ni la descripción, ni las notas. desde/hasta filtran por el día de ALTA; updated_since por updated_at (las órdenes sin updated_at cuentan por su alta o su cierre). Además del permiso, la organización tiene que tener Mantenimiento activado (si no, 403).
Permiso: mantenimiento:read
Parámetro
Dónde
Tipo
Descripción
estado
consulta
una de: borrador, planificada, en_curso, pausada, cerrada, facturada, cancelada
Estado.
tipo
consulta
una de: correctivo, preventivo, inspeccion, mejora, otro
Tipo de mantenimiento.
activo_id
consulta
string (uuid)
De este activo.
espacio_id
consulta
string (uuid)
De este espacio.
desde
consulta
string
Alta desde (AAAA-MM-DD = 00:00 UTC, o fecha y hora ISO 8601).
hasta
consulta
string
Alta hasta (AAAA-MM-DD incluye ese día entero, o fecha y hora ISO 8601).
updated_since
consulta
string
Modificados desde (AAAA-MM-DD = 00:00 UTC, o fecha y hora ISO 8601).
limit
consulta
integer · 1 a 1000 · por defecto 1000
Filas por página (1 a 1000; por defecto 1000). Fuera de rango, 400.
cursor
consulta
string · patrón · ≤ 2048
El next_cursor de la respuesta anterior, para pedir la página siguiente CON LOS MISMOS FILTROS. Opaco; solo vale para el listado que lo dio (si no, 400).
Respuesta 200: data (lista) y next_cursor — 27 campos
Campo
Tipo
Descripción
id
string (uuid)
codigo
string · o null
titulo
string · o null
estado
una de: borrador, planificada, en_curso, pausada, cerrada, facturada, cancelada
prioridad
string · o null
tipo_mantenimiento
una de: correctivo, preventivo, inspeccion, mejora, otro
activo_id
string (uuid) · o null
espacio_id
string (uuid) · o null
incidencia_id
string (uuid) · o null
plan_activo_id
string (uuid) · o null
proveedor_id
string (uuid) · o null
brigada_id
string (uuid) · o null
con_tecnico
boolean
Tiene técnico asignado (quién, no).
fecha_prevista
string (date) · o null
fecha_programada
string (date) · o null
fecha_limite
string (date) · o null
iniciada_at
string (date-time) · o null
cerrada_at
string (date-time) · o null
cancelada_at
string (date-time) · o null
duracion_estimada_min
integer · o null
modo_fallo_id
string (uuid) · o null
causa_id
string (uuid) · o null
accion_id
string (uuid) · o null
garantia_id
string (uuid) · o null
reclamacion_garantia
boolean
created_at
string (date-time)
updated_at
string (date-time) · o null
Respuestas: 200 · 400 · 401 · 403 · 429 · 500
GET/v1/mantenimiento/ordenes/{id}
Una orden de mantenimiento
Con paradas, materiales y minutos por tipo (trabajo, desplazamiento, espera). Con mantenimiento:costes, además coste y el coste, el precio y el IVA de cada material. Además del permiso, la organización tiene que tener Mantenimiento activado (si no, 403).
Vistas de Mantenimiento de solo lectura con nombres y columnas estables, para Power BI, Tableau o Metabase, en JSON o CSV. Permiso bi:read dicho expresamente en la clave y función «Vistas para BI» (mnt_bi) activada.
Las vistas que puede leer esta clave, con su ruta y sus columnas en orden (sin las de importes si la clave no tiene mantenimiento:costes). Requiere el permiso bi:read DICHO EN LA CLAVE (el comodín * de las claves antiguas no lo abre), Mantenimiento activado y la función «Vistas para BI» (mnt_bi). Las columnas de importes solo salen con mantenimiento:costes. Guía para Power BI, Tableau y Metabase en la documentación.
una de: activos, espacios, ordenes, incidencias, preventivo, lecturas, sla_ot, fiabilidad_activos
Las vistas de BI. Columnas de cada una, en su orden, en x-talavora-columnas (las de x-talavora-columnas-coste solo salen con mantenimiento:costes). Nombres y columnas ESTABLES: solo se añaden columnas al final.
ruta
string
columnas
lista de string
Respuestas: 200 · 401 · 403 · 429 · 500 · 503
GET/v1/bi/{vista}
Una vista de BI, por páginas (JSON o CSV)
Filas de UNA vista de la organización de la clave (la base filtra por ella; no hay forma de pedir otra), en orden estable por su clave (id; ot_id en sla_ot, activo_id en fiabilidad_activos), hasta limit (1 a 1000, por defecto 1000). cursor es opaco y solo vale para la vista que lo dio. Sin datos personales: de las personas solo ids; ni descripciones, ni notas, ni quién comunicó o anotó. JSON: { data, next_cursor, columnas }. CSV (format=csv o Accept: text/csv): UTF-8 con BOM, coma y CRLF, fechas ISO 8601 y punto decimal; la página siguiente, en las cabeceras X-Next-Cursor y Link: <…>; rel="next". Requiere el permiso bi:read DICHO EN LA CLAVE (el comodín * de las claves antiguas no lo abre), Mantenimiento activado y la función «Vistas para BI» (mnt_bi). Las columnas de importes solo salen con mantenimiento:costes. Guía para Power BI, Tableau y Metabase en la documentación.
Permiso: bi:read
Parámetro
Dónde
Tipo
Descripción
vista *
ruta
una de: activos, espacios, ordenes, incidencias, preventivo, lecturas, sla_ot, fiabilidad_activos
limit
consulta
integer · 1 a 1000 · por defecto 1000
Filas por página (1 a 1000; por defecto 1000). Fuera de rango, 400.
cursor
consulta
string · patrón · ≤ 2048
El next_cursor de la respuesta anterior, para pedir la página siguiente CON LOS MISMOS FILTROS. Opaco; solo vale para el listado que lo dio (si no, 400).
format
consulta
una de: json, csv · por defecto json
csv para CSV (también con Accept: text/csv); json por defecto. Otro valor: 400.
Pasarelas, sensores, BMS o PLC que mandan lecturas de los contadores de Mantenimiento con SU credencial (tlv_dev_…), no con la clave de la organización. Función «Dispositivos conectados» (mnt_iot).
Con la credencial del aparato (tlv_dev_…), NO con una clave de API; función «Dispositivos conectados» (mnt_iot) y Mantenimiento activados. Hasta 500 lecturas y 256 KB por petición, y su cupo de lecturas por minuto (429 + Retry-After; el cupo de 600 por hora de las claves no aplica). Cada punto es un canal mapeado a un contador; Talavora convierte el valor bruto (× factor + desplazamiento) y guarda COMO MUCHO una lectura por punto e intervalo (la última, con cuántas llegaron, la mínima y la máxima); los umbrales miran todas. Idempotente por (dispositivo, punto, hora de la lectura): reenviar el lote no duplica nada (lo ya recibido sale repetida; el intervalo que ya se guardó, también). No usa Idempotency-Key. Respuesta 200 también con lecturas rechazadas, una a una en detalle con su code: no reintentar esas. 503 + Retry-After si la base no responde: reenviar el lote.
Credencial del dispositivo (tlv_dev_…), no una clave de API.
Parámetro
Dónde
Tipo
Descripción
X-Talavora-Version
cabecera
string · ≤ 60
Versión del firmware o del flujo de la pasarela (hasta 60 caracteres; se ve en la ficha del aparato). También vale version en el cuerpo.
Cuerpo (JSON)
Campo
Tipo
Descripción
version
string · ≤ 60
Versión del firmware o del flujo (como X-Talavora-Version).
Lecturas que han quedado en Talavora con esta petición (intervalos cerrados y atrasadas).
disparos
integer
Umbrales que han saltado.
cupo
object
cupo.por_minuto
integer
cupo.restante
integer
hora_servidor
string (date-time)
detalle
lista de object
Una entrada por lectura del lote, en su orden.
detalle[].i
integer
Posición en el lote (desde 0).
detalle[].id
string (uuid)
El id que mandó la pasarela, si lo mandó.
detalle[].estado
una de: agregada, guardada, repetida, rechazada
agregada: entra en el intervalo abierto; guardada: una atrasada que se guarda sola; repetida: ya estaba (reenvío); rechazada: con su code (no reintentarla).
detalle[].code
string · patrón
Solo en las rechazadas: MNT_IOT_FORMATO, MNT_IOT_PUNTO, MNT_IOT_PUNTO_BAJA, MNT_IOT_ANTIGUA, MNT_CONTADOR_BAJA, MNT_LECTURA_VALOR, MNT_LECTURA_FUTURA, MNT_LECTURA_BAJA, MNT_LECTURA_SUPERA, MNT_LECTURA_NEGATIVA (u otro MNT_… de las reglas de los contadores).
detalle[].error
string
Texto, en las que rechaza la API antes de llegar a la base (forma, valor, hora).
Con la credencial del aparato (tlv_dev_…), NO con una clave de API; función mnt_iot. Cuerpo opcional. Devuelve la hora del servidor, el desvío del reloj del aparato (si manda hora), su cupo y los puntos activos que debe mandar. Cada 5–15 minutos basta: más a menudo no escribe nada (solo se anota si ha pasado un minuto o cambia la versión o el reloj), así que repetirlo no tiene efectos. No usa Idempotency-Key.
Credencial del dispositivo (tlv_dev_…), no una clave de API.
Parámetro
Dónde
Tipo
Descripción
X-Talavora-Version
cabecera
string · ≤ 60
Versión del firmware o del flujo de la pasarela (hasta 60 caracteres; se ve en la ficha del aparato). También vale version en el cuerpo.
Cuerpo (JSON)
Campo
Tipo
Descripción
version
string · ≤ 60
Versión del firmware o del flujo (si no, la de X-Talavora-Version).
hora
string (date-time) o number
La hora del aparato (ISO 8601 con zona o epoch): Talavora devuelve el desvío de su reloj.