Hotel PMS Integration Guide: Mapping Your Data to Seam

Last updated

Overview

When integrating Seam into your hotel PMS, you need to map your existing resources (properties, rooms, bookings) to Seam's resources (Connected Accounts, Spaces, Access Grants). Seam makes this easy by allowing you to tag each Seam resource with your own internal IDs using resource keys.

This guide shows you how to map:

  • Hotel properties → Seam Connected Accounts (using customer_key)

  • Hotel rooms → Seam Spaces (using space_key)

  • Guest records → Seam User Identities (using user_identity_key)

  • Guest bookings → Seam Access Grants (using access_grant_key)

Once mapped, you can retrieve Seam resources directly using your PMS IDs, making integration seamless.


Step 1: Map Hotel Properties to Seam Connected Accounts

Each hotel property in your PMS needs to connect their access control system to Seam. When you create a Connect Webview for a property, you tag it with your PMS property ID using customer_key. This creates a permanent link between your property and their Seam Connected Account.

How to Map Properties

When setting up a new hotel property in your system, create a Connect Webview tagged with your property ID:

Text
1seam.connect_webviews.create(
2  accepted_providers=["salto", "assa_abloy_visionline", "dormakaba_oracode"],
3  customer_key="hotel-property-123"  # Your PMS property ID
4)

Send this Connect Webview to the hotel. When they complete authentication, Seam automatically copies the customer_key to their Connected Account. Now you can always find their Seam account using your property ID.

Retrieving Mapped Properties

Retrieve all Connected Accounts for a specific property using your PMS property ID:

Text
1connected_accounts = seam.connected_accounts.list(
2  customer_key="hotel-property-123"
3)

Then retrieve devices or access control systems depending on what the hotel connected:

For consumer smart locks (August, Yale, etc.):

Text
1devices = seam.devices.list(
2  connected_account_id=account.connected_account_id
3)

For access control systems (Salto, ASSA ABLOY, etc.):

Text
1# Get the access control system
2acs_systems = seam.acs.systems.list(
3  connected_account_id=account.connected_account_id
4)
5
6# Get all doors/entrances in the system
7acs_entrances = seam.acs.entrances.list(
8  acs_system_id=acs_system.acs_system_id
9)

Step 2: Map Hotel Rooms to Seam Spaces

After a hotel connects their access control system, you need to map each room in your PMS to a Seam Space. A Space represents a physical location (like a hotel room) and can have one or more doors/entrances.

How to Map Rooms

For each room in your PMS, create a Space tagged with your room ID:

Text
1seam.spaces.create(
2  name="Room 304",
3  acs_entrance_ids=[door_entrance_id],
4  space_key="property-123-room-304"  # Your PMS room ID
5)

The space_key links the Seam Space to your room record. You can now reference this room using your existing room ID whenever you need to grant access.

For multi-door rooms (like suites), include multiple entrance IDs:

Text
1seam.spaces.create(
2  name="Presidential Suite 1200",
3  acs_entrance_ids=[main_door_id, bedroom_door_id],
4  space_key="property-123-suite-1200"
5)

Retrieving Mapped Rooms

Retrieve a Space directly using your PMS room ID:

Text
1room_space = seam.spaces.get(
2  space_key="property-123-room-304"
3)

Step 3: Create User Identities for Guests

Before creating access grants, you need to create a User Identity for each guest. User Identities represent the people receiving access and are especially important for mobile keys, which need to be tied to a specific person.

How to Map Guest Records to User Identities

Create a User Identity tagged with your guest ID using user_identity_key:

Text
1user_identity = seam.user_identities.create(
2  user_identity_key="guest-12345",  # Your PMS guest ID
3  full_name="Jane Smith",
4  email_address="jane.smith@example.com",
5  phone_number="+1-415-555-0123"
6)

Recommendation: Use your internal guest ID directly as the user_identity_key. This makes it simple to retrieve the User Identity later:

Text
1user_identity = seam.user_identities.get(
2  user_identity_key="guest-12345"  # Your PMS guest ID
3)

