Integración PMS por API
Autenticación, consultas, órdenes y confirmaciones de la API REST de Hospitality.
API REST · v1
Conexión y consultas
La API permite consultar los datos del hotel y, con los permisos correspondientes, enviar órdenes de estancia y despertadores mediante HTTPS.
Solicita al responsable de la integración la clave API del hotel y los permisos necesarios. Una clave de consulta permite leer información; enviar órdenes requiere permisos de escritura específicos. Guarda la clave de forma segura. Si se renueva, actualízala en el PMS.
Descargar contrato OpenAPI JSON. Base: https://hospitality.fibwi.com/api/pms/v1. Envía siempre Authorization: Bearer <clave>; nunca incluyas la clave en la URL. Cada clave pertenece a un solo hotel. No envíes tenant_id ni x-tenant-id.
curl 'https://hospitality.fibwi.com/api/pms/v1/rooms?limit=100' \
-H 'Authorization: Bearer hosp_pms_REEMPLAZA_CON_TU_CLAVE'
| GET | Contenido | Permiso |
|---|---|---|
/hotel | Hotel, zona horaria y permisos de la clave. | Cualquier credencial válida. |
/rooms | Habitaciones, ocupación y limpieza; sin nombre del huésped. | rooms:read |
/stays | Estancias activas, fechas y nombre del huésped. | stays:read |
/calls | Llamadas con identificadores e importes neto, IVA y total en EUR. | calls:read |
/wakeups | Programación y resultados de despertadores. | wakeups:read |
/events | Eventos de estancias, limpieza, despertadores y CDR. | events:read y permiso del recurso correspondiente. |
Paginación y filtros
Las listas devuelven data, meta.next_cursor, meta.has_more, meta.limit y server_time. limit va de 1 a 200 (100 por defecto). Usa cursor con el valor devuelto para continuar y conserva los mismos filtros. El cursor solo sirve para ese hotel, recurso y filtros. Las habitaciones, estancias, llamadas y despertadores admiten room_number; las llamadas añaden from y to en ISO 8601 con zona horaria; los despertadores, date=YYYY-MM-DD; los eventos, category=stay|services|cdr. Las listas se ordenan por ID ascendente.
Sincronización incremental
- Obtén una foto completa de los recursos que necesites, recorriendo sus páginas.
- Consulta
/eventssin cursor para recuperar el histórico conservado. Los eventos históricos pueden solaparse con la foto inicial: reconoce los registros por su identificador y evita aplicarlos dos veces. - Procesa y guarda cada página de forma duradera antes de guardar su
next_cursor. Continúa mientrashas_moresea verdadero, incluso si una página está vacía. - Después consulta los eventos con el último cursor cada 15–30 segundos por hotel. En caso de desconexión, retoma ese cursor: el feed no se limita al día actual.
Los eventos se ordenan por publicación, no por la fecha de la llamada. Un evento recibido tarde obtiene una posición posterior en el feed, aunque su occurred_at sea antiguo. id identifica la publicación y source_event_id el evento de Hospitality. En los CDR, uniqueid identifica la llamada de origen cuando está disponible. No sumes los importes del listado de llamadas y los del feed como si fueran cargos distintos.
Las listas de recursos son fotos paginadas: conservar su último cursor no detecta modificaciones de filas anteriores. Usa el feed para detectar cambios y vuelve a consultar el recurso o la habitación afectada. Tras cambiar de filtros o ampliar permisos con una nueva clave, inicia una nueva sincronización según los datos que necesites.
Interpretación de los datos
/stays contiene únicamente estancias activas. Esta versión no incorpora una referencia de reserva externa ni un identificador permanente de estancia que sobreviva a los cambios de habitación. /calls devuelve room_id, room_number y checkout_id cuando existen. Una habitación se reutiliza: no atribuyas cargos históricos basándote únicamente en su ocupación actual. Se incluyen también llamadas sin coste; amounts declara neto, IVA del 21%, total y moneda EUR según el contrato actual.
Los datos reflejan lo recibido por Hospitality, no una consulta en vivo a la centralita. outbound_enabled es el permiso configurado en Hospitality y no acredita por sí solo que la PBX haya aplicado el cambio. Un despertador awaiting_confirmation o unconfirmed no debe interpretarse como contestado.
Límites y errores
Máximo 120 peticiones por minuto y credencial. Las respuestas incluyen X-RateLimit-Limit, X-RateLimit-Remaining y X-Request-Id. Ante un 429, espera el Retry-After. Los errores devuelven error.code, error.message y request_id: 400 para filtros o cursores incorrectos, 401 para credenciales no válidas o integración inactiva, 403 por falta de permisos y 405 para métodos no admitidos. Si necesitas soporte, facilita el X-Request-Id, la fecha y hora y la operación afectada. No incluyas la clave API.
Órdenes del PMS
Envía una orden a POST /api/pms/v1/commands con JSON, Content-Type: application/json, la credencial en Authorization y una Idempotency-Key única para esa orden. La clave admite de 8 a 128 caracteres alfanuméricos, punto, guion, dos puntos o guion bajo. Consérvala de forma duradera en el PMS.
| type | Operación | Permiso |
|---|---|---|
checkin | Ocupar una habitación libre. | stays:write |
stay_update | Modificar datos y fechas de la estancia activa. | stays:write |
checkout | Salir, liquidar llamadas y solicitar el bloqueo de llamadas externas. | stays:write |
room_move | Mover la estancia, llamadas pendientes y despertadores a una habitación libre. | stays:write |
wakeup_set | Programar un despertador en un minuto futuro. | wakeups:write |
wakeup_cancel | Cancelar un despertador pendiente por su ID. | wakeups:write |
La respuesta inicial es 201 e incluye data.id, data.status=applied, data.pbx_sync y data.result. La respuesta confirma la modificación en Hospitality; el estado de sincronización se consulta por separado. El check-in se rechaza si la habitación ya está ocupada; el cambio de habitación también comprueba las llamadas y despertadores pendientes de la habitación destino. La limpieza sigue siendo de consulta para el PMS.
Reintentos sin duplicar operaciones
Si se pierde la respuesta, repite exactamente la misma orden con la misma Idempotency-Key. Se devuelve 200 con el mismo resultado guardado y Idempotency-Replayed: true. No se vuelve a ejecutar ni a liquidar. Usar esa clave con otra orden devuelve 409. La clave de idempotencia pertenece al hotel, por lo que sigue funcionando al renovar la credencial. Los errores de validación o conflictos que impiden aplicar la orden no generan una operación confirmada.
No crees una clave de idempotencia nueva para reintentar una orden cuyo resultado desconozcas. La respuesta repetida conserva el resultado inicial; consulta el estado de sincronización actualizado en GET /api/pms/v1/commands/{id}, con el permiso de escritura correspondiente al tipo de orden.
Estado de la orden
status=applied significa que Hospitality ha aplicado la orden. pbx_sync puede ser pending, processing, applied, failed o not_required. Consulta GET /api/pms/v1/commands/{id} mientras pbx_sync sea pending o processing. Si pasa a failed, comunica el ID de la orden al responsable de la integración: la modificación en Hospitality sigue aplicada. No envíes otra orden para repetir el check-in o checkout. not_required se utiliza al programar o cancelar despertadores: el despertador se solicitará a la hora programada, no al recibir la orden.
Protección de la estancia
stay_update, checkout y room_move exigen expected_checkin_at: copia exactamente el checkin_at recibido del check-in o de /stays. Si la habitación ya está libre o pertenece a otra estancia, la orden devuelve 409 y no modifica al nuevo huésped. También puedes enviarlo en órdenes de despertador. Esta referencia protege la estancia activa; no es una referencia de reserva externa.
Ejemplo de check-in
curl 'https://hospitality.fibwi.com/api/pms/v1/commands' \
-H 'Authorization: Bearer hosp_pms_REEMPLAZA_CON_TU_CLAVE' \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: reserva-123-entrada-1' \
--data '{"type":"checkin","room_number":"401","guest_first_name":"Ana","guest_last_name":"García","stay_checkin_date":"2026-11-10","stay_checkout_date":"2026-11-12","outbound_enabled":true}'
También se admiten guest_doc_id, guest_phone, guest_email y guest_address. Son opcionales; evita enviar datos que no necesites. Las fechas se interpretan en la zona horaria del hotel y outbound_enabled es booleano.
Editar estancia y hacer checkout
{
"type": "stay_update",
"room_number": "401",
"expected_checkin_at": "2026-11-10T10:00:00.000Z",
"changes": {"stay_checkout_date":"2026-11-13","outbound_enabled":false}
}
{
"type": "checkout",
"room_number": "401",
"expected_checkin_at": "2026-11-10T10:00:00.000Z"
}
Utiliza una Idempotency-Key distinta por cada modificación real. El checkout liquida las llamadas pendientes; no las marca como pagadas. No se deben ejecutar órdenes de salida basándose solo en la fecha prevista.
Cambio de habitación y despertadores
{"type":"room_move","room_number":"401","target_room_number":"402","expected_checkin_at":"2026-11-10T10:00:00.000Z"}
{"type":"wakeup_set","room_number":"402","wakeup_date":"2026-11-11","wakeup_time":"07:30"}
{"type":"wakeup_cancel","room_number":"402","wakeup_id":"12345"}
Un despertador ya en curso no se cancela mediante esta orden. El resultado de wakeup_set devuelve el ID necesario para cancelarlo; también puedes consultarlo en /wakeups. Envía únicamente los campos definidos para cada tipo de orden.
