Schlage Lock Integration Debugging

Overview

Since we implemented Schlage v2 in November 2024, lock programming is now asynchronous. We issue the "Set / Update Access Code" API call, and the Schlage servers immediately respond with an "Okay" command before the lock has actually been updated. This response does not mean the lock access code succeeded or failed but it does give us a command I.D. to look up the state.

Additionally, Schlage will send webhooks with status updates if the command succeeds, fails, or times out. To handle missing webhooks, we have a SchlageDoorCodeSyncService that runs and looks for any pending commands that are older than 5 minutes that will look up the status and fail/complete as applicable.

Event Flow

1 - Something Triggers a Door Code Sync

  • Booking Created (if integration "Generate When" is "At Booking")
  • Guest change (if integration "Code Generation" is "Use the guest's phone number")
  • Trigger (if integration "Generate When" is "A number of days before arrival")
  • If the user manually click Set Code / Sync / Regenerate from the Booking Overview

2 - OwnerRez sends Schlage API the access code

The API will either return an error or "202 (Accepted)" with a command ID.

API Call Sequence:

  1. If applicable, we will refresh the API access token (POST https://account.schlage.com/oauth2/token)
  2. We will query the API for the lock details (GET https://api.allegion.com/schlage-home/Devices)
    • This is to specifically get the "vlac", or Variable-Length-Access-Code feature flag, so we know if we can send any arbitrary length access code, or half to limit the code length
  3. We will then try to set the access code (PUT https://api.allegion.com/schlage-home/Devices/{account id}/accesscodes)
  4. If we get an error that either the code name or access code are in use, we will query the lock for a list of existing access codes to try and match to our code (GET https://api.allegion.com/schlage-home/Devices/{account id}/accesscodes)
    • If the access code start and end date match (ignoring time), and the guest name (Full, First + Last Initial, First, ORB#) ignoring case, spaces, and special characters matches, we "adopt" that access code and will issue an update command just to make sure the start and end time are correct (PUT https://api.allegion.com/schlage-home/Devices/{account id}/accesscodes/{code id})
    • If we cannot match up the code, we will return an error

Example:

3 - Wait for a webhook

Schlage will send us a webhook if the command is successful, errors, or times out.

  • Success
    • We confirm the Booking Door Code, taking it out of the Pending status
  •  Timeout
    • We actually ignore this event.
    • Schlage will send a timeout after 30 seconds, and this is not configurable. We found this is too strict, and sometimes lock may later get the code, so sending the user an email at this point was premature as sometimes they would log in and see the code was actually there.
  • Any other state
    • We send the user a failure email

Examples:

 

4 - Schlage Door Code Sync Service

This service will only run against pending codes and will wait 5 minutes after the command is sent to the server.

We will look up the command state from the Schlage API and apply similar logic as the webhooks:

  • Success
    • We confirm the Booking Door Code, taking it out of the Pending status
  • Pending after 5 minutes
    • Fail the door code, and send a "pending for more than 5 minutes" error
  • Any other state
    • Fail the door code, and attempt to read any errors from the API response, otherwise, say reason "unknown"

Examples:

Common Issues

Access code/code name are already in use OR Access code ID not found on device

The initial API calls work (step 2), but the webhook/sync service comes back and says the access code/code name is already in use.

The explanation we got from Schlage about this is the API servers, and the physical lock hardware are suffering from a "split-brain" situation. The database of codes on the lock does not match the list of codes the API servers are aware of. According to Schlage, at the time we reported this error, there was no way for the lock hardware to send the API servers the list of codes it had to resolve the data mismatch. The only solution to fix this problem is to delete all the codes on the lock and set them up again. Users can use the "Delete All" button in the Schlage Home app.

 

Commands frequently timeout

Commands frequently, but sporadically, timeout. Manually resyncing the code can help, but users want it to work on the first try.

We have raised this to Schlage multiple times, and while they are aware it happens, they have not been able to offer a solution. They generally blame "real world factors", which could include:

  • Poor Wi-Fi coverage on-site
  • Intermitted internet connectivity on-site
  • Low/poor quality batteries
  • Unreported service interrupts with Schlage's API servers

Users should try:

Door Code Sync Service shows a "Nack" state

This indicates there is no acknowledgement from the lock. Users should try the same interventions for environmental factors listed in the "Commands frequently timeout" section above or reach out to Schlage support.

"Schedule parameters are not valid" Error

We have an open request with Schlage about this and are waiting on more information.

https://developersupport.allegion.com/hc/en-us/requests/25566

"User not found in the device" Error

According to Schlage, this is due to a lock desync issue, and they are currently working on a fix. Users should try the "Delete All" to remove all the codes, and if that doesn't work, to factory-reset.

https://developersupport.allegion.com/hc/en-us/requests/52258

"Unrecognized job state" Error

This is an error saying that the booking is not associated to a lock, meaning that the Settings > Door Locks > Schlage pages need to be verified for active connection and correct property mapping.