Mobile Keys vs. Physical Cards

For mobile keys: Always create a unique User Identity for each guest, as mobile keys are delivered to their personal device via email or SMS.

For plastic cards: We recommend:

  • Reuse a generic User Identity for all guests in the same reservation (e.g., use your booking ID as the user_identity_key)

Since plastic cards aren't tied to a device, the User Identity is primarily for record-keeping rather than credential delivery.


Step 4: Create Access Grants for Guest Bookings

When a guest checks in, you create Access Grants that grant them access to their room. A single booking can have multiple Access Grants - for example, one for a plastic card and another for a mobile key. Tag each Access Grant with your booking ID using reservation_key so you can retrieve all access grants for a booking.

How to Map Bookings

At check-in, create an Access Grant tagged with your booking ID:

Text
1# Create mobile key access grant
2mobile_grant = seam.access_grants.create(
3  user_identity_id=guest_user_identity_id,
4  starts_at="2025-12-15T15:00:00.000Z",
5  ends_at="2025-12-18T11:00:00.000Z",
6  space_ids=[room_space_id],
7  requested_access_methods=[{"mode": "mobile_key"}],
8  reservation_key="booking-78901"  # Your PMS booking ID
9)
10
11# Create card access grant for the same booking
12card_grant = seam.access_grants.create(
13  user_identity_id=booking_user_identity_id,
14  starts_at="2025-12-15T15:00:00.000Z",
15  ends_at="2025-12-18T11:00:00.000Z",
16  space_ids=[room_space_id],
17  requested_access_methods=[{"mode": "card"}],
18  reservation_key="booking-78901"  # Same booking ID
19)

The reservation_key links all Access Grants to your booking record. Access automatically expires at checkout time based on ends_at.

Retrieving All Access Grants for a Booking

Retrieve all Access Grants for a booking using your PMS booking ID:

Text
1access_grant = seam.access_grants.list(
2  reservation_key="booking-789456"
3)
4
5# Returns all access grants for this booking (mobile key, card, etc.)

How Resource Keys Work

When you create Seam resources, you tag them with your PMS IDs using resource keys. Seam stores these keys, allowing you to retrieve Seam resources directly using your existing identifiers.

What gets stored in Seam:

  • customer_key - Your property ID

  • space_key - Your room ID

  • user_identity_key - Your guest ID

  • access_grant_key - Your booking ID

How to retrieve using your IDs:

Text
1# Find a property's connected accounts using your property ID
2accounts = seam.connected_accounts.list(
3  customer_key="hotel-property-123"  # Your PMS property ID
4)
5
6# Find a room using your room ID
7room = seam.spaces.get(
8  space_key="property-123-room-304"  # Your PMS room ID
9)
10
11# Find a booking's access grant using your booking ID
12grant = seam.access_grants.get(
13  access_grant_key="booking-789456"  # Your PMS booking ID
14)

Since Seam stores your IDs as resource keys, you don't need to maintain a separate mapping table. Just use your existing PMS IDs when calling Seam's API.


Complete Workflow Examples

Check-in with Physical Key (Encoder)

Text
1# 1. Create user identity (per-booking for plastic cards)
2user_identity = seam.user_identities.create(
3  user_identity_key="booking-78901",  # Use booking ID for plastic cards
4  full_name=guest_name
5)
6
7# 2. Find the room and create access grant with your booking ID
8room = seam.spaces.get(space_key=f"room-1234"). # Your PMS room ID
9
10grant = seam.access_grants.create(
11  user_identity_id=user_identity.user_identity_id,
12  starts_at=checkin_datetime,
13  ends_at=checkout_datetime,
14  space_ids=[room.space_id],
15  requested_access_methods=[{"mode": "card"}],
16  reservation_key="booking-78901"  # Your PMS booking ID
17)
18
19# 3. Retrieve the card access method from the grant
20access_methods = seam.access_methods.list(
21  access_grant_id=grant.access_grant_id
22)
23
24card_method = next(am for am in access_methods if am.mode == "card")
25
26# 4. Encode the physical key at front desk
27seam.acs.encoders.encode_card(
28  acs_credential_id=card_method.acs_credential_id,
29  acs_encoder_id=front_desk_encoder_id
30)

