PMS Integration for Smart Hotels: Connecting Opera, Mews and Apaleo to IoT Room Controls
Start Blog PMS Integration for Smart Hotels: Connecting Opera, Mews and Apaleo to IoT Room Controls
Hospitality Architecture Best Practices Hospitality Integrations IoT PMS

PMS Integration for Smart Hotels: Connecting Opera, Mews and Apaleo to IoT Room Controls

📅 April 2026 ⏳ 12 min read FSS Engineering Team

The most expensive square meter in any luxury hotel is the one nobody is in. An empty suite still draws power, still runs HVAC at full setpoint, still leaves do-not-disturb logic up to the room itself. Multiply that across 300 keys and you start to see why Property Management System (PMS) integration is no longer a back-office concern; it is the central nervous system of a connected hotel.

At FSS Technology, we build the hardware, firmware and cloud that sit between the PMS and the physical room. This article is the engineering playbook we wish existed when we first connected our GEST service-call system to Oracle Opera Cloud, Mews and Apaleo. It covers webhook patterns, OAuth flows, room-state machines, energy strategies on checkout, GDPR considerations and the failure modes nobody warns you about.

Why PMS-IoT integration matters more than dashboards do

Hoteliers buy IoT for one of three reasons: guest experience, operational efficiency or energy savings. None of those payoffs materialize if the room does not know its own state. A thermostat that runs at 22 degrees while the room is vacant for three days is not a smart thermostat. A do-not-disturb light that ignores a checked-out guest is a liability. A service request from a guest who already left is noise.

The PMS knows. It knows when a reservation is created, when a guest checks in, when housekeeping marks a room clean, when a no-show is processed. Surfacing that knowledge to the room controller, the BMS, the lock, the AV system and the staff mobile app is what separates connected hotels from hotels with WiFi thermostats. The PMS is the canonical source of truth for occupancy state, and any IoT system that does not consume from it is guessing.

The major PMS platforms and their integration models

Oracle Opera Cloud (OHIP)

Oracle Hospitality Integration Platform (OHIP) is the modern REST surface for Opera Cloud. Authentication uses OAuth 2.0 client credentials with an additional x-app-key and x-hotelid header pattern. Webhooks are available through the OHIP Async APIs and can deliver reservation, room status and housekeeping events with sub-second latency in production. Rate limits are generous but enforced per integration key, typically around 60 requests per second per tenant, so design for backoff from day one. Opera also still ships an on-premises variant whose XML interface (OXI) you may need to support for older properties; budget extra integration time when you encounter it.

Mews

Mews exposes the Connector API for partner integrations and the Open API for properties to expose their own data. Authentication uses an access token plus a client token issued during partner onboarding. Mews supports webhooks for reservation events, but you still need to call reservations/getAll with a date range to fully reconcile state after downtime. The Mews data model is event-sourced under the hood, which makes idempotency easier than on legacy PMS platforms. The Marketplace certification process is real engineering review, not a rubber stamp; plan two to four weeks for partner onboarding.

Apaleo

Apaleo is the cleanest of the three from a developer perspective. Pure REST, OAuth 2.0 with proper scopes (reservations.read, maintenances.manage, etc.), and a first-class webhook subscription endpoint. The free developer sandbox is a real environment, not a stub, which makes CI integration trivial. Apaleo’s open-by-default philosophy means you almost never need to ask for a special endpoint; if it exists in the product, it is in the API.

Cloudbeds and others

Cloudbeds offers a REST API and webhooks similar to Apaleo but with stricter scope review. Protel, Stayntouch and Shiji each have their own conventions; the patterns in this article apply, but specifics differ. Always read the partner agreement before assuming a given event type is available.

Webhooks vs polling: why you need both

Webhooks are obviously preferable. They are low-latency, cheap, and event-driven. But every PMS we have integrated has dropped events at least once. Network blips, partner-side queue failures, expired endpoints, malformed payloads, IP allow-list misconfigurations. If you trust webhooks alone, you will eventually run with stale state and not know it.

The pattern that works in production is webhooks for real-time events plus a reconciliation job that runs every 5 to 15 minutes and pulls the authoritative state for any room flagged as active. We push the events through Azure Event Hubs for buffering and process them with Azure Functions, which gives us automatic retry, dead-letter handling and observability without writing infrastructure code. The same pattern is described in our IoT data pipeline article and translates directly to the hospitality domain.

OAuth flows for partner integrations

