Room Access Key API is used to read or write room door pin numbers, key storage pin, or other type of room access types. Room Access Key is a generic name for anything that gives guest access to the room - pin, physical key or other types of access in the future. This API allows to:

  • Reading the PIN to, for example, send the guest an sms with their room’s number and PIN. We expect most integrations to care only about reading PINs.
  • For door lock or key storage integrators, inform 3RPMS of what PIN is being used for a reservation, for other integrations to use.

Reading Room Access Key

For most integrations only reading PIN will be relevant.

Currently two types of PINs can be present on a room:

  • RoomAccessPin is used for pins with direct access to the room and used for the entire duration of the stay, e.g., door locks
  • RoomAccessKeyStorage is used for key storage that, after entering pin, will give the guest a physical key to use. This pin is meant to be used only once on arrival, and may not function after.

Example query

Forwards compatability

New Room Access Key types may be added at any time. Your integration must handle cases when roomAccessKey returns a type not queried for.

Given a reservation room’s id, to retrieve a pin for a specific room:

# Variables:
# {
#   "roomId": "<room id>"
# }
query RoomAccessKey($roomId:ID!) {
  room_stays(filter:{id:{eq:$roomId}} first:1) {
    edges {
      node {
        room_setup { name }
        roomAccessKey {
          ... on RoomAccessPin { pin }
          ... on RoomAccessKeyStorage { pin }
        }
      }
    }
  }
}

A reservation may contain multiple rooms, and each room may have a different room access key. To retrieve pins for all rooms inside a reservation, when you have the reservation’s code (not to be confused with reservation’s id):

# Variables:
# {
#   "reservationCode": "<reservation code>",
#   "roomCursor": null
# }
query ReservationRoomAccessKeys($reservationCode:String! $roomsCursor:String = null) {
  reservations(filter:{code:{eq:$reservationCode}}) {
    edges {
      node {
        rooms(first:20 after:$roomsCursor) {
          edges {
            node {
              room_setup { name }
              roomAccessKey {
                ... on RoomAccessPin { pin }
                ... on RoomAccessKeyStorage { pin }
              }
            }
          }
          pageInfo { hasNextPage endCursor }
        }
      }
    }
  }
}

In the response, roomAccessKey.pin can be an alpha-numerical string with length up to 10 characters. RoomAccessKeyStorage will also contain a compartment field, but that must not be shown to end guests.

Pagination

A reservation can contain more rooms than can be returned with one request. Make sure to use pageInfo.hasNextPage and pageInfo.endCursor to read subsequent pages.

Room Access Key Changes

Room access key can change at any time before arrival, or during stay. See webhooks guide, if your integration requires the latest room access keys.

Writing Room Access Key

Intended Use

This section is relevant only for door lock or key storage integrations. Writing room access keys only informs 3RPMS of how to access the room. If your integration does not control any keys, these writes wont do anything.

Basic Flow

  1. createRoomAccessKey() creates a room access key. Until added to a room stay, this will not be visible to users or other integrations.
  2. addRoomAccessKey() assigns a room access key to a room stay. Recommended to do this at least a day before arrival, so that arrival instructions can be sent to guest beforehand.
    • Integrations can add only keys it has created with createRoomAccessKey()
    • Same key can be assigned to multiple rooms at the same time
    • Each room stay can have only one key assigned to it.
  3. removeRoomAccessKey() removes room access key from a room stay.
    • Integrations can remove only its own keys
  4. deleteRoomAccessKey() deletes a room access key; it has to be removed from any room stays first. 3RPMS will delete keys 2 days after departure (or 2 days after not being assigned to any room).
    • Integrations can delete only keys its own keys

1. Create a Room Access Key

There are two types of room access keys - RoomAccessPin and RoomAccessKeyStorage. Either can be created with the same mutation by providing different variables for each:

mutation CreateRoomAccessKey($input:CreateRoomAccessKeyInput!) {
    createRoomAccessKey(input:$input) {
        roomAccessKey { id }
    }
}

In response, you’ll get an id that you need to save, to assign to a room stay and keep track of.

RoomAccessPin type’s use case is when a pin unlocks a door directly. This type has one required field:

  • pin that guest will use to open the door. Up to 10 alpha-numeric characters. Both uppercase and lowercase is allowed, but not both at the same time.

Variable structure to use for this type, with the previously mentioned mutation:

{
  "input": {
    "roomAccessPin": {
      "pin": "1234567890"
    }
  }
}

RoomAccessKeyStorage use case is when a pin is used to on arrival get a physical key that is then used for the duration of the stay. This type has two required fields :

  • pin that guest will use to access key storage. Up to 10 alpha-numeric characters. Both uppercase and lowercase is allowed, but not both at the same time.
  • compartment where hotel staff will place the key. Usually not relevant for guests. Up to 10 alphanumeric characters.

Variable structure to use for this type, with the previously mentioned mutation:

{
  "input": {
    "roomAccessKeyStorage": {
      "pin": "1234567890",
      "compartment": "3R"
    }
  }
}

2. Assign a Room Access Key

