Volver al inicio

Para integradores · versión 1.3.0

API pública de Talavora

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.

URL base
https://yaladpjmdzxwnxmvepqg.supabase.co/functions/v1/api-publica
Formato
JSON en UTF-8; fechas ISO 8601 (los días, AAAA-MM-DD); identificadores uuid.
Especificación
OpenAPI 3.1.0, con todas las rutas, esquemas y webhooks.
Descargar el OpenAPI (JSON)

Primeros pasos: pedir la clave

  1. 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).
  2. 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.
  3. 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.
  4. 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.

Primera llamada
export TALAVORA_API_KEY='tlv_pub_…'
curl 'https://yaladpjmdzxwnxmvepqg.supabase.co/functions/v1/api-publica/v1/me' \
  -H "Authorization: Bearer $TALAVORA_API_KEY"
Respuesta
{
  "data": {
    "empresa_id": "3f2b8c1e-5d4a-4e7b-9c6d-1a2b3c4d5e6f",
    "scopes": ["fichajes:read", "ausencias:read"]
  }
}

Autenticación y permisos

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).

PermisoQué abre
empleados:readPersonas
fichajes:readFichajes
ausencias:readAusencias
clientes:readClientes
ordenes:readÓrdenes de trabajo y su parte
facturas:readFacturas de venta
mantenimiento:readLeer Mantenimiento
mantenimiento:writeComunicar incidencias, anotar lecturas y dar de alta o cambiar activos y espacios (nunca borra)
mantenimiento:costesImportes de Mantenimiento (coste de órdenes y materiales; coste de adquisición al escribir)
bi:readVistas 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.

Recorrer los fichajes de un mes
cursor=""
while :; do
  r=$(curl -s "https://yaladpjmdzxwnxmvepqg.supabase.co/functions/v1/api-publica/v1/fichajes?desde=2026-10-01&hasta=2026-10-31&limit=500${cursor:+&cursor=$cursor}" \
    -H "Authorization: Bearer $TALAVORA_API_KEY")
  echo "$r" | jq -c '.data[]'
  cursor=$(echo "$r" | jq -r '.next_cursor // empty')
  [ -z "$cursor" ] && break
done

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ódigoCuándo
400Parámetro, cursor o cuerpo no válido. El texto dice cuál.
401Falta la clave, no es válida, está revocada o ha caducado.
403A 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 code FUNCION_APAGADA y su funcion, o un texto que la nombra).
404La ruta no existe, o el recurso no existe o es de otra organización (nunca se distingue).
405Método no admitido en esa ruta.
409Conflicto: 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.
413Solo en Dispositivos: el lote pasa de 256 KB; pártalo.
422Esa Idempotency-Key ya se usó con otra petición.
429Má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).
500Error 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))
EventoCuándoDatos
fichaje.creadoSe ha registrado un fichaje (no los importados)id, empleado_id, tipo, timestamp, metodo, validado
fichaje.editadoSe ha corregido la hora o el tipo de un fichajeid, empleado_id, antes, despues, motivo, editado_por
fichaje.anuladoSe ha anulado un fichaje (un fichaje no se borra: se anula con motivo)id, empleado_id, anulado_at, motivo, fichaje
ausencia.aprobadaSe ha aprobado una ausenciaid, empleado_id, fecha_inicio, fecha_fin, tipo
incidencia.creadaSe ha creado una incidencia de mantenimiento (cualquier origen)id, codigo, titulo, prioridad, estado, origen, activo_id, espacio_id, created_at
ot_mantenimiento.creadaSe ha creado una orden de mantenimiento (o una orden pasa a serlo)version, id, codigo, titulo, tipo_mantenimiento, estado, prioridad, activo_id, espacio_id, incidencia_id, plan_activo_id, proveedor_id, fecha_prevista, fecha_programada, fecha_limite, created_at
ot_mantenimiento.asignadaUna orden de mantenimiento pasa a tener técnico, brigada o proveedor (o cambia)version, id, codigo, titulo, tipo_mantenimiento, estado, a, con_tecnico, brigada_id, proveedor_id, activo_id, espacio_id, fecha_prevista, fecha_programada, asignada_at
ot_mantenimiento.cerradaSe ha cerrado una orden de mantenimientoid, codigo, titulo, tipo_mantenimiento, activo_id, espacio_id, incidencia_id, proveedor_id, cerrada_at
activo.estado_cambiadoUn activo entra en (o sale de) averiado o fuera de servicioversion, id, codigo, nombre, estado, estado_anterior, espacio_id, categoria_id, criticidad, cambiado_at
preventivo.vencidoUn preventivo sigue abierto y su fecha límite ya pasó (barrido diario, 05:30 UTC)version, id, codigo, titulo, estado, activo_id, espacio_id, plan_activo_id, plan_id, fecha_programada, fecha_limite, dias_vencido
test.pingLa 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).

Referencia: Utilidad

Comprobar la clave y el estado de la plataforma.

GET/v1/me

Organización y permisos de la clave

Comprueba que la clave funciona y dice de qué organización es y qué permisos tiene. No necesita ningún permiso concreto.

Cualquier clave válida.

Ejemplo
curl 'https://yaladpjmdzxwnxmvepqg.supabase.co/functions/v1/api-publica/v1/me' \
  -H "Authorization: Bearer $TALAVORA_API_KEY"
Respuesta 200: data — 2 campos
CampoTipoDescripción
empresa_idstring (uuid)
scopeslista de Scope

Respuestas: 200 · 401 · 429 · 500

GET/v1/salud

Estado de la plataforma (sin clave)

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).

Sin clave.

Ejemplo
curl 'https://yaladpjmdzxwnxmvepqg.supabase.co/functions/v1/api-publica/v1/salud'
Respuesta 200: data — 4 campos
CampoTipoDescripción
okboolean
base_msintegerMilisegundos de la consulta de comprobación.
motivostring
cacheadaboolean

Respuestas: 200 · 503

Referencia: Registro horario

Personas, fichajes y ausencias.

GET/v1/empleados

Personas

Personas de la organización (de alta y de baja), por nombre e id. Paginado por cursor.

Permiso: empleados:read

ParámetroDóndeTipoDescripción
limitconsultainteger · 1 a 1000 · por defecto 1000Filas por página (1 a 1000; por defecto 1000). Fuera de rango, 400.
cursorconsultastring · patrón · ≤ 2048El 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).
Ejemplo
curl 'https://yaladpjmdzxwnxmvepqg.supabase.co/functions/v1/api-publica/v1/empleados' \
  -H "Authorization: Bearer $TALAVORA_API_KEY"
Respuesta 200: data (lista) y next_cursor — 6 campos
CampoTipoDescripción
idstring (uuid)
nombrestring · o null
apellidosstring · o null
emailstring · o null
rolstring · o nullEMPLEADO, SUBADMIN, ADMIN…
activoboolean · o null

Respuestas: 200 · 400 · 401 · 403 · 429 · 500

GET/v1/empleados/{id}

Una persona

Con su fecha de alta y de nacimiento. 404 si no existe o es de otra organización.

Permiso: empleados:read

ParámetroDóndeTipoDescripción
id *rutastring (uuid)
Ejemplo
curl 'https://yaladpjmdzxwnxmvepqg.supabase.co/functions/v1/api-publica/v1/empleados/3f2b8c1e-5d4a-4e7b-9c6d-1a2b3c4d5e6f' \
  -H "Authorization: Bearer $TALAVORA_API_KEY"
Respuesta 200: data — 8 campos
CampoTipoDescripción
idstring (uuid)
nombrestring · o null
apellidosstring · o null
emailstring · o null
rolstring · o nullEMPLEADO, SUBADMIN, ADMIN…
activoboolean · o null
fecha_altastring (date) · o null
fecha_nacimientostring (date) · o null