Check-in with Mobile Key

Text
1# 1. Create or retrieve the user identity for the guest
2user_identity = seam.user_identities.create(
3  user_identity_key="guest-12345",  # Your PMS guest ID
4  full_name=guest_name,
5  email_address=guest_email,
6  phone_number=guest_phone
7)
8
9# 2. Find the room Space using your PMS room ID
10room = seam.spaces.get(space_key=f"room-1234")  # Your PMS room ID
11
12# 3. Create access grant tagged with your PMS booking ID
13grant = seam.access_grants.create(
14  user_identity_id=user_identity.user_identity_id,
15  starts_at=checkin_datetime,
16  ends_at=checkout_datetime,
17  space_ids=[room.space_id],
18  requested_access_methods=[{"mode": "mobile_key"}],
19  reservation_key="booking-78901"  # Your PMS booking ID
20)
21
22# 4. Retrieve the mobile key access method from the grant
23access_methods = seam.access_methods.list(
24  access_grant_id=grant.access_grant_id
25)
26
27mobile_key = next(am for am in access_methods if am.mode == "mobile_key")
28
29# 5. Send guest the mobile key URL
30send_sms(guest_phone, mobile_key.instant_key_url)

Early Check-out

Text
1# Find all access grants for the booking and revoke them
2grants = seam.access_grants.list(reservation_key=f"booking-12345")
3
4for grant in grants:
5  seam.access_grants.delete(access_grant_id=grant.access_grant_id)

Looking Up Guest Access During Stay

Text
1# Guest reports they can't get into their room - look up by booking ID
2grant = seam.access_grants.get(access_grant_key=f"booking-1234")
3
4# Check grant time frame
5print(f"Active: {grant.starts_at} to {grant.ends_at}")
6
7# Check status of issued access methods
8access_methods = seam.access_methods.list(access_grant_id=grant.access_grant_id)
9
10for method in access_methods:
11  print(f"{method.mode}: {method.status}")
12  # Status could be: "issued", "unissued", "issuing", etc.

Best Practices for Resource Mapping

Use Your Internal IDs Directly

Use your existing PMS identifiers directly as resource keys:

  • customer_key: Your property ID (e.g., "property-456")

  • space_key: Your room ID (e.g., "room-304")

  • user_identity_key: Your guest ID (e.g., "guest-12345")

  • access_grant_key: Your booking ID (e.g., "booking-78901")

This creates a direct mapping between your PMS identifiers and Seam resources.

Create Spaces Once, Reference Many Times

Map rooms to Spaces once when setting up a property:

Text
1# Do this once during property setup
2for room in property.rooms:
3  seam.spaces.create(
4    name=f"Room {room.number}",
5    acs_entrance_ids=[room.door_id],
6    space_key=f"property-{property.id}-room-{room.number}"
7  )

Then reference the Space using space_key for every booking:

Text
1# Do this at every check-in
2room = seam.spaces.get(space_key=f"property-{property_id}-room-{room_number}")
3# Create access grant referencing this Space...

Handle Multi-Property Integrations

For PMS systems serving multiple hotel properties:

  1. Create separate Connect Webviews for each property with unique customer_key

  2. Always filter operations by customer_key to keep properties isolated

  3. Store the customer_key to property_id mapping in your database

Text
1# When querying devices for a specific property
2accounts = seam.connected_accounts.list(customer_key=f"hotel-property-{property_id}")

Additional Resources


Need Help?

If you have questions about implementing this data model or need assistance with your specific use case, contact Seam support (support@seam.co) or your solutions engineer.

Still need help? Our support team will take a look.

Smart Locks
Access Systems
Knowledge
Lock Capabilities
Thermostats
Sensors
© 2026 Seam Labs, Inc.