Three flows cover 95 percent of PMS integrations:

  1. Client credentials for server-to-server. Used by Opera Cloud and Apaleo for backend integrations. Token TTL is typically one hour; cache it, refresh proactively at 80 percent of TTL.
  2. Authorization code with PKCE for properties to grant access to your platform. Used by Apaleo and Mews. Store the refresh token encrypted at rest in Azure Key Vault.
  3. Long-lived access tokens issued during partner onboarding. Used by Mews Connector API. Treat them like service account credentials and rotate annually.

Never store tokens in application configuration or environment variables that are not backed by a secrets manager. We cover the broader posture in our IoT security best practices guide; the same principles apply at the integration layer.

Room-state synchronization

The canonical room state machine has more states than people assume. At minimum:

Each transition needs a side-effect plan. Vacant-clean to occupied triggers loading of the guest preference profile; occupied to vacant-dirty fires the energy reset and disables in-room voice assistants; do-not-disturb on the door panel mirrors to staff devices and to the corridor light over the door. Model the state machine explicitly, in code, with assertions on illegal transitions. Free-form boolean flags scattered across services will eventually contradict each other in production, and the cost of fixing it after launch is an order of magnitude higher than getting it right the first time.

Sample webhook payload (Apaleo reservation)

{
  "topic": "Reservation",
  "type": "CheckedIn",
  "timestamp": "2026-04-24T14:32:11.482Z",
  "accountId": "FSS-DEMO",
  "propertyId": "BB-GRAND",
  "data": {
    "reservationId": "GXNRPL-1",
    "unitId": "BB-GRAND-407",
    "unitGroupId": "DLX-KING",
    "primaryGuest": {
      "id": "guest_8f2c",
      "preferences": {
        "temperatureC": 21.5,
        "pillowType": "down-alt",
        "wakeupSceneAt": "07:30",
        "languageTag": "en-GB"
      }
    },
    "arrival": "2026-04-24T14:00:00Z",
    "departure": "2026-04-27T11:00:00Z",
    "adults": 2,
    "children": 0
  },
  "signature": "sha256=8b4c7f1e9a..."
}

Two things matter here. First, the signature: every production webhook should be HMAC-signed with a shared secret. Reject unsigned or invalid payloads at the edge. Second, the preference object: if the PMS does not store guest preferences natively (most do not, in a structured form), you need a side-table keyed by guest ID that your integration layer joins on the fly.

Node.js / TypeScript reference handler

import { app, HttpRequest, InvocationContext } from "@azure/functions";
import { createHmac, timingSafeEqual } from "node:crypto";
import { ServiceBusClient } from "@azure/service-bus";

const WEBHOOK_SECRET = process.env.APALEO_WEBHOOK_SECRET!;
const SB_CONN = process.env.SERVICE_BUS_CONNECTION!;
const sb = new ServiceBusClient(SB_CONN);
const sender = sb.createSender("room-state-events");

function verify(req: HttpRequest, raw: string): boolean {
  const header = req.headers.get("x-apaleo-signature") ?? "";
  const expected = "sha256=" + createHmac("sha256", WEBHOOK_SECRET)
    .update(raw).digest("hex");
  const a = Buffer.from(header);
  const b = Buffer.from(expected);
  return a.length === b.length && timingSafeEqual(a, b);
}

app.http("pmsWebhook", {
  methods: ["POST"],
  authLevel: "anonymous",
  handler: async (req: HttpRequest, ctx: InvocationContext) => {
    const raw = await req.text();
    if (!verify(req, raw)) {
      ctx.warn("Rejected webhook: bad signature");
      return { status: 401 };
    }
    const evt = JSON.parse(raw);
    await sender.sendMessages({
      body: evt,
      messageId: `${evt.data.reservationId}:${evt.type}:${evt.timestamp}`,
      subject: evt.type,
      applicationProperties: {
        propertyId: evt.propertyId,
        unitId: evt.data.unitId
      }
    });
    return { status: 202 };
  }
});

Three details that matter in production: the messageId guarantees idempotency at the Service Bus layer, the timing-safe comparison prevents signature timing attacks, and returning 202 (not 200) signals “accepted, processing” which most PMS partners treat as success without retry.

Guest preference profiles and automatic room setup

The dream scenario is that a returning guest walks into a room already at their preferred temperature, with their preferred lighting scene loaded and their language set on the in-room tablet. The reality is that PMS guest profiles are messy: free-text notes, inconsistent codes, missing data for first-time guests.