Respuestas: 200 · 400 · 401 · 403 · 404 · 429 · 500

GET/v1/fichajes

Marcajes del registro de jornada

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ámetroDóndeTipoDescripción
desdeconsultastring (date)Día inicial incluido (AAAA-MM-DD, desde las 00:00:00 UTC).
hastaconsultastring (date)Día final incluido (AAAA-MM-DD, hasta las 23:59:59 UTC).
empleado_idconsultastring (uuid)Solo los de esta persona.
limitconsultainteger · 1 a 1000 · por defecto 1000Filas por página (1 a 1000; por defecto 1000). Fuera de rango, 400.
cursorconsultastring · patrón · ≤ 2048El 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).
Ejemplo
curl 'https://yaladpjmdzxwnxmvepqg.supabase.co/functions/v1/api-publica/v1/fichajes' \
  -H "Authorization: Bearer $TALAVORA_API_KEY"
Respuesta 200: data (lista) y next_cursor — 8 campos
CampoTipoDescripción
idstring (uuid)
empleado_idstring (uuid)
tipouna de: ENTRADA, SALIDA, PAUSA_INICIO, PAUSA_FIN
timestampstring (date-time)
metodostring · o nullVía de registro.
validadoboolean · o null
latnumber · o null
lngnumber · 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ámetroDóndeTipoDescripción
estadoconsultastringEstado exacto.
limitconsultainteger · 1 a 1000 · por defecto 1000Filas por página (1 a 1000; por defecto 1000). Fuera de rango, 400.
cursorconsultastring · patrón · ≤ 2048El 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).
Ejemplo
curl 'https://yaladpjmdzxwnxmvepqg.supabase.co/functions/v1/api-publica/v1/ausencias' \
  -H "Authorization: Bearer $TALAVORA_API_KEY"
Respuesta 200: data (lista) y next_cursor — 8 campos
CampoTipoDescripción
idstring (uuid)
empleado_idstring (uuid)
tipostring · o null
fecha_iniciostring (date)
fecha_finstring (date)
diasnumber · o null
estadostringCoexisten dos grafías de los estados finales; trátelas como iguales: APROBADO/APROBADA, RECHAZADO/RECHAZADA, CANCELADA/CANCELADO.
motivostring · o null

Respuestas: 200 · 400 · 401 · 403 · 429 · 500

Referencia: Servicio de campo y facturación

Clientes, órdenes de trabajo con su parte, y facturas de venta.

GET/v1/clientes

Clientes

Por nombre e id. Buscar por NIF es lo habitual para cruzar la ficha con la de un ERP.

Permiso: clientes:read

ParámetroDóndeTipoDescripción
nifconsultastringNIF exacto.
limitconsultainteger · 1 a 1000 · por defecto 1000Filas por página (1 a 1000; por defecto 1000). Fuera de rango, 400.
cursorconsultastring · patrón · ≤ 2048El 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).
Ejemplo
curl 'https://yaladpjmdzxwnxmvepqg.supabase.co/functions/v1/api-publica/v1/clientes' \
  -H "Authorization: Bearer $TALAVORA_API_KEY"
Respuesta 200: data (lista) y next_cursor — 11 campos
CampoTipoDescripción
idstring (uuid)
nombrestring · o null
nifstring · o null
emailstring · o null
telefonostring · o null
direccionstring · o null
ciudadstring · o null
cpstring · o null
provinciastring · o null
activoboolean · o null
created_atstring (date-time) · o null

Respuestas: 200 · 400 · 401 · 403 · 429 · 500

GET/v1/clientes/{id}

Un cliente

404 si no existe o es de otra organización.

Permiso: clientes:read

ParámetroDóndeTipoDescripción
id *rutastring (uuid)
Ejemplo
curl 'https://yaladpjmdzxwnxmvepqg.supabase.co/functions/v1/api-publica/v1/clientes/3f2b8c1e-5d4a-4e7b-9c6d-1a2b3c4d5e6f' \
  -H "Authorization: Bearer $TALAVORA_API_KEY"
Respuesta 200: data — 11 campos
CampoTipoDescripción
idstring (uuid)
nombrestring · o null
nifstring · o null
emailstring · o null
telefonostring · o null
direccionstring · o null
ciudadstring · o null
cpstring · o null
provinciastring · o null
activoboolean · o null
created_atstring (date-time) · o null

Respuestas: 200 · 400 · 401 · 403 · 404 · 429 · 500

GET/v1/ordenes

Órdenes de trabajo

Por fecha prevista descendente (las que no tienen fecha, primero) e id.

Permiso: ordenes:read

ParámetroDóndeTipoDescripción
estadoconsultastringEstado exacto de la orden.
cliente_idconsultastring (uuid)Solo las de este cliente.
desdeconsultastring (date)fecha_prevista ≥ desde.
hastaconsultastring (date)fecha_prevista ≤ hasta.
limitconsultainteger · 1 a 1000 · por defecto 1000Filas por página (1 a 1000; por defecto 1000). Fuera de rango, 400.
cursorconsultastring · patrón · ≤ 2048El 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).
Ejemplo
curl 'https://yaladpjmdzxwnxmvepqg.supabase.co/functions/v1/api-publica/v1/ordenes' \
  -H "Authorization: Bearer $TALAVORA_API_KEY"
Respuesta 200: data (lista) y next_cursor — 16 campos
CampoTipoDescripción
idstring (uuid)
codigostring · o null
titulostring · o null
estadostring · o null
prioridadstring · o null
cliente_idstring (uuid) · o null
asignado_astring (uuid) · o null
fecha_previstastring · o null
duracion_estimada_mininteger · o null
cerrada_atstring (date-time) · o null
albaran_numerostring · o null
direccionstring · o null
poblacionstring · o null
cpstring · o null
provinciastring · o null
created_atstring (date-time) · o null

Respuestas: 200 · 400 · 401 · 403 · 429 · 500

GET/v1/ordenes/{id}

Una orden de trabajo

404 si no existe o es de otra organización.

Permiso: ordenes:read

ParámetroDóndeTipoDescripción
id *rutastring (uuid)
Ejemplo
curl 'https://yaladpjmdzxwnxmvepqg.supabase.co/functions/v1/api-publica/v1/ordenes/3f2b8c1e-5d4a-4e7b-9c6d-1a2b3c4d5e6f' \
  -H "Authorization: Bearer $TALAVORA_API_KEY"
Respuesta 200: data — 16 campos
CampoTipoDescripción
idstring (uuid)
codigostring · o null
titulostring · o null
estadostring · o null
prioridadstring · o null
cliente_idstring (uuid) · o null
asignado_astring (uuid) · o null
fecha_previstastring · o null
duracion_estimada_mininteger · o null
cerrada_atstring (date-time) · o null
albaran_numerostring · o null
direccionstring · o null
poblacionstring · o null
cpstring · o null
provinciastring · o null
created_atstring (date-time) · o null

Respuestas: 200 · 400 · 401 · 403 · 404 · 429 · 500

GET/v1/ordenes/{id}/parte

Parte de trabajo de una orden

Tiempos, materiales y la firma vigente, sin la imagen (con hash_parte para comprobar que el parte no ha cambiado).

Permiso: ordenes:read

ParámetroDóndeTipoDescripción
id *rutastring (uuid)
Ejemplo
curl 'https://yaladpjmdzxwnxmvepqg.supabase.co/functions/v1/api-publica/v1/ordenes/3f2b8c1e-5d4a-4e7b-9c6d-1a2b3c4d5e6f/parte' \
  -H "Authorization: Bearer $TALAVORA_API_KEY"
