Skip to content
OAOpenAppPhysical Security as a Service
Login

Integrate OpenApp with your existing software

Hotels, campuses, offices, short-term rentals, and locker / parcel operators already run systems of record — property management (PMS/VRMS), student information (SIS), workplace (IWMS), or custom parcel software. OpenApp is designed as an API-first access layer on top of that stack: your software stays authoritative for bookings and identities; OpenApp models who may open which door, when, and how guests are invited.

See Model by sector for the full sector list and which primary system pairs with each.

Your system (PMS / SIS / IWMS / custom)
│ webhook or scheduled job
OpenApp HTTP API or SDK
│ invitations · entity actions · scripting
Doors, gates, intercom portals, audit

Typical responsibilities:

Your systemOpenApp
Reservation / enrollment datesTime-bound access invites
Room or unit identifierPortal ids, entity ids, zones (mapped once at setup)
Checkout / departure eventDisable or delete invite; optional switchable.close
Staff directory (optional)Building users / apartment residents APIs

On check-in (webhook): create an access invite with valid_from / valid_to aligned to stay dates; send the guest the public invite URL or deep link.

On checkout: PUT to disable the invite or DELETE when the link must not be reused.

Pair with Public Access and the STR portfolio playbook.

Same invite pattern as STR, often with additional staff roles and lobby portals. See Boutique hotel playbook for unified orchestration alongside room-lock vendors.

Map dorm or building to an OpenApp org or sub-org. Provision roles via Apartment residents or org user APIs when the SIS emits enrollment changes.

Use OpenApp Scripting for bulk term rollover if many buildings share one template.

IWMS often owns badging and occupancy; OpenApp can orchestrate physical actuators (doors, lifts, parking gates) when IWMS events fire. Prefer read-only discovery agents first; gate switchable.open behind IWMS-approved states.

Model each compartment as an entity (or scripted matrix). Release on pickup code validation in your app → POST .../actions/switchable.open on the compartment entity.

SDK

import os
from datetime import datetime, timezone
from openapp_sdk import AsyncClient
client = AsyncClient(os.environ["OPENAPP_API_KEY"])
INTEGRATION_ID = os.environ["VIRTUAL_ACCESS_INTEGRATION_ID"]
LOBBY_PORTAL_ID = os.environ["LOBBY_PORTAL_ID"]
async def on_check_in(reservation_id: str, arrival: datetime, departure: datetime):
await client.integrations.create_access_invite(
INTEGRATION_ID,
portal_ids=[LOBBY_PORTAL_ID],
name=f"Stay {reservation_id}",
valid_from=arrival.astimezone(timezone.utc).isoformat(),
valid_to=departure.astimezone(timezone.utc).isoformat(),
max_uses=50,
)

Adjust paths to match your deployment; confirm create_integration_access_invite in the API reference for the latest request schema.

Python (HTTP API)

import os
from datetime import datetime, timezone
import httpx
API_BASE = os.environ["OPENAPP_API_BASE"]
API_KEY = os.environ["OPENAPP_API_KEY"]
ORG = os.environ["OPENAPP_ORG_ID"]
INTEGRATION_ID = os.environ["VIRTUAL_ACCESS_INTEGRATION_ID"]
LOBBY_PORTAL_ID = os.environ["LOBBY_PORTAL_ID"]
async def on_check_in(reservation_id: str, arrival: datetime, departure: datetime):
body = {
"portal_ids": [LOBBY_PORTAL_ID],
"name": f"Stay {reservation_id}",
"valid_from": arrival.astimezone(timezone.utc).isoformat(),
"valid_to": departure.astimezone(timezone.utc).isoformat(),
"max_uses": 50,
}
async with httpx.AsyncClient() as http:
await http.post(
f"{API_BASE}/integrations/{INTEGRATION_ID}/access-invites",
headers={
"authorization": f"Bearer {API_KEY}",
"content-type": "application/json",
"x-org": ORG,
},
json=body,
)

HTTP API (curl)

Terminal window
curl -sS -X POST \
-H "Authorization: Bearer ${OPENAPP_API_KEY}" \
-H "Content-Type: application/json" \
-H "X-Org: ${OPENAPP_ORG_ID}" \
-d '{
"portal_ids": ["'"${PORTAL_ID}"'"],
"name": "PMS stay 4821",
"valid_from": "2026-06-01T15:00:00Z",
"valid_to": "2026-06-05T11:00:00Z",
"max_uses": 20
}' \
"${OPENAPP_API_BASE}/integrations/${INTEGRATION_ID}/access-invites"

The response includes invite_token for guest URLs — distribute through your PMS guest messaging, not in public logs.