A newly created room access key will not be used for anything. For hotel staff and other systems to be aware of a Room Access Key, it has to be assigned to a Room Stay. Assignment is done the sameway for all Room Access Key types:

# Variables:
# {
#   "addRoomAccessKey": {
#     "roomStayId": "<room stay id>",
#     "roomAccessKeyId": "<room access key id>"
#   }
# }
mutation AddRoomAccessKey($addRoomAccessKey: AddRoomAccessKeyInput!) {
  addRoomAccessKey(input:$addRoomAccessKey) {
    roomStay {
      room_setup { id name }
      arrival: reservation_from
      departure: reservation_to
      roomAccessKey { id }
    }
  }
}

Recommendation

Room Access Key should be assigned to the room at least a day before arrival, to allow sending out arrival instructions.

3. Listen for Room Stay Changes

Room Stay arrival, departure and physical room can change at any time. Your integration may need to listen for room changes so that a pin works when, for example, booking is moved up by a week.

Scenarios to handle:

  • Arrival/Departure change
  • Room Stay moved to a different physical room
  • Room Stay deleted
  • Reservation cancelled or re-activated
  • Room Stay created
    • In some cases, a newly created room stay may use an already existing room access key. For example, when an existing room stay is split in two separate ones.

Most scenarios are applicable only when using door pin, but some are relevant for key storage as well.

There’s two approaches for this:

  1. Polling - Loading data every minute to see if any relevant rooms or reservations have changed.
  2. Webhooks - Receive a webhook from 3RPMS whenever some data changes.

Polling

Polling is not recommended, as (1) updates will always be delayed, and (2) easy to go over rate limits. That said, for simple and small scale deployments this approach may be suitable.

To cover the previous scenarios in an optimal way, two queries are needed:

  1. Read rooms for all current keys you control
  2. Read rooms in a given date period

Changes to rooms with assigned Room Access Key

# Variables
# {
#   "roomAccessKeyIds": ["abc", "def"],
#   "idsCount": 2
# }
query RelevantRoomStays($roomAccessKeyIds: [ID!]! $idsCount:Int! $roomsCursor:String = null) {
  roomAccessKeys(filter:{id:{in:$roomAccessKeyIds}} first:$idsCount) {
    edges {
      node {
        id
        roomStays(first:20 after:$roomsCursor) {
          edges {
            node {
              arrival: reservation_from
              departure: reservation_to
              room_setup { id }
              reservation { status }
            }
          }
        }
      }
    }
  }
}

In the previous query variables, roomAccessKeyIds is ids of Room Access Keys your integration controls.

Changes to rooms in a given date period

Retrieves all non-cancelled rooms that arrive or stay between Jan 30th and Feb 5th

# Variables
# {
#   "start": "2023-01-30",
#   "end": "2023-02-05"
# }
query RoomStays($start:Date! end:Date! $cursor:String=null) {
  room_stays(filter:{reservation_from:{le:$end} reservation_to:{gt:$start}} first:20) {
    edges {
      node {
          room_setup { id }
          arrival: reservation_from
          departure: reservation_to
          roomAccessKey { id }
      }
    }
  }
}

Webhooks

The recommended approach is using webhooks. Relevant webhooks events to listen for changes:

  • room_stay.created - In some cases\, a newly created room stay may use a previously created key. E.g.\, when an existing room stay is split in two separate ones.
  • room_stay.updated - Changes to arrival\, departure or physical room may be of interest.
  • room_stay.deleted - When a room stay\, that had your integration’s key assigned\, is deleted\, your integration may need to remove some access on your side.
  • reservation.updated - When a reservation\, that had your integration’s key assigned\, is cancelled\, your integration may need to remove some access on your side. Similarly when a reservation is activated.
  • room_access_key.deleted

See webhooks guide on how to use them.

4. Revoke a Room Access Key

A Room Stay can have only on Room Access Key assigned. To change pin, or assign a different Room Access Key, the previous one has to be revoked. This is the same for all Room Access Key types:

# Variables
# {
#   "removeRoomAccessKey": {
#     "roomStayId": "<room stay id>",
#     "roomAccessKeyId": "<room access key id >"
#   }
# }
mutation RemoveRoomAccessKey($removeRoomAccessKey:RemoveRoomAccessKeyInput!) {
  removeRoomAccessKey(input:$removeRoomAccessKey) {
    roomStay {
      id
      roomAccessKey {
        id
      }
    }
  }
}

5. Delete a Room Access Key

After departure, or when your integration knows the key is no longer needed, its recommended to delete the room access key. Only Room Access Keys that have not been assigned to any rooms can be deleted.

# Variables
# { 
#   "roomAccessKeyId": "abc"
# }
mutation DeleteRoomAccessKey($roomAccessKeyId:ID!) {
  deleteRoomAccessKey(input:{roomAccessKeyId: $roomAccessKeyId}) {
    deleted
  }
}

Cleanup

3RPMS will revoke and delete Room Access Keys it thinks are no longer used. This happens 2 days after room stay departure, or 2 days of not being assigned to any room.