Respuesta 200: data — 27 campos
CampoTipoDescripción
ordenobject
orden.idstring (uuid)
orden.codigostring · o null
orden.titulostring · o null
orden.estadostring · o null
orden.fecha_previstastring · o null
orden.cerrada_atstring (date-time) · o null
orden.albaran_numerostring · o null
tiemposlista de object
tiempos[].idstring (uuid)
tiempos[].empleado_idstring (uuid) · o null
tiempos[].tipostring · o null
tiempos[].iniciostring (date-time) · o null
tiempos[].finstring (date-time) · o null
tiempos[].minutosnumber · o null
tiempos[].notasstring · o null
materialeslista de object
materiales[].idstring (uuid)
materiales[].conceptostring · o null
materiales[].cantidadnumber · o null
materiales[].precionumber · o null
materiales[].iva_pctnumber · o null
firmaobject · o null
firma.firmantestring · o null
firma.dnistring · o null
firma.hash_partestring · o null
firma.firmado_atstring (date-time) · o null

Respuestas: 200 · 401 · 403 · 404 · 429 · 500

GET/v1/facturas

Facturas de venta

Por fecha descendente e id.

Permiso: facturas:read

ParámetroDóndeTipoDescripción
estadoconsultastringEstado exacto.
desdeconsultastring (date)fecha ≥ desde.
hastaconsultastring (date)fecha ≤ hasta.
limitconsultainteger · 1 a 1000 · por defecto 1000Filas por página (1 a 1000; por defecto 1000). Fuera de rango, 400.
cursorconsultastring · patrón · ≤ 2048El 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).
Ejemplo
curl 'https://yaladpjmdzxwnxmvepqg.supabase.co/functions/v1/api-publica/v1/facturas' \
  -H "Authorization: Bearer $TALAVORA_API_KEY"
Respuesta 200: data (lista) y next_cursor — 19 campos
CampoTipoDescripción
idstring (uuid)
numero_completostring · o null
seriestring · o null
numerointeger · o null
fechastring (date) · o null
tipostring · o null
estadostring · o null
cliente_idstring (uuid) · o null
cliente_nombrestring · o null
cliente_nifstring · o null
basenumber · o null
iva_totalnumber · o null
irpf_pctnumber · o null
irpf_importenumber · o null
totalnumber · o null
fecha_vencimientostring (date) · o null
verifactu_estadostring · o null
proyecto_idstring (uuid) · o null
created_atstring (date-time) · o null

Respuestas: 200 · 400 · 401 · 403 · 429 · 500

GET/v1/facturas/{id}

Una factura con sus líneas

404 si no existe o es de otra organización.

Permiso: facturas:read

ParámetroDóndeTipoDescripción
id *rutastring (uuid)
Ejemplo
curl 'https://yaladpjmdzxwnxmvepqg.supabase.co/functions/v1/api-publica/v1/facturas/3f2b8c1e-5d4a-4e7b-9c6d-1a2b3c4d5e6f' \
  -H "Authorization: Bearer $TALAVORA_API_KEY"
Respuesta 200: data — 27 campos
CampoTipoDescripción
idstring (uuid)
numero_completostring · o null
seriestring · o null
numerointeger · o null
fechastring (date) · o null
tipostring · o null
estadostring · o null
cliente_idstring (uuid) · o null
cliente_nombrestring · o null
cliente_nifstring · o null
basenumber · o null
iva_totalnumber · o null
irpf_pctnumber · o null
irpf_importenumber · o null
totalnumber · o null
fecha_vencimientostring (date) · o null
verifactu_estadostring · o null
proyecto_idstring (uuid) · o null
created_atstring (date-time) · o null
lineaslista de object
lineas[].ordeninteger · o null
lineas[].conceptostring · o null
lineas[].cantidadnumber · o null
lineas[].precionumber · o null
lineas[].descuento_pctnumber · o null
lineas[].iva_pctnumber · o null
lineas[].base_lineanumber · o null

Respuestas: 200 · 400 · 401 · 403 · 404 · 429 · 500

Referencia: Mantenimiento

Espacios, activos, incidencias, preventivo, contadores y órdenes de mantenimiento. Solo con Mantenimiento activado en la organización.

GET/v1/espacios

Espacios (árbol de ubicaciones)

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ámetroDóndeTipoDescripción
padre_idconsultastring (uuid)Solo los hijos directos de este espacio.
raizconsultauna de: truetrue = solo los espacios raíz (cualquier otro valor se ignora).
activoconsultabooleantrue = solo los de alta; false = solo los de baja.
updated_sinceconsultastringModificados desde (AAAA-MM-DD = 00:00 UTC, o fecha y hora ISO 8601).
refconsultastring · ≤ 200Por 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.
limitconsultainteger · 1 a 1000 · por defecto 1000Filas por página (1 a 1000; por defecto 1000). Fuera de rango, 400.
cursorconsultastring · patrón · ≤ 2048El 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).
Ejemplo
curl 'https://yaladpjmdzxwnxmvepqg.supabase.co/functions/v1/api-publica/v1/espacios' \
  -H "Authorization: Bearer $TALAVORA_API_KEY"
Respuesta 200: data (lista) y next_cursor — 24 campos
CampoTipoDescripción
idstring (uuid)
padre_idstring (uuid) · o null
tipo_idstring (uuid) · o null
codigostring
nombrestring
descripcionstring · o null
direccionstring · o null
latnumber · o null
lngnumber · o null
responsable_idstring (uuid) · o null
ubicacion_idstring (uuid) · o null
cliente_centro_idstring (uuid) · o null
profundidadinteger
rutastringIds desde la raíz, separados por /.
activoboolean
created_atstring (date-time)
updated_atstring (date-time)
refs_externasRefsExternasIdentificadores 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.ifcstring · patrón
refs_externas.rfidstring · patrón
refs_externas.inventariostring · ≤ 80
refs_externas.erpstring · ≤ 80
refs_externas.catastrostring · patrónSolo espacios.
refs_externas.otrostring · ≤ 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, 403 FUNCION_APAGADA): null = quitar una; si un valor ya es de otro activo o espacio, 409 con code MNT_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ámetroDóndeTipoDescripción
Idempotency-Keycabecerastring · patrónRepetir 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)

CampoTipoDescripción
idstring (uuid)Solo en el alta; la hace idempotente.
nombrestring · ≤ 200Obligatorio en el alta.
codigostring · patrónObligatorio en el alta.
padre_idstring (uuid) · o nullSolo en el alta.
tipo_idstring (uuid) · o null
descripcionstring · ≤ 4000 · o null
direccionstring · ≤ 400 · o null
latnumber · -90 a 90 · o null
lngnumber · -180 a 180 · o null
responsable_idstring (uuid) · o null
ubicacion_idstring (uuid) · o null
cliente_centro_idstring (uuid) · o null
refs_externasRefsExternasEscritura{ 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 code FUNCION_APAGADA. Un valor que ya tiene otro activo o espacio: 409 con code MNT_REF_EN_USO y no cambia nada (en un alta, no se crea).
Ejemplo
curl -X POST 'https://yaladpjmdzxwnxmvepqg.supabase.co/functions/v1/api-publica/v1/espacios' \
  -H "Authorization: Bearer $TALAVORA_API_KEY" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: crearEspacio-0001' \
  -d '{"nombre":"texto","codigo":"texto","padre_id":"3f2b8c1e-5d4a-4e7b-9c6d-1a2b3c4d5e6f"}'

Respuestas: 200 · 201 · 400 · 401 · 403 · 409 · 422 · 429 · 500

GET/v1/espacios/{id}

Un espacio

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).

Permiso: mantenimiento:read

