Learn how to create offline access codes for applicable smart locks with keypads.
Overview
This guide explains how to create offline access (PIN) codes for smart locks that support these types of codes. Use the Access Codes API to generate a time-bound or one-time-use offline access code. Note that Seam support for offline access code functions varies depending on the device manufacturer. For details, see the corresponding device guide.
Note the following restrictions on offline access codes:
You cannot set custom codes for offline access codes.
For devices that support offline access codes, these PIN codes are retrieved from the door lock itself. That is, these PIN codes are not programmed using Wi-Fi. Rather, they are generated by an algorithm.
Once you create an offline access code, you cannot use the Seam API to update or delete it.
Brand-Specific Offline Access Code Restrictions
It is imperative to understand all manufacturer- and device-specific behaviors and constraints. For example, igloohome categorizes time-bound offline access codes as hourly-bound or daily-bound and enforces maximum numbers of each type. Also, you must configure dormakaba Oracode offline access codes to fit into specific predefined time slots called "user levels." Further, some manufacturers support one-time-use offline access codes, while others do not.
For details, see the corresponding device guide. Also, get the lock and view any manufacturer-specific properties.
Before you attempt to create an offline access code, be sure to confirm that your device has the capability to perform this operation. You can check the following capability flag for the device:
device.can_program_offline_access_codes
Use Get Device for a specific device to return this capability flag. Then, use an if statement or similar check to confirm that this flag is both present and true before attempting to create an offline access code.
Device(
device_id='11111111-1111-1111-1111-444444444444',
can_program_offline_access_codes=True, // You can create offline access codes for this device.
...
)
Request:
# Use GET or POST.curl-X'GET' \'https://connect.getseam.com/locks/get' \-H'accept: application/json' \-H'Authorization: Bearer ${API_KEY}' \-H'Content-Type: application/json' \-d'{ "device_id": "11111111-1111-1111-1111-444444444444"}'
Response:
{"lock": {"device_id":"11111111-1111-1111-1111-444444444444","can_program_offline_access_codes":true,// You can create offline access codes for this device. ... },"ok":true}
{ device_id: '11111111-1111-1111-1111-444444444444', can_program_offline_access_codes:true,// You can create offline access codes for this device. ...}
<Seam::Device:0x00438
device_id="11111111-1111-1111-1111-444444444444"
can_program_offline_access_codes=true // You can create offline access codes for this device.
...
>
{"device_id":"11111111-1111-1111-1111-444444444444","can_program_offline_access_codes":true,// You can create offline access codes for this device. ...}
{
"device_id": "11111111-1111-1111-1111-444444444444",
"can_program_offline_access_codes": true, // You can create offline access codes for this device.
...
}
{"device_id":"11111111-1111-1111-1111-444444444444","can_program_offline_access_codes":true,// You can create offline access codes for this device. ...}
{"device_id":"11111111-1111-1111-1111-444444444444","can_program_offline_access_codes":true,// You can create offline access codes for this device. ...}
Creating Time-Bound Offline Access Codes
For Lockly locks, you can create time-bound offline access codes that define a validity period using starts_at and ends_at timestamps. For igloohome locks and dormakaba Oracode locks, you can create time-bound offline access codes with validity durations at either the hour level or the day level.
Make sure to learn any manufacturer-specific behavior and restrictions regarding time-bound offline access codes. For details, see the corresponding device guide.
To create a time-bound offline access code, first issue a creation request. Then, poll or use a webhook to confirm that the code was registered successfully in the device manufacturer's offline access code server.
1. Create a Time-Bound Offline Access Code
To create a time-bound offline access code, provide the device_id of the lock for which you want to create the code and set is_offline_access_code to true. Specify the starts_at and ends_atISO 8601 timestamps to define the active time window for the offline code. You can also assign an optional name to the offline access code. For more details, see the Create Access Code endpoint.
Request:
# Get the device.device = seam.locks.get( device_id="11111111-1111-1111-1111-444444444444")# Confirm that the device supports offline access codes.if device.can_program_offline_access_codes:# Create the time-bound offline access code. seam.access_codes.create( device_id = device.device_id, name ="my time-bound offline code", starts_at ="2023-11-10T00:00:00-00:00", ends_at ="2023-11-15T18:00:00-00:00",# To create a daily-bound code for devices# that support this feature, include# max_time_rounding = "1d", is_offline_access_code =True )
# Get the device.device=$(# Use GET or POST.curl-X'GET' \'https://connect.getseam.com/devices/get' \-H'accept: application/json' \-H"Authorization: Bearer ${API_KEY}" \-H'Content-Type: application/json' \-d'{ "device_id": "11111111-1111-1111-1111-444444444444" }')# Confirm that the device supports offline access codes.if$(jq-r'.device.can_program_offline_access_codes'<<<${device}); then \# Create the time-bound offline access code.# To create a daily-bound code for devices# that support this feature, include# \"max_time_rounding\": \"1d\",curl-X'POST' \'https://connect.getseam.com/access_codes/create' \-H'accept: application/json' \-H"Authorization: Bearer ${API_KEY}" \-H'Content-Type: application/json' \-d"{ \"device_id\": \"$(jq-r '.device.device_id' <<<${device})\", \"name\": \"my time-bound offline code\", \"starts_at\": \"2023-11-10T00:00:00-00:00\", \"ends_at\": \"2023-11-15T18:00:00-00:00\", \"is_offline_access_code\": true }";fi
// Get the device.constdevice=awaitseam.locks.get({ device_id:"11111111-1111-1111-1111-444444444444"});// Confirm that the device supports offline access codes.if (device.can_program_offline_access_codes) {// Create the time-bound offline access code.awaitseam.accessCodes.create({ device_id:device.device_id, name:"my time-bound offline code", starts_at:"2023-11-10T00:00:00-00:00", ends_at:"2023-11-15T18:00:00-00:00",// To create a daily-bound code for devices// that support this feature, include// max_time_rounding: "1d", is_offline_access_code:true })};
# Get the device.device = client.locks.get(device_id: "11111111-1111-1111-1111-444444444444")# Confirm that the device supports offline access codes.if (device.can_program_offline_access_codes)# Create the time-bound offline access code. client.access_codes.create( device_id: device.device_id, name: "my time-bound offline code", starts_at: "2023-11-10T00:00:00-00:00", ends_at: "2023-11-15T18:00:00-00:00",# To create a daily-bound code for devices# that support this feature, include# max_time_rounding: "1d", is_offline_access_code: true )end
Response:
<Seam::AccessCode:0x00438
access_code_id="11111111-1111-1111-1111-777777777777"
device_id="11111111-1111-1111-1111-444444444444"
name="my time-bound offline code"
type="time_bound"
starts_at=2023-11-10 00:00:00 UTC
ends_at=2023-11-15 18:00:00 UTC
is_offline_access_code: true
...
>
Request:
// Get the device.$device = $seam->locks->get(device_id:"11111111-1111-1111-1111-444444444444");// Confirm that the device supports offline access codes.if ($device->can_program_offline_access_codes) {// Create the time-bound offline access code. $seam->access_codes->create( device_id: $device->device_id, name:"my time-bound offline code", starts_at:"2023-11-10T00:00:00Z", ends_at:"2023-11-15T18:00:00Z",// To create a daily-bound code for devices// that support this feature, include// max_time_rounding: "1d", is_offline_access_code:true);}
// Get the device.Device device =seam.Locks.Get(deviceId:"11111111-1111-1111-1111-444444444444");// Confirm that the device supports offline access codes.if (device.CanProgramOfflineAccessCodes==true) { // Create the time-bound offline access code.seam.AccessCodes.Create( deviceId:device.DeviceId, name:"my time-bound offline code", startsAt:"2023-11-10T00:00:00Z", endsAt:"2023-11-15T18:00:00Z", // To create a daily-bound code for devices // that support this feature, include // maxTimeRounding: "1d", isOfflineAccessCode:true );}
// Get the device.Device device =seam.devices().get(DevicesGetRequest.builder().deviceId("11111111-1111-1111-1111-444444444444").build());// Confirm that the device supports offline access codes.if (device.getCanProgramOfflineAccessCodes()){// Create the time-bound offline access code.seam.accessCodes().create(AccessCodesCreateRequest.builder().deviceId(device.getDeviceId()).name("my time-bound offline code").startsAt("2023-11-10T00:00:00Z").endsAt("2023-11-15T18:00:00Z")// To create a daily-bound code for devices// that support this feature, include// .maxTimeRounding("1d").isOfflineAccessCode(true).build());}
Unset: When initially created on Seam, the offline access code remains in an unset state, indicating that it is not yet available for use on the lock due to a configured future activation time.
Setting: As the scheduled starts_at time approaches, Seam initiates the process of readying the code for use on the lock, transitioning the status of the offline code to setting.
Set: Upon successful programming, the status updates to set, signaling that the code is ready to grant the designated user the ability to unlock the door.
There are two methods to verify that an time-bound offline access code has been registered in the offline access code server that the device manufacturer maintains:
Polling: Continuously query the access code until the status is updated. For instructions, see Polling Method.
Webhook: Wait for updates to arrive using webhook requests from the Seam API. For instructions, see Webhook Events Method.
Creating One-Time-Use Offline Access Codes
For igloohome locks and Lockly locks, you can create one-time-use offline access codes. These codes expire after a single use. To confirm whether your device supports one-time-use offline access codes and to learn any manufacturer- and device-specific restrictions, see the corresponding device guide.
To create a one-time-use offline access code, first issue a creation request. In this request, set is_offline_access_code and is_one_time_use to true, and specify the desired starts_at and ends_at timestamps, as applicable for your device. Then, poll or use a webhook to confirm that the code was registered successfully in the offline access code server that the device manufacturer maintains.
1. Create a One-Time-Use Offline Access Code
To create a one-time-use offline access code, provide the device_id of the lock for which you want to create the code. Set is_offline_access_code and is_one_time_use to true. Specify the starts_atISO 8601 timestamp to define the beginning of the active time window for the offline code. If applicable for your device, specify the ends_atISO 8601 timestamp to define the end of the active time window for the offline code.
You can also assign an optional name to the offline access code. For more details, see the Create Access Code endpoint.
Request:
# Get the device.device = seam.locks.get( device_id="11111111-1111-1111-1111-444444444444")# Confirm that the device supports offline access codes.if device.can_program_offline_access_codes:# Create the one-time-use offline access code. seam.access_codes.create( device_id = device.device_id, name ="my one-time-use offline code", starts_at ="2023-11-12T00:00:00-00:00",# Specify ends_at if your device supports it. ends_at ="2023-11-14T00:00:00-00:00", is_offline_access_code =True, is_one_time_use =True )
// Get the device.constdevice=awaitseam.locks.get({ device_id:"11111111-1111-1111-1111-444444444444"});// Confirm that the device supports offline access codes.if (device.can_program_offline_access_codes) {// Create the one-time-use offline access code.awaitseam.accessCodes.create({ device_id:device.device_id, name:"my one-time-use offline code", starts_at:"2023-11-12T00:00:00-00:00",// Specify ends_at if your device supports it. ends_at:"2023-11-14T00:00:00-00:00", is_offline_access_code:true, is_one_time_use:true })};
# Get the device.device = client.locks.get(device_id: "11111111-1111-1111-1111-444444444444")# Confirm that the device supports offline access codes.if (device.can_program_offline_access_codes)# Create the one-time-use offline access code. client.access_codes.create( device_id: device.device_id, name: "my one-time-use offline code", starts_at: "2023-11-12T00:00:00-00:00",# Specify ends_at if your device supports it. ends_at: "2023-11-14T00:00:00-00:00", is_offline_access_code: true, is_one_time_use: true )end
Response:
<Seam::AccessCode:0x00438
access_code_id="11111111-1111-1111-1111-777777888888"
device_id="11111111-1111-1111-1111-444444444444"
name="my one-time-use offline code"
type="time_bound"
starts_at=2023-11-12 00:00:00 UTC
ends_at=2023-11-14 00:00:00 UTC
is_offline_access_code: true
is_one_time_use: true
...
>
Request:
// Get the device.$device = $seam->locks->get(device_id:"11111111-1111-1111-1111-444444444444");// Confirm that the device supports offline access codes.if ($device->can_program_offline_access_codes) {// Create the one-time-use offline access code. $seam->access_codes->create( device_id: $device->device_id, name:"my one-time-use offline code", starts_at:"2023-11-12T00:00:00Z",// Specify ends_at if your device supports it. ends_at:"2023-11-14T00:00:00Z", is_offline_access_code:true, is_one_time_use:true);}
// Get the device.Device device =seam.devices().get(DevicesGetRequest.builder().deviceId("11111111-1111-1111-1111-444444444444").build());// Confirm that the device supports offline access codes.if (device.getCanProgramOfflineAccessCodes()){// Create the one-time-use offline access code.seam.accessCodes().create(AccessCodesCreateRequest.builder().deviceId(device.getDeviceId()).name("my one-time-use offline code").startsAt("2023-11-12T00:00:00Z")// Specify ends_at if your device supports it..endsAt("2023-11-14T00:00:00Z").isOfflineAccessCode(true).isOneTimeUse(true).build());}
Unset: When initially created on Seam, the offline access code remains in an unset state, indicating that it is not yet available for use on the lock due to a configured future activation time.
Setting: As the scheduled starts_at time approaches, Seam initiates the process of readying the code for use on the lock, transitioning the status of the offline code to setting.
Set: Upon successful programming, the status updates to set, signaling that the code is ready to grant the designated user the ability to unlock the door.
There are two methods to verify that a one-time-use offline access code has been registered in the offline access code server that the device manufacturer maintains:
Polling: Continuously query the access code until the status is updated. For instructions, see Polling Method.
Webhook: Wait for updates to arrive using webhook requests from the Seam API. For instructions, see Webhook Events Method.