Skip to content

Keyless access that follows the booking: what has to be true before you trust a door

Connecting a smart lock takes an afternoon. Trusting it at 1am, when a guest is outside with a phone and nobody is at the desk, is a different engineering problem — and it is decided by where the access decision lives.

Updated · By

The decision has to live where bookings live

Every keyless access project starts with the same shortcut: create the credential directly in the lock vendor's dashboard, or through their API, and move on. It works until the booking changes.

A reservation is cancelled, shortened, moved a week later, upgraded to a different room. If the access decision only exists inside the provider, each of those is a manual cleanup that somebody has to remember, and the failure mode is a working credential for a stay that no longer exists.

So Boris keeps the intent — which person may open which door, from when until when — as its own record, and treats the provider as the thing that enforces it. The provider can be replaced, can be down, can be two providers in two buildings. The intent is still the booking's.

The Boris reception screen with today's arrivals and departures and a check-in action for each
Access is one of the steps that follows a confirmed booking, alongside check-in, registration and payment.

Never let a door block a booking

This is a small architectural decision with outsized consequences. If creating access is part of saving a booking, then an access provider having a bad afternoon means your staff cannot take reservations.

Access provisioning is downstream of the booking, triggered by the booking event, and its failure is recorded rather than propagated. The reservation saves. The grant stays pending. Someone can see it.

Pending is the right answer; failed is not

When the provider is unreachable, there are three possible behaviours and only one is acceptable.

  • Fail the grant. A guest arrives to a door that will not open, and nothing in the system is trying to fix it.
  • Succeed optimistically. Worse: the record says access was granted, and nobody looks again.
  • Stay pending and retry. The intent persists, a scheduled job keeps pushing, and staff can see the stays whose access has not landed yet.

Retrying only works if every push is idempotent. Pushing the same grant twice must not produce two credentials — otherwise the mechanism meant to recover from an outage becomes a slow leak of valid keys.

A moved booking is a revoke and a re-push

The instinct is to edit the credential's validity window. The safe implementation revokes the old grant and pushes a new one, because the thing that must never happen is a credential valid for last week's window surviving into this week's.

Cancellation is the same mechanism with no second half. Both are driven by the booking event — not by a nightly cleanup, and definitely not by a person noticing.

When access starts is a commercial decision, not a technical one

Some operators want the door to work the moment a booking is confirmed. Others want it only after check-in is complete, or after the stay is paid. These are genuinely different businesses, and the difference is not something software should decide on their behalf.

In Boris the trigger is configured per connection, which also means the compliance-sensitive version is available: in a lodging workspace you may need identity details registered before a guest can open anything, and tying access to the completed check-in makes that structural rather than a matter of staff discipline.

Only a door event proves anything

The most common overstatement in access integrations is treating a 200 response as proof. It proves the provider accepted your instruction. It does not prove a credential reached a person, or that a person opened a door.

Reading events back from the provider and matching them to the grant window is what closes the loop. It turns "we sent the access" into "the door opened at 23:41", which is the only version that answers a guest complaint, and the only version worth putting in an operational log.

What to check before you choose a provider

Boris connects several access providers — Kisi, Salto, Akiles, Tapkey, Brivo, Doordeck and Nuki among them — and they differ in ways that matter more than their feature lists:

  1. Is granting idempotent, or does a retry create a second credential?
  2. Can a grant carry a validity window, or only an on/off state you have to manage yourself?
  3. Are door events readable back through the API, with timestamps you can match?
  4. Does revoking take effect immediately, or at the lock's next sync — and do you know which?
  5. What happens to a credential if the lock is offline when you revoke?

Being straight about status: these connections are marked beta in Boris, and they run against each provider's documented API with a simulation mode for setup and testing. The part that is solid is the layer underneath — the grant record, the idempotent push, the retry, the revoke on cancellation and the verification from events. That is the part that decides whether a door is trustworthy, and it is the part you cannot buy from a lock vendor.

Frequently asked questions

Should access live in the lock system or in the booking system?

The intent — who may open which door, between when and when — belongs to the booking system, because that is where it is created and changed. The lock system enforces it. Keep the intent only in the provider and a cancelled booking in Boris leaves a working credential in the world, with nothing to reconcile against.

What happens when the access provider is unreachable?

The grant must stay pending and be retried, not fail. A failed push is a door that will not open for a guest who has already paid, so the correct behaviour is to keep the intent, keep retrying on a schedule, and keep the pending state visible to staff. Every push also has to be idempotent, or a retry hands out a second credential.

What should happen when a booking is cancelled or moved?

Cancelled revokes the grant. Moved is a revoke and a re-push, not an edit, because a credential valid for the old window must stop working before the new one starts. In Boris both are driven by the booking event rather than by someone remembering to tidy up.

How do you know a guest actually got in?

Only from a door event. A successful API call proves the provider accepted the instruction, not that a person opened a door. Reading events back and matching them to the grant window is what turns "we sent the code" into "they came in at 23:41".