ParámetroDóndeTipoDescripción
id *rutastring (uuid)
Ejemplo
curl 'https://yaladpjmdzxwnxmvepqg.supabase.co/functions/v1/api-publica/v1/espacios/3f2b8c1e-5d4a-4e7b-9c6d-1a2b3c4d5e6f' \
  -H "Authorization: Bearer $TALAVORA_API_KEY"
Respuesta 200: data — 24 campos
CampoTipoDescripción
idstring (uuid)
padre_idstring (uuid) · o null
tipo_idstring (uuid) · o null
codigostring
nombrestring
descripcionstring · o null
direccionstring · o null
latnumber · o null
lngnumber · o null
responsable_idstring (uuid) · o null
ubicacion_idstring (uuid) · o null
cliente_centro_idstring (uuid) · o null
profundidadinteger
rutastringIds desde la raíz, separados por /.
activoboolean
created_atstring (date-time)
updated_atstring (date-time)
refs_externasRefsExternasIdentificadores 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.ifcstring · patrón
refs_externas.rfidstring · patrón
refs_externas.inventariostring · ≤ 80
refs_externas.erpstring · ≤ 80
refs_externas.catastrostring · patrónSolo espacios.
refs_externas.otrostring · ≤ 80

Respuestas: 200 · 400 · 401 · 403 · 404 · 429 · 500

PATCH/v1/espacios/{id}

Cambiar un espacio

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, 403 FUNCION_APAGADA): null = quitar una; si un valor ya es de otro activo o espacio, 409 con code MNT_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ámetroDóndeTipoDescripción
id *rutastring (uuid)
Idempotency-Keycabecerastring · patrónRepetir 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)

CampoTipoDescripción
idstring (uuid)Solo en el alta; la hace idempotente.
nombrestring · ≤ 200Obligatorio en el alta.
codigostring · patrónObligatorio en el alta.
padre_idstring (uuid) · o nullSolo en el alta.
tipo_idstring (uuid) · o null
descripcionstring · ≤ 4000 · o null
direccionstring · ≤ 400 · o null
latnumber · -90 a 90 · o null
lngnumber · -180 a 180 · o null
responsable_idstring (uuid) · o null
ubicacion_idstring (uuid) · o null
cliente_centro_idstring (uuid) · o null
refs_externasRefsExternasEscritura{ 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 code FUNCION_APAGADA. Un valor que ya tiene otro activo o espacio: 409 con code MNT_REF_EN_USO y no cambia nada (en un alta, no se crea).
Ejemplo
curl -X PATCH 'https://yaladpjmdzxwnxmvepqg.supabase.co/functions/v1/api-publica/v1/espacios/3f2b8c1e-5d4a-4e7b-9c6d-1a2b3c4d5e6f' \
  -H "Authorization: Bearer $TALAVORA_API_KEY" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cambiarEspacio-0001' \
  -d '{"nombre":"texto","codigo":"texto","padre_id":"3f2b8c1e-5d4a-4e7b-9c6d-1a2b3c4d5e6f"}'
Respuesta 200: data — 24 campos
CampoTipoDescripción
idstring (uuid)
padre_idstring (uuid) · o null
tipo_idstring (uuid) · o null
codigostring
nombrestring
descripcionstring · o null
direccionstring · o null
latnumber · o null
lngnumber · o null
responsable_idstring (uuid) · o null
ubicacion_idstring (uuid) · o null
cliente_centro_idstring (uuid) · o null
profundidadinteger
rutastringIds desde la raíz, separados por /.
activoboolean
created_atstring (date-time)
updated_atstring (date-time)
refs_externasRefsExternasIdentificadores 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.ifcstring · patrón
refs_externas.rfidstring · patrón
refs_externas.inventariostring · ≤ 80
refs_externas.erpstring · ≤ 80
refs_externas.catastrostring · patrónSolo espacios.
refs_externas.otrostring · ≤ 80

Respuestas: 200 · 400 · 401 · 403 · 404 · 409 · 422 · 429 · 500

GET/v1/activos

Activos (equipos e instalaciones)

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ámetroDóndeTipoDescripción
espacio_idconsultastring (uuid)Activos ubicados directamente en este espacio.
categoria_idconsultastring (uuid)De esta categoría.
estadoconsultauna de: en_servicio, averiado, fuera_servicio, en_reparacion, bajaEstado del activo.
activoconsultabooleantrue = solo los de alta; false = solo los de baja.
updated_sinceconsultastringModificados desde (AAAA-MM-DD = 00:00 UTC, o fecha y hora ISO 8601).
refconsultastring · ≤ 200Por 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.
limitconsultainteger · 1 a 1000 · por defecto 1000Filas por página (1 a 1000; por defecto 1000). Fuera de rango, 400.
cursorconsultastring · patrón · ≤ 2048El 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).
Ejemplo
curl 'https://yaladpjmdzxwnxmvepqg.supabase.co/functions/v1/api-publica/v1/activos' \
  -H "Authorization: Bearer $TALAVORA_API_KEY"
Respuesta 200: data (lista) y next_cursor — 35 campos
CampoTipoDescripción
idstring (uuid)
codigostring · o null
nombrestring
marcastring · o null
modelostring · o null
num_seriestring · o null
padre_idstring (uuid) · o nullActivo del que es componente.
espacio_idstring (uuid) · o null
categoria_idstring (uuid) · o null
criticidaduna de: baja, media, alta, critica · o null
estado_activouna de: en_servicio, averiado, fuera_servicio, en_reparacion, baja · o null
responsable_idstring (uuid) · o null
proveedor_idstring (uuid) · o null
cliente_idstring (uuid) · o null
centro_idstring (uuid) · o null
fecha_comprastring (date) · o null
coste_adquisicionnumber · o null
instalado_elstring (date) · o null
garantia_hastastring (date) · o null
rutastring · o null
activoboolean
created_atstring (date-time)
updated_atstring (date-time) · o null
latnumber · o nullLatitud PROPIA del activo (WGS84). Sin ella, el activo está donde su espacio.
lngnumber · o nullLongitud propia (WGS84), siempre junto con lat.
posicion_precision_mnumber · o nullPrecisión de la posición en metros (la del GPS, si la hay).
posicion_origenuna de: manual, gps, importacion, api · o nullDe dónde salió la posición: a mano, GPS del móvil, importación o API.
posicion_atstring (date-time) · o nullCuándo se puso la posición.
refs_externasRefsExternasIdentificadores 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.ifcstring · patrón
refs_externas.rfidstring · patrón
refs_externas.inventariostring · ≤ 80
refs_externas.erpstring · ≤ 80
refs_externas.catastrostring · patrónSolo espacios.
refs_externas.otrostring · ≤ 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, 403 FUNCION_APAGADA): null = quitar una; si un valor ya es de otro activo o espacio, 409 con code MNT_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, 403 FUNCION_APAGADA). Además del permiso, la organización tiene que tener Mantenimiento activado (si no, 403).

Permiso: mantenimiento:write

ParámetroDóndeTipoDescripción
Idempotency-Keycabecerastring · patrónRepetir 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)