The pattern that works is a preference service that owns the structured schema, joined to the PMS guest ID. On check-in, the integration layer fires a single command to the room controller with the resolved preferences. If preferences are missing, fall back to brand defaults, never to whatever the previous guest left behind. The brand-default fallback is the single biggest improvement most properties can make in their guest-experience scores; it eliminates the “why is the room set to 16 degrees” complaint at zero engineering cost.

Energy management on checkout

Checkout is the highest-leverage event for energy savings. The instant the PMS marks a reservation as departed, the integration should:

  1. Set HVAC to eco band (typically 18 to 26 degrees C, configurable per climate)
  2. Turn off all lighting circuits except the entry path
  3. Close powered drapes if installed
  4. Disable in-room AV standby power on switched outlets
  5. Mark the room as ready for housekeeping in the staff app

Across a 250-room property, the difference between disciplined checkout automation and “guest left the AC on” is regularly 12 to 18 percent on HVAC energy spend. This is the line item that pays for the entire integration project within 18 months.

Do-not-disturb propagation

DND is deceptively complex. The signal can originate from the door panel, the in-room tablet, the guest mobile app or the PMS itself (some properties allow front desk to set DND remotely). It needs to propagate to housekeeping tablets, the corridor light, the room service ordering system and any robotic delivery integration.

Model DND as a bidirectional flag on the room state, with last-write-wins semantics and a source attribution. Always log who or what set it, with timestamps. Disputes about whether a guest was disturbed during DND become much easier to resolve when you have a verifiable audit trail.

Service request workflow with GEST

Our GEST system handles in-room service requests: extra towels, room service, maintenance, concierge. The PMS integration enriches every request with reservation context (guest name, language, VIP status, allergies, special instructions) and routes it to the right department with the right SLA.

The closed loop is what matters: when housekeeping closes a request in the GEST staff app, the integration writes a note back to the PMS guest folio. This single behavior dramatically improves recurring-guest experience because the next stay starts with full context.

Error handling and retry logic

The retry strategy that survives real-world PMS quirks looks like this:

Every dead-letter event needs a human-friendly summary in the operations dashboard. Engineers should never have to read raw JSON to triage a stuck reservation. Pair the dead-letter view with a one-click “replay after fix” action, scoped per tenant and gated on RBAC.

GDPR and data residency

Guest data flowing through your integration is personal data under GDPR. Three rules cover most of the risk:

  1. Minimize: only ingest the fields you actually need. Full passport scans almost never belong in your IoT layer.
  2. Localize: deploy the integration in the same Azure region as the property, particularly for EU properties. We default to Germany West Central or West Europe for European hotels.
  3. Expire: drop guest preference cache 30 days after departure unless the guest has explicitly opted into long-term personalization.

Document your data flow in a Record of Processing Activities (ROPA) and make it available to the property’s DPO. This is not optional for hotels operating in the EU.

Common pitfalls

Architecture summary

The reference architecture we deploy looks like this: webhook receivers as Azure Functions behind API Management, events buffered in Service Bus, processing handlers grouped by event type, room-state projections in Cosmos DB, room commands published to Azure IoT Hub for delivery to room controllers, and an analytics fan-out to the property dashboard via our analytics layer. The whole thing is stateless except for the projection store, which makes blue-green deploys trivial.

For broader integration patterns across our platform, see FSS Integrations, and for the cloud foundations underneath, see FSS Cloud. Mobile staff workflows tie into the same projection store via our mobile control service, so housekeeping, maintenance and concierge teams all see consistent state without bespoke integrations.

Bringing it together

PMS-IoT integration is the difference between a hotel that has IoT and a hotel that runs on IoT. Done right, it is invisible: guests notice the room feels right, staff notice the requests close themselves, finance notices the energy line item drop. Done wrong, it is the source of every complaint that starts with “why did the room”.

If you operate a luxury or boutique property and want to connect your PMS to a production-grade IoT control layer, the team at FSS Connected Devices can take you from architecture review to a deployed pilot in 8 to 12 weeks. We bring the hardware, the firmware, the cloud and the PMS integration patterns proven across multiple European hotel groups, so your property gets a working system rather than a six-month integration project. Talk to us about a pilot on one floor before committing the full estate.

Building something connected?

FSS Technology designs and builds IoT products from silicon to cloud — embedded firmware, custom hardware, and Azure backends.

Talk to our team →