CampoTipoDescripción
idstring (uuid)Solo en el alta; la hace idempotente.
nombrestring · ≤ 120Obligatorio en el alta.
codigostring · patrón · o null
marcastring · ≤ 120 · o null
modelostring · ≤ 120 · o null
num_seriestring · ≤ 120 · o null
notasstring · ≤ 4000 · o null
padre_idstring (uuid) · o null
espacio_idstring (uuid) · o null
categoria_idstring (uuid) · o null
responsable_idstring (uuid) · o null
proveedor_idstring (uuid) · o null
criticidaduna de: baja, media, alta, critica · o null
estado_activouna de: en_servicio, averiado, fuera_servicio, en_reparacion
instalado_elstring (date) · o null
garantia_hastastring (date) · o null
fecha_comprastring (date) · o null
coste_adquisicionnumber · 0 a … · o nullRequiere mantenimiento:costes.
refs_externasRefsExternasEscritura{ 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 code FUNCION_APAGADA. Un valor que ya tiene otro activo o espacio: 409 con code MNT_REF_EN_USO y no cambia nada (en un alta, no se crea).
latnumber · -90 a 90 · o nullPosició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 code FUNCION_APAGADA.
lngnumber · -180 a 180 · o null
precision_mnumber · 0 a 100000 · o nullPrecisión de la posición en metros (se guarda como posicion_precision_m).
Ejemplo
curl -X POST 'https://yaladpjmdzxwnxmvepqg.supabase.co/functions/v1/api-publica/v1/activos' \
  -H "Authorization: Bearer $TALAVORA_API_KEY" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: crearActivo-0001' \
  -d '{"nombre":"texto","codigo":"texto","marca":"texto"}'

Respuestas: 200 · 201 · 400 · 401 · 403 · 409 · 422 · 429 · 500

GET/v1/activos/{id}

Un activo, con sus componentes y documentos

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).

Permiso: mantenimiento:read

ParámetroDóndeTipoDescripción
id *rutastring (uuid)
Ejemplo
curl 'https://yaladpjmdzxwnxmvepqg.supabase.co/functions/v1/api-publica/v1/activos/3f2b8c1e-5d4a-4e7b-9c6d-1a2b3c4d5e6f' \
  -H "Authorization: Bearer $TALAVORA_API_KEY"
Respuesta 200: data — 50 campos
CampoTipoDescripción
idstring (uuid)
codigostring · o null
nombrestring
marcastring · o null
modelostring · o null
num_seriestring · o null
padre_idstring (uuid) · o nullActivo del que es componente.
espacio_idstring (uuid) · o null
categoria_idstring (uuid) · o null
criticidaduna de: baja, media, alta, critica · o null
estado_activouna de: en_servicio, averiado, fuera_servicio, en_reparacion, baja · o null
responsable_idstring (uuid) · o null
proveedor_idstring (uuid) · o null
cliente_idstring (uuid) · o null
centro_idstring (uuid) · o null
fecha_comprastring (date) · o null
coste_adquisicionnumber · o null
instalado_elstring (date) · o null
garantia_hastastring (date) · o null
rutastring · o null
activoboolean
created_atstring (date-time)
updated_atstring (date-time) · o null
latnumber · o nullLatitud PROPIA del activo (WGS84). Sin ella, el activo está donde su espacio.
lngnumber · o nullLongitud propia (WGS84), siempre junto con lat.
posicion_precision_mnumber · o nullPrecisión de la posición en metros (la del GPS, si la hay).
posicion_origenuna de: manual, gps, importacion, api · o nullDe dónde salió la posición: a mano, GPS del móvil, importación o API.
posicion_atstring (date-time) · o nullCuándo se puso la posición.
refs_externasRefsExternasIdentificadores 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.ifcstring · patrón
refs_externas.rfidstring · patrón
refs_externas.inventariostring · ≤ 80
refs_externas.erpstring · ≤ 80
refs_externas.catastrostring · patrónSolo espacios.
refs_externas.otrostring · ≤ 80
componenteslista de object
componentes[].idstring (uuid)
componentes[].codigostring · o null
componentes[].nombrestring
componentes[].estado_activostring · o null
documentoslista de objectMetadatos de los documentos vigentes (hasta 200).
documentos[].idstring (uuid)
documentos[].tipostring
documentos[].titulostring
documentos[].mimestring · o null
documentos[].bytesinteger · o null
documentos[].sha256string · o null
documentos[].emitido_elstring (date) · o null
documentos[].vence_elstring (date) · o null
documentos[].created_atstring (date-time)

Respuestas: 200 · 400 · 401 · 403 · 404 · 429 · 500

PATCH/v1/activos/{id}

Cambiar un activo

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, 403 FUNCION_APAGADA): null = quitar una; si un valor ya es de otro activo o espacio, 409 con code MNT_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, 403 FUNCION_APAGADA). Las dos null = quitarla. Además del permiso, la organización tiene que tener Mantenimiento activado (si no, 403).

Permiso: mantenimiento:write

ParámetroDóndeTipoDescripción
id *rutastring (uuid)
Idempotency-Keycabecerastring · patrónRepetir 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)

CampoTipoDescripción
idstring (uuid)Solo en el alta; la hace idempotente.
nombrestring · ≤ 120Obligatorio en el alta.
codigostring · patrón · o null
marcastring · ≤ 120 · o null
modelostring · ≤ 120 · o null
num_seriestring · ≤ 120 · o null
notasstring · ≤ 4000 · o null
padre_idstring (uuid) · o null
espacio_idstring (uuid) · o null
categoria_idstring (uuid) · o null
responsable_idstring (uuid) · o null
proveedor_idstring (uuid) · o null
criticidaduna de: baja, media, alta, critica · o null
estado_activouna de: en_servicio, averiado, fuera_servicio, en_reparacion
instalado_elstring (date) · o null
garantia_hastastring (date) · o null
fecha_comprastring (date) · o null
coste_adquisicionnumber · 0 a … · o nullRequiere mantenimiento:costes.
refs_externasRefsExternasEscritura{ 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 code FUNCION_APAGADA. Un valor que ya tiene otro activo o espacio: 409 con code MNT_REF_EN_USO y no cambia nada (en un alta, no se crea).
latnumber · -90 a 90 · o nullPosició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 code FUNCION_APAGADA.
lngnumber · -180 a 180 · o null
precision_mnumber · 0 a 100000 · o nullPrecisión de la posición en metros (se guarda como posicion_precision_m).
Ejemplo
curl -X PATCH 'https://yaladpjmdzxwnxmvepqg.supabase.co/functions/v1/api-publica/v1/activos/3f2b8c1e-5d4a-4e7b-9c6d-1a2b3c4d5e6f' \
  -H "Authorization: Bearer $TALAVORA_API_KEY" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cambiarActivo-0001' \
  -d '{"nombre":"texto","codigo":"texto","marca":"texto"}'
Respuesta 200: data — 35 campos
CampoTipoDescripción
idstring (uuid)
codigostring · o null
nombrestring
marcastring · o null
modelostring · o null
num_seriestring · o null
padre_idstring (uuid) · o nullActivo del que es componente.
espacio_idstring (uuid) · o null
categoria_idstring (uuid) · o null
criticidaduna de: baja, media, alta, critica · o null
estado_activouna de: en_servicio, averiado, fuera_servicio, en_reparacion, baja · o null
responsable_idstring (uuid) · o null
proveedor_idstring (uuid) · o null
cliente_idstring (uuid) · o null
centro_idstring (uuid) · o null
fecha_comprastring (date) · o null
coste_adquisicionnumber · o null
instalado_elstring (date) · o null
garantia_hastastring (date) · o null
rutastring · o null
activoboolean
created_atstring (date-time)
updated_atstring (date-time) · o null
latnumber · o nullLatitud PROPIA del activo (WGS84). Sin ella, el activo está donde su espacio.
lngnumber · o nullLongitud propia (WGS84), siempre junto con lat.
posicion_precision_mnumber · o nullPrecisión de la posición en metros (la del GPS, si la hay).
posicion_origenuna de: manual, gps, importacion, api · o nullDe dónde salió la posición: a mano, GPS del móvil, importación o API.
posicion_atstring (date-time) · o nullCuándo se puso la posición.
refs_externasRefsExternasIdentificadores 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.ifcstring · patrón
refs_externas.rfidstring · patrón
refs_externas.inventariostring · ≤ 80
refs_externas.erpstring · ≤ 80
refs_externas.catastrostring · patrónSolo espacios.
refs_externas.otrostring · ≤ 80

Respuestas: 200 · 400 · 401 · 403 · 404 · 409 · 422 · 429 · 500

GET/v1/incidencias

Incidencias (avisos de avería)

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ámetroDóndeTipoDescripción
estadoconsultauna de: nueva, en_revision, aceptada, convertida, rechazada, duplicada, cerradaEstado.
prioridadconsultauna de: baja, normal, alta, urgentePrioridad.
activo_idconsultastring (uuid)De este activo.
espacio_idconsultastring (uuid)De este espacio.
updated_sinceconsultastringModificados desde (AAAA-MM-DD = 00:00 UTC, o fecha y hora ISO 8601).
limitconsultainteger · 1 a 1000 · por defecto 1000Filas por página (1 a 1000; por defecto 1000). Fuera de rango, 400.
cursorconsultastring · patrón · ≤ 2048El 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).
Ejemplo
curl 'https://yaladpjmdzxwnxmvepqg.supabase.co/functions/v1/api-publica/v1/incidencias' \
  -H "Authorization: Bearer $TALAVORA_API_KEY"
Respuesta 200: data (lista) y next_cursor — 17 campos
CampoTipoDescripción
idstring (uuid)
codigostring · patrón
titulostring
descripcionstring · o null
prioridaduna de: baja, normal, alta, urgente
espacio_idstring (uuid) · o null
activo_idstring (uuid) · o null
latnumber · o null
lngnumber · o null
estadouna de: nueva, en_revision, aceptada, convertida, rechazada, duplicada, cerrada
motivo_rechazostring · o null
origenuna de: interno, tecnico, portal_cliente, api, publico, proveedorPor 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_idstring (uuid) · o null
duplicada_destring (uuid) · o null
resuelta_atstring (date-time) · o null
created_atstring (date-time)
updated_atstring (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ámetroDóndeTipoDescripción
Idempotency-Keycabecerastring · patrónRepetir 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)

CampoTipoDescripción
idstring (uuid)Opcional; hace la petición idempotente.
titulo *string · ≤ 200
descripcionstring · ≤ 4000
prioridadobject
activo_idstring (uuid)
espacio_idstring (uuid)
latnumber · -90 a 90Junto con lng.
lngnumber · -180 a 180
Ejemplo
curl -X POST 'https://yaladpjmdzxwnxmvepqg.supabase.co/functions/v1/api-publica/v1/incidencias' \
  -H "Authorization: Bearer $TALAVORA_API_KEY" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: crearIncidencia-0001' \
  -d '{"titulo":"texto"}'

Respuestas: 200 · 201 · 400 · 401 · 403 · 409 · 422 · 429 · 500

GET/v1/incidencias/{id}

Una incidencia

404 si no existe o es de otra organización. Además del permiso, la organización tiene que tener Mantenimiento activado (si no, 403).

Permiso: mantenimiento:read

ParámetroDóndeTipoDescripción
id *rutastring (uuid)
Ejemplo
curl 'https://yaladpjmdzxwnxmvepqg.supabase.co/functions/v1/api-publica/v1/incidencias/3f2b8c1e-5d4a-4e7b-9c6d-1a2b3c4d5e6f' \
  -H "Authorization: Bearer $TALAVORA_API_KEY"
Respuesta 200: data — 17 campos
CampoTipoDescripción
idstring (uuid)
codigostring · patrón
titulostring
descripcionstring · o null
prioridaduna de: baja, normal, alta, urgente
espacio_idstring (uuid) · o null
activo_idstring (uuid) · o null
latnumber · o null
lngnumber · o null
estadouna de: nueva, en_revision, aceptada, convertida, rechazada, duplicada, cerrada
motivo_rechazostring · o null
origenuna de: interno, tecnico, portal_cliente, api, publico, proveedorPor 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_idstring (uuid) · o null
duplicada_destring (uuid) · o null
resuelta_atstring (date-time) · o null
created_atstring (date-time)
updated_atstring (date-time)

Respuestas: 200 · 400 · 401 · 403 · 404 · 429 · 500

GET/v1/planes

Planes de mantenimiento preventivo

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ámetroDóndeTipoDescripción
updated_sinceconsultastringModificados desde (AAAA-MM-DD = 00:00 UTC, o fecha y hora ISO 8601).
limitconsultainteger · 1 a 1000 · por defecto 1000Filas por página (1 a 1000; por defecto 1000). Fuera de rango, 400.
cursorconsultastring · patrón · ≤ 2048El 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).
Ejemplo
curl 'https://yaladpjmdzxwnxmvepqg.supabase.co/functions/v1/api-publica/v1/planes' \
  -H "Authorization: Bearer $TALAVORA_API_KEY"
Respuesta 200: data (lista) y next_cursor — 27 campos
CampoTipoDescripción
idstring (uuid)
codigostring · o null
nombrestring
descripcionstring · o null
reglamentarioboolean · o null
normativastring · o null
disparouna de: calendario, contador, mixto
frecuencia_valorinteger · o null
frecuencia_unidadstring · o nullnull en un plan solo por uso.
base_calculostring · o null
fecha_iniciostring (date) · o null
fecha_finstring (date) · o null
tolerancia_diasinteger · o null
dias_antelacioninteger · o null
duracion_estimada_mininteger · o null
prioridadstring · o null
responsable_idstring (uuid) · o null
brigada_idstring (uuid) · o null
proveedor_idstring (uuid) · o null
estadostring · o null
created_atstring (date-time)
updated_atstring (date-time) · o null
contador_tipostring · o null
contador_unidadstring · o null
uso_intervalonumber · o null
uso_antelacionnumber · o null
uso_antelacion_pctnumber · o null

Respuestas: 200 · 400 · 401 · 403 · 404 · 429 · 500

GET/v1/planes/{id}

Un plan, con sus asignaciones a activos o espacios

Hasta 1.000 asignaciones. Además del permiso, la organización tiene que tener Mantenimiento activado (si no, 403).

Permiso: mantenimiento:read

ParámetroDóndeTipoDescripción
id *rutastring (uuid)
Ejemplo
curl 'https://yaladpjmdzxwnxmvepqg.supabase.co/functions/v1/api-publica/v1/planes/3f2b8c1e-5d4a-4e7b-9c6d-1a2b3c4d5e6f' \
  -H "Authorization: Bearer $TALAVORA_API_KEY"
Respuesta 200: data — 42 campos
CampoTipoDescripción
idstring (uuid)
codigostring · o null
nombrestring
descripcionstring · o null
reglamentarioboolean · o null
normativastring · o null
disparouna de: calendario, contador, mixto
frecuencia_valorinteger · o null
frecuencia_unidadstring · o nullnull en un plan solo por uso.
base_calculostring · o null
fecha_iniciostring (date) · o null
fecha_finstring (date) · o null
tolerancia_diasinteger · o null
dias_antelacioninteger · o null
duracion_estimada_mininteger · o null
prioridadstring · o null
responsable_idstring (uuid) · o null
brigada_idstring (uuid) · o null
proveedor_idstring (uuid) · o null
estadostring · o null
created_atstring (date-time)
updated_atstring (date-time) · o null
contador_tipostring · o null
contador_unidadstring · o null
uso_intervalonumber · o null
uso_antelacionnumber · o null
uso_antelacion_pctnumber · o null
asignacioneslista de object
asignaciones[].idstring (uuid)
asignaciones[].plan_idstring (uuid)
asignaciones[].activo_idstring (uuid) · o null
asignaciones[].espacio_idstring (uuid) · o null
asignaciones[].proxima_fechastring (date) · o null
asignaciones[].ultima_fecha_previstastring (date) · o null
asignaciones[].ultimo_cierre_atstring (date-time) · o null
asignaciones[].ultima_ot_idstring (uuid) · o null
asignaciones[].activoboolean
asignaciones[].created_atstring (date-time)
asignaciones[].updated_atstring (date-time) · o null
asignaciones[].uso_contador_idstring (uuid) · o null
asignaciones[].uso_basenumber · o nullLectura de la última ejecución.
asignaciones[].uso_umbralnumber · o nullLa lectura a la que toca la siguiente; null con una orden abierta.

Respuestas: 200 · 400 · 401 · 403 · 404 · 429 · 500

GET/v1/contadores

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ámetroDóndeTipoDescripción
activo_idconsultastring (uuid)De este activo.
activoconsultabooleantrue = solo los de alta; false = solo los de baja.
updated_sinceconsultastringModificados desde (AAAA-MM-DD = 00:00 UTC, o fecha y hora ISO 8601).
limitconsultainteger · 1 a 1000 · por defecto 1000Filas por página (1 a 1000; por defecto 1000). Fuera de rango, 400.
cursorconsultastring · patrón · ≤ 2048El 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).
Ejemplo
curl 'https://yaladpjmdzxwnxmvepqg.supabase.co/functions/v1/api-publica/v1/contadores' \
  -H "Authorization: Bearer $TALAVORA_API_KEY"
Respuesta 200: data (lista) y next_cursor — 12 campos
CampoTipoDescripción
idstring (uuid)
activo_idstring (uuid)
codigostring · o null
nombrestring
tipouna de: horas, km, ciclos, kwh, m3, unidades, otro
unidadstring
acumulativoboolean
valor_actualnumber · o null
leido_atstring (date-time) · o null
activoboolean
created_atstring (date-time)
updated_atstring (date-time)

Respuestas: 200 · 400 · 401 · 403 · 429 · 500

GET/v1/contadores/{id}

Un contador, con sus 50 últimas lecturas

404 si no existe o es de otra organización. Además del permiso, la organización tiene que tener Mantenimiento activado (si no, 403).

Permiso: mantenimiento:read

ParámetroDóndeTipoDescripción
id *rutastring (uuid)
Ejemplo
curl 'https://yaladpjmdzxwnxmvepqg.supabase.co/functions/v1/api-publica/v1/contadores/3f2b8c1e-5d4a-4e7b-9c6d-1a2b3c4d5e6f' \
  -H "Authorization: Bearer $TALAVORA_API_KEY"
Respuesta 200: data — 23 campos
CampoTipoDescripción
idstring (uuid)
activo_idstring (uuid)
codigostring · o null
nombrestring
tipouna de: horas, km, ciclos, kwh, m3, unidades, otro
unidadstring
acumulativoboolean
valor_actualnumber · o null
leido_atstring (date-time) · o null
activoboolean
created_atstring (date-time)
updated_atstring (date-time)
ultimas_lecturaslista de Lectura
ultimas_lecturas[].idstring (uuid)
ultimas_lecturas[].contador_idstring (uuid)
ultimas_lecturas[].valornumber
ultimas_lecturas[].leido_atstring (date-time)
ultimas_lecturas[].origenuna de: manual, qr, api, dispositivo, ot, importacion
ultimas_lecturas[].ot_idstring (uuid) · o null
ultimas_lecturas[].notastring · o null
ultimas_lecturas[].reinicioboolean
ultimas_lecturas[].motivostring · o null
ultimas_lecturas[].created_atstring (date-time)

Respuestas: 200 · 400 · 401 · 403 · 404 · 429 · 500

POST/v1/lecturas

Anotar una lectura de un contador

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 code MNT_LECTURA_BAJA o MNT_LECTURA_SUPERA), ni del futuro (5 minutos de margen, 400 con code MNT_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ámetroDóndeTipoDescripción
Idempotency-Keycabecerastring · patrónRepetir 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)

CampoTipoDescripción
idstring (uuid)Lo pone el integrador: la hace idempotente.
contador_id *string (uuid)
valor *number o stringHasta 3 decimales; |valor| ≤ 1e12. También como texto con punto decimal.
leido_atstring (date-time)Por defecto, ahora. Con zona horaria.
origenuna de: api, dispositivo · por defecto api
notastring · ≤ 500
Ejemplo
curl -X POST 'https://yaladpjmdzxwnxmvepqg.supabase.co/functions/v1/api-publica/v1/lecturas' \
  -H "Authorization: Bearer $TALAVORA_API_KEY" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: crearLectura-0001' \
  -d '{"contador_id":"3f2b8c1e-5d4a-4e7b-9c6d-1a2b3c4d5e6f","valor":12.5}'

Respuestas: 200 · 201 · 400 · 401 · 403 · 404 · 409 · 422 · 429 · 500

GET/v1/mantenimiento/ordenes

Órdenes de trabajo de mantenimiento

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ámetroDóndeTipoDescripción
estadoconsultauna de: borrador, planificada, en_curso, pausada, cerrada, facturada, canceladaEstado.
tipoconsultauna de: correctivo, preventivo, inspeccion, mejora, otroTipo de mantenimiento.
activo_idconsultastring (uuid)De este activo.
espacio_idconsultastring (uuid)De este espacio.
desdeconsultastringAlta desde (AAAA-MM-DD = 00:00 UTC, o fecha y hora ISO 8601).
hastaconsultastringAlta hasta (AAAA-MM-DD incluye ese día entero, o fecha y hora ISO 8601).
updated_sinceconsultastringModificados desde (AAAA-MM-DD = 00:00 UTC, o fecha y hora ISO 8601).
limitconsultainteger · 1 a 1000 · por defecto 1000Filas por página (1 a 1000; por defecto 1000). Fuera de rango, 400.
cursorconsultastring · patrón · ≤ 2048El 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).
Ejemplo
curl 'https://yaladpjmdzxwnxmvepqg.supabase.co/functions/v1/api-publica/v1/mantenimiento/ordenes' \
  -H "Authorization: Bearer $TALAVORA_API_KEY"
Respuesta 200: data (lista) y next_cursor — 27 campos
CampoTipoDescripción
idstring (uuid)
codigostring · o null
titulostring · o null
estadouna de: borrador, planificada, en_curso, pausada, cerrada, facturada, cancelada
prioridadstring · o null
tipo_mantenimientouna de: correctivo, preventivo, inspeccion, mejora, otro
activo_idstring (uuid) · o null
espacio_idstring (uuid) · o null
incidencia_idstring (uuid) · o null
plan_activo_idstring (uuid) · o null
proveedor_idstring (uuid) · o null
brigada_idstring (uuid) · o null
con_tecnicobooleanTiene técnico asignado (quién, no).
fecha_previstastring (date) · o null
fecha_programadastring (date) · o null
fecha_limitestring (date) · o null
iniciada_atstring (date-time) · o null
cerrada_atstring (date-time) · o null
cancelada_atstring (date-time) · o null
duracion_estimada_mininteger · o null
modo_fallo_idstring (uuid) · o null
causa_idstring (uuid) · o null
accion_idstring (uuid) · o null
garantia_idstring (uuid) · o null
reclamacion_garantiaboolean
created_atstring (date-time)
updated_atstring (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).

Permiso: mantenimiento:read

ParámetroDóndeTipoDescripción
id *rutastring (uuid)
Ejemplo
curl 'https://yaladpjmdzxwnxmvepqg.supabase.co/functions/v1/api-publica/v1/mantenimiento/ordenes/3f2b8c1e-5d4a-4e7b-9c6d-1a2b3c4d5e6f' \
  -H "Authorization: Bearer $TALAVORA_API_KEY"
Respuesta 200: data — 55 campos
CampoTipoDescripción
idstring (uuid)
codigostring · o null
titulostring · o null
estadouna de: borrador, planificada, en_curso, pausada, cerrada, facturada, cancelada
prioridadstring · o null
tipo_mantenimientouna de: correctivo, preventivo, inspeccion, mejora, otro
activo_idstring (uuid) · o null
espacio_idstring (uuid) · o null
incidencia_idstring (uuid) · o null
plan_activo_idstring (uuid) · o null
proveedor_idstring (uuid) · o null
brigada_idstring (uuid) · o null
con_tecnicobooleanTiene técnico asignado (quién, no).
fecha_previstastring (date) · o null
fecha_programadastring (date) · o null
fecha_limitestring (date) · o null
iniciada_atstring (date-time) · o null
cerrada_atstring (date-time) · o null
cancelada_atstring (date-time) · o null
duracion_estimada_mininteger · o null
modo_fallo_idstring (uuid) · o null
causa_idstring (uuid) · o null
accion_idstring (uuid) · o null
garantia_idstring (uuid) · o null
reclamacion_garantiaboolean
created_atstring (date-time)
updated_atstring (date-time) · o null
paradaslista de object
paradas[].idstring (uuid)
paradas[].causastring
paradas[].causa_idstring (uuid) · o null
paradas[].iniciostring (date-time)
paradas[].finstring (date-time) · o null
paradas[].minutosinteger · o null
paradas[].activo_idstring (uuid) · o null
paradas[].afecta_disponibilidadboolean
materialeslista de object
materiales[].idstring (uuid)
materiales[].producto_idstring (uuid) · o null
materiales[].conceptostring · o null
materiales[].cantidadnumber · o null
materiales[].clasestring · o null
materiales[].proveedor_idstring (uuid) · o null
materiales[].almacen_idstring (uuid) · o null
materiales[].created_atstring (date-time)
materiales[].costenumber · o nullSolo con mantenimiento:costes.
materiales[].precionumber · o nullSolo con mantenimiento:costes.
materiales[].iva_pctnumber · o nullSolo con mantenimiento:costes.
minutosobjectMinutos por tipo (trabajo, desplazamiento, espera).
costeobject · o nullSolo con mantenimiento:costes.
coste.manonumber
coste.materialnumber
coste.externonumber
coste.totalnumber
coste.incompletobooleanHay horas o materiales sin coste.

Respuestas: 200 · 400 · 401 · 403 · 404 · 429 · 500

Referencia: BI

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.

GET/v1/bi

Catálogo de vistas de BI y sus columnas

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.

Permiso: bi:read

Ejemplo
curl 'https://yaladpjmdzxwnxmvepqg.supabase.co/functions/v1/api-publica/v1/bi' \
  -H "Authorization: Bearer $TALAVORA_API_KEY"
Respuesta 200: data — 3 campos
CampoTipoDescripción
vistauna de: activos, espacios, ordenes, incidencias, preventivo, lecturas, sla_ot, fiabilidad_activosLas 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.
rutastring
columnaslista 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ámetroDóndeTipoDescripción
vista *rutauna de: activos, espacios, ordenes, incidencias, preventivo, lecturas, sla_ot, fiabilidad_activos
limitconsultainteger · 1 a 1000 · por defecto 1000Filas por página (1 a 1000; por defecto 1000). Fuera de rango, 400.
cursorconsultastring · patrón · ≤ 2048El 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).
formatconsultauna de: json, csv · por defecto jsoncsv para CSV (también con Accept: text/csv); json por defecto. Otro valor: 400.
Ejemplo
curl 'https://yaladpjmdzxwnxmvepqg.supabase.co/functions/v1/api-publica/v1/bi/activos' \
  -H "Authorization: Bearer $TALAVORA_API_KEY"

Respuestas: 200 · 400 · 401 · 403 · 404 · 429 · 500 · 503

Referencia: Dispositivos

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).

POST/v1/dispositivos/lecturas

Un lote de lecturas de un dispositivo

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ámetroDóndeTipoDescripción
X-Talavora-Versioncabecerastring · ≤ 60Versió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)

CampoTipoDescripción
versionstring · ≤ 60Versión del firmware o del flujo (como X-Talavora-Version).
lecturas *lista de LecturaDispositivo
Ejemplo
curl -X POST 'https://yaladpjmdzxwnxmvepqg.supabase.co/functions/v1/api-publica/v1/dispositivos/lecturas' \
  -H "Authorization: Bearer $TALAVORA_DISPOSITIVO" \
  -H 'Content-Type: application/json' \
  -d '{"version":"nodered-3.1","lecturas":[{"punto":"AI1","valor":2931,"leido_at":"2026-10-29T09:15:00Z"},{"punto":"HORAS","valor":1520.5,"leido_at":1793000000}]}'
Respuesta 200: data — 16 campos
CampoTipoDescripción
ok«true»
recibidasintegerLecturas del lote.
aceptadasintegerAgregadas + guardadas + repetidas.
rechazadasinteger
guardadasintegerLecturas que han quedado en Talavora con esta petición (intervalos cerrados y atrasadas).
disparosintegerUmbrales que han saltado.
cupoobject
cupo.por_minutointeger
cupo.restanteinteger
hora_servidorstring (date-time)
detallelista de objectUna entrada por lectura del lote, en su orden.
detalle[].iintegerPosición en el lote (desde 0).
detalle[].idstring (uuid)El id que mandó la pasarela, si lo mandó.
detalle[].estadouna de: agregada, guardada, repetida, rechazadaagregada: entra en el intervalo abierto; guardada: una atrasada que se guarda sola; repetida: ya estaba (reenvío); rechazada: con su code (no reintentarla).
detalle[].codestring · patrónSolo 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[].errorstringTexto, en las que rechaza la API antes de llegar a la base (forma, valor, hora).

Respuestas: 200 · 400 · 401 · 403 · 413 · 429 · 503

POST/v1/dispositivos/latido

«Sigo vivo», versión y reloj del dispositivo

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ámetroDóndeTipoDescripción
X-Talavora-Versioncabecerastring · ≤ 60Versió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)

CampoTipoDescripción
versionstring · ≤ 60Versión del firmware o del flujo (si no, la de X-Talavora-Version).
horastring (date-time) o numberLa hora del aparato (ISO 8601 con zona o epoch): Talavora devuelve el desvío de su reloj.
Ejemplo
curl -X POST 'https://yaladpjmdzxwnxmvepqg.supabase.co/functions/v1/api-publica/v1/dispositivos/latido' \
  -H "Authorization: Bearer $TALAVORA_DISPOSITIVO" \
  -H 'Content-Type: application/json' \
  -d '{"version":"texto","hora":"2026-10-29T09:15:00Z"}'
Respuesta 200: data — 8 campos
CampoTipoDescripción
ok«true»
hora_servidorstring (date-time)
desvio_sinteger · o nullSegundos que va adelantado (+) o atrasado (−) el reloj del aparato; null si no mandó hora.
cupo_minutointegerSu cupo de lecturas por minuto.
max_lecturas_peticion«500»
puntoslista de objectLos puntos activos que debe mandar.
puntos[].codigostring
puntos[].intervalo_minintegerMinutos del intervalo en que se agrega (15 a 1440).

Respuestas: 200 · 400 · 401 · 403 · 413 · 429 · 503

¿Algo no cuadra con lo que devuelve la API? Escriba a soporte@talavora.com con el x-request-id.