LogoLogo
Sign UpSupported Devices
  • Seam Documentation
  • 🚲Quick Start
  • 🚀Go Live!
  • Contact Us
  • Core Concepts
    • Overview
    • Seam Console
      • Seam Online CLI
    • Workspaces
    • Authentication
      • API Keys
      • Personal Access Tokens
      • Client Sessions and Client Session Tokens
        • Implementing Client Sessions for Device Management in the Backend
    • Devices
      • Displaying Device Health
      • Displaying Device Power Status
      • Managed and Unmanaged Devices
      • Adding Custom Metadata to a Device
      • Filtering Devices by Custom Metadata
      • Testing Your App Against Device Disconnection and Removal
    • Connected Accounts
      • Adding Custom Metadata to a Connected Account
      • Filtering Connected Accounts by Custom Metadata
      • Reconnecting an Account
    • Action Attempts
  • Capability Guides
    • 📋Device and System Capabilities
    • 🔒Smart Locks
      • Locking and Unlocking Smart Locks
      • Creating and Managing Smart Lock Access Codes
        • Creating Access Codes
        • Retrieving Access Codes
        • Modifying Access Codes
        • Deleting Access Codes
        • Lifecycle of Access Codes
        • Access Code Requirements for Door Locks
        • Streamlining Access Code Management from the Manufacturer App
        • Troubleshooting Access Codes
        • Managing Backup Access Codes
        • Managing Offline Access Codes
        • Creating and Updating Multiple Linked Access Codes
        • Migrating Existing Unmanaged Access Codes
    • 🏢Access Control Systems
      • ACS Quick Starts
        • PIN Code Quick Start
        • Encodable Key Card Quick Start
        • Mobile Key Quick Start
      • Connect an ACS to Seam
        • Retrieving ACS System Details
        • Access Control System Resources
        • Understanding Access Control System Differences
      • Managing ACS Users
        • Suspending and Unsuspending ACS Users
        • Assigning ACS Users to Access Groups
      • Retrieving Entrance Details
      • Managing Credentials
        • Assigning Credentials to ACS Users
        • Listing Credentials and Associated Entrances
      • Working with Card Encoders and Scanners
        • Creating and Encoding Card-based Credentials
        • Scanning Encoded Cards
      • Troubleshooting Your Access Control System
    • 📱Mobile Access
      • Prepare your Workspace
      • Managing Mobile App User Accounts with User Identities
      • Managing Phones for a User Identity
      • Issuing Mobile Credentials from an Access Control System
      • Developing in a Sandbox Workspace
      • Integrating into your Mobile Application
        • Initializing the Seam Mobile SDK
        • Handling System Permissions
        • Using Unlock With Tap
    • 🌡️Thermostats
      • Understanding Thermostat Concepts
        • HVAC Mode
        • Set Points
      • Retrieving Thermostats
      • Setting and Monitoring Temperature Thresholds
      • Setting the Current HVAC and Fan Mode Settings
      • Creating and Managing Climate Presets
        • Setting the Fallback Climate Preset
        • Activating a Climate Preset
      • Creating and Managing Thermostat Schedules
      • Testing Your Thermostat App with Simulate Endpoints
    • 👂Noise Sensors
      • Configuring Noise Threshold Settings
    • 📡Seam Bridge
  • 💻UI Components
    • 🔌Connect Webviews
      • Connect Webview Process
      • Embedding a Connect Webview in Your App
      • Verifying Successful Account Connection
      • Retrieving Devices or Access Control Systems Connected Through a Connect Webview
      • Attaching Custom Metadata to the Connect Webview
      • Filtering Connect Webviews by Custom Metadata
      • Customizing Connect Webviews
    • 🧱Seam Components
      • Getting Started with Seam Components
        • Get Started with React
        • Get started with Angular
        • Get started with Vue
        • Get started with Client Side Components
      • Components
        • Device Details
        • Device Table
        • Access Code Table
        • Access Code Details
        • Create Access Code Form
        • Update Access Code Form
        • Supported Devices Table
        • Seam Provider
        • Connect Account Button
      • Make a Supported Devices Page
      • Using User Identities to Scope Users' Device Access
  • 📋API Reference
    • Overview
    • Installation
    • Authentication
    • Workspaces
      • Get Workspace
      • Reset Workspace
    • Client Sessions
      • Create a Client Session
      • Get or Create a Client Session
      • List Client Sessions
      • Get a Client Session
      • Grant Access to a Client Session
      • Delete a Client Session
    • Connect Webviews
      • Create a Connect Webview
      • List Connect Webviews
      • Get a Connect Webview
      • Delete a Connect Webview
    • Connected Accounts
      • Get a Connected Account
      • List Connected Accounts
      • Update a Connected Account
      • Delete a Connected Account
    • Devices
      • List Devices
      • List Device Providers
      • Device Provider Metadata
      • Get a Device
      • Update a Device
      • Unmanaged Devices
        • Update an Unmanaged Device
        • List Unmanaged Devices
        • Get an Unmanaged Device
    • Access Codes
      • Create an Access Code
      • Create Multiple Linked Access Codes
      • List Access Codes
      • Get an Access Code
      • Update an Access Code
      • Update Multiple Linked Access Codes
      • Report Device Access Code Constraints
      • Delete an Access Code
      • Pull Backup Access Code
      • Unmanaged Access Codes
        • List Unmanaged Access Codes
        • Convert an Unmanaged Access Code
        • Delete an Unmanaged Access Code
    • Locks
      • Get Lock
      • Lock a Lock
      • Unlock a Lock
      • List Locks
    • Access Control Systems
      • Systems
        • List ACS Systems
        • Get an ACS System
        • List Compatible Credential Manager ACS Systems
      • ACS Users
        • Create an ACS User
        • List ACS Users
        • Get an ACS User
        • Update an ACS User
        • Suspend an ACS User
        • Unsuspend an ACS User
        • Delete an ACS User
        • Add an ACS User to an Access Group
        • Remove an ACS User from an Access Group
      • Entrances
        • List Entrances
        • Get an Entrance
        • List Credentials with Access to an Entrance
      • Access Groups
        • List Access Groups
        • Get an Access Group
        • Add an ACS User to an Access Group
        • Remove an ACS User from an Access Group
        • List ACS Users in an Access Group
      • Credentials
        • Create a Credential for an ACS User
        • Assign a Credential to an ACS User
        • List Credentials
        • Get a Credential
        • Update a Credential
        • Unassign a Credential from an ACS User
        • Delete a Credential
        • List Accessible Entrances
      • Encoders
        • Encode a Credential
        • Get an Encoder
        • List Encoders
        • Scan a Credential
        • Encoder Simulations
          • Simulate that the Next Credential Encoding Will Fail
          • Simulate that the Next Credential Encoding Will Succeed
          • Simulate that the Next Credential Scan Will Fail
          • Simulate that the Next Credential Scan Will Succeed
    • Noise Sensors
      • Noise Thresholds
        • Create Noise Thresholds
        • List Noise Thresholds
        • Update Noise Threshold
        • Delete Noise Threshold
    • Phones
      • Get a Phone
      • List Phones
      • Deactivate a Phone
      • Phone Simulations
        • Create a Sandbox Phone
    • Thermostats
      • List Thermostats
      • Set to Heat Mode
      • Set to Cool Mode
      • Set to Heat-Cool (Auto) Mode
      • Set to Off Mode
      • Set the HVAC Mode
      • Set Fan Mode
      • Activate a Climate Preset
      • Create a Climate Preset
      • Update a Climate Preset
      • Delete a Climate Preset
      • Set a Fallback Climate Preset
      • Set a Temperature Threshold
      • Thermostat Schedules
        • Get a Thermostat Schedule
        • List Thermostat Schedules
        • Create a Thermostat Schedule
        • Update a Thermostat Schedule
        • Delete a Thermostat Schedule
      • Thermostat Simulations
        • Temperature Reached
        • HVAC Mode Adjusted
    • User Identities
      • Create a User Identity
      • List User Identities
      • Get a User Identity
      • Update a User Identity
      • Add an ACS User to a User Identity
      • List ACS Users Associated with a User Identity
      • List ACS Systems Associated with a User Identity
      • Remove an ACS User from a User Identity
      • Grant a User Identity Access to a Device
      • List Accessible Devices for a User Identity
      • Revoke Access to a Device from a User Identity
      • Delete a User Identity
      • Enrollment Automations
        • Launch an Enrollment Automation
        • List Enrollment Automations
        • Get an Enrollment Automation
        • Delete an Enrollment Automation
    • Action Attempts
      • Get Action Attempt
    • Events
      • List Events
      • Get an Event
  • 🛠️Developer Tools
    • Webhooks
    • Seam CLI
    • Sandbox Devices and Systems
      • Sandbox 2N Intercoms
      • Sandbox 4SUITES Locks
      • Sandbox Akiles Locks
      • Sandbox ASSA ABLOY Credential Services
      • Sandbox ASSA ABLOY Visionline Access Control System
      • Sandbox August Locks
      • Sandbox Avigilon Alta Access System
      • Sandbox Brivo Access
      • Sandbox ControlByWeb Relays
      • Sandbox Doorking Callboxes
      • Sandbox dormakaba Oracode Locks
      • Sandbox ecobee Thermostats
      • Sandbox Genie Garage Openers
      • Sandbox Google Nest Thermostats
      • Sandbox Honeywell Resideo Thermostats
      • Sandbox igloohome Locks
      • Sandbox Kwikset Locks
      • Sandbox Latch Access Control System
      • Sandbox Linear Callboxes
      • Sandbox Lockly Locks
      • Sandbox Minut Sensors
      • Sandbox NoiseAware Sensors
      • Sandbox Nuki Locks
      • Sandbox PTI Storlogix Cloud
      • Sandbox Salto KS Access Control System
      • Sandbox Salto Locks
      • Sandbox Salto Space Access System
      • Sandbox Schlage Encode Locks
      • Sandbox Seam Bridge
      • Sandbox SmartThings Hub
      • Sandbox Tedee Locks
      • Sandbox TTLock Locks
      • Sandbox Wyze Locks
      • Sandbox Yale Locks
    • Rate Limits and Guardrails
    • Mobile SDKs
      • Android SDK
      • iOS SDK
  • 🎛️Device and System Integration Guides
    • Overview
    • 2N Intercom Systems
      • Get started with 2N Intercoms
    • 33 Lock Devices
      • Get started with 33 Lock devices
    • 4SUITES Locks
      • Get started with 4SUITES locks
    • Akiles Locks
      • Get started with Akiles locks
    • ASSA ABLOY Credential Services
    • ASSA ABLOY Visionline Access Control System
      • Visionline ACS Setup Instructions
        • Developing and Launching Your Visionline Plastic Card Encoding App
          • Developing Your Visionline Plastic Card Encoding App Using a Real Visionline Server
            • Step 1: Install Your Visionline Application
            • Step 2: Unblock Required Ports
            • Step 3: Configure a Visionline User Account
            • Step 4: Install a Visionline Card Encoder
            • Step 5: Set up Door Locks
            • Step 6: Program Door Locks
            • Step 7: Create a Production Workspace
            • Step 8: Connect Your Visionline Development Account to Seam
            • Next Steps
          • Developing Your Visionline Plastic Card Encoding App Using a Sandbox Workspace
            • Step 1: Create a Sandbox Workspace
            • Step 2: Connect the Virtual Visionline ACS to Seam
            • Next Steps
          • Launching Your Visionline Plastic Card Encoding App to a Live Site
            • Step 1: Confirm That Your Visionline Site Meets the Requirements
            • Step 2: Configure a Visionline User Account
            • Step 3: Purchase and Import the Callback Option from ASSA ABLOY
            • Step 4: Create a Production Workspace
            • Step 5: Connect Your Visionline Production Account to Seam
        • Developing and Launching Your Visionline Mobile Key App
          • Developing Your Visionline Mobile Key App
            • Step 1: Complete the ASSA ABLOY Mobile Development Course
            • Step 2: Install Your Visionline Application
            • Step 3: Unblock Required Ports
            • Step 4: Configure a Visionline User Account
            • Step 5: Set up Your Credential Services Account in Visionline
            • Step 6: Configure the Mobile Access UUID in Visionline
            • Step 7: Set up Door Locks with BLE Profiles
            • Step 8: Program Door Locks
            • Step 9: Create a Production Workspace
            • Step 10: Connect Your Visionline Development Account to Seam
            • Next Steps
          • Launching Your Visionline Mobile Key App
            • Step 1: Obtain ASSA ABLOY Certification for Your Mobile Key App
            • Step 2: Confirm That Your Visionline Site Meets the Requirements
            • Step 3: Confirm BLE Module on All Locks
            • Step 4: Set up Door Locks with BLE Profiles
            • Step 5: Program Door Locks
            • Step 6: Configure a Visionline User Account
            • Step 7: Purchase and Import the Callback and Mobile Service Options from ASSA ABLOY
            • Step 8: Create a Production Workspace
            • Step 9: Connect Your Visionline Production Account to Seam
      • Configuring Visionline Mobile Credentials
        • Issuing Various Types of Guest Mobile Credentials
        • Issuing Various Types of Guest Joiner Mobile Credentials
        • Retrieving Guest and Common Entrances
        • Checking if a User Identity Has a Phone That Is Set up for a Credential Manager
        • Updating Guest Mobile Credentials
        • Revoking Mobile Credentials
      • Mobile Credential-Related Properties
      • Common Use Cases
      • Special Requirements for Android Mobile Access SDK Development
      • Special Requirements for iOS Mobile Access SDK Development
      • Creating Visionline Card-based Credentials
    • August Locks
      • Get started with August locks
    • Avigilon Alta Access System
    • Brivo Access
    • Get started with ControlByWeb Devices
    • dormakaba Oracode Locks
      • Get started with dormakaba Oracode Locks
      • Creating dormakaba Oracode Offline Access Codes
    • ecobee Thermostats
      • Get Started with ecobee Thermostats
    • Google Nest Thermostats
      • Get Started with Nest Thermostats
      • Obtain Google Nest Device Access and Commercial Development
    • Honeywell Resideo Thermostats
      • Get Started with Honeywell Resideo Thermostats
    • igloohome Locks
      • Get started with igloohome Locks
      • Creating igloohome Offline Access Codes
    • Kwikset Locks
      • Get started with Kwikset Wi-Fi Locks
    • Latch Access Control System
      • Latch ACS Setup Instructions
      • Programming Code-Based Latch Credentials
      • Programming Latch ACS Mobile Credentials
    • Lockly Locks
      • Creating Lockly Offline Access Codes
    • Minut Sensors
      • Get started with Minut Sensors
    • NoiseAware Sensors
      • Get started with NoiseAware Sensors
    • Nuki Locks
      • Get Started with Nuki Locks
    • PTI Storlogix Cloud
    • Salto KS Access Control System
      • Salto KS Setup Instructions
      • Programming Salto KS PIN Code Credentials
      • Programming Salto KS Mobile Credentials
      • Special Requirements for Android Mobile Access SDK Development
    • Salto KS Locks
      • Get started with Salto KS Locks
    • Salto ProAccess Space Access System
      • Salto Space Setup Instructions
      • Programming Salto Space Card-based Credentials
      • Programming Salto Space Mobile Credentials
    • Schlage Locks
      • Schlage Locks Setup Instructions
      • Get started with Schlage Locks
    • SmartThings Hubs + Smart Locks
      • Get started with SmartThings Hubs + Smart Locks
    • Tedee Locks
      • Get Started with Tedee Locks
    • TTLock Locks
      • Get started with TTLock Locks
    • Wyze Locks
      • Get started with Wyze Locks
    • Yale Locks
      • Get started with Yale Locks
    • Get started with Smart Locks
  • Device Manufacturer Guidance
    • Creating a Seam-Compatible Intercom API
      • Creating OAuth Endpoints
      • Creating Intercom CRUD Endpoints
      • Creating Access Code CRUD Endpoints
      • Creating the Health Endpoint
    • Creating a Seam-Compatible Door Locks API
      • Creating OAuth Endpoints
      • Creating Door Lock CRUD Endpoints
      • Creating Access Code CRUD Endpoints
      • Creating the Health Endpoint
Powered by GitBook
LogoLogo

Get Started

  • Sign Up
  • Supported Devices

News

  • Changelog
  • Blog

Company

  • About
  • Privacy Notice

© Seam Labs, Inc. All rights reserved.

On this page
  • Offline Access Code Requirements
  • Duration
  • Deletion and Access Code Limits
  • User Levels
  • Time Zones
  • Master Codes
  • One-Time-Use Codes
  • Programming dormakaba Oracode Offline Access Codes
  • Hourly-Bound Offline Access Codes
  • Daily-Bound Offline Access Codes

Was this helpful?

Edit on GitHub
  1. Device and System Integration Guides
  2. dormakaba Oracode Locks

Creating dormakaba Oracode Offline Access Codes

Learn how to create dormakaba Oracode offline access codes, including understanding manufacturer-specific requirements.

PreviousGet started with dormakaba Oracode LocksNextecobee Thermostats

Last updated 5 months ago

Was this helpful?

The Seam integration for dormakaba Oracode enables you to manage for dormakaba Oracode locks. You generate offline access (PIN) codes remotely, and the manufacturer maintains a server-based registry of synchronized encryption keys (tokens) to enable these offline codes. Then, owners or managers can share these codes with users through messaging or other similar applications, and the users do not need to install a special application to unlock the device.

To learn about the special requirements regarding offline access codes for dormakaba Oracode locks, see . For more information about using offline access codes, see and .


Offline Access Code Requirements

Seam supports daily-bound and hourly-bound for dormakaba Oracode locks. Note the following dormakaba Oracode-specific restrictions and requirements for offline access codes:

Duration

The duration limit for a dormakaba Oracode offline access code is 31 consecutive days.

Deletion and Access Code Limits

You cannot delete dormakaba Oracode offline access codes. Consequently, it is important to be aware of device- and installation-specific access code limits, especially if you plan to create large numbers of codes simultaneously. For more information about these limits, see the user manual for your dormakaba Oracode lock or contact your dormakaba Oracode support representative.

User Levels

dormakaba Oracode locks use pre-programmed sets of access code time slots called "user levels" or "user prefixes." All the access codes in a specific user level have the same prefix, for example, 123 in 123456789 and 123987654. Further, all access codes in a specific user level use the same configuration for the following characteristics:

  • Check in and check out time

  • Whether the access code is a one-time-use code

  • Whether the access code is daily-bound (is_24_hour)

  • Whether the access code is a biweekly code (that is, a code that is valid for two weeks)

  • Whether the access code is a master code that exists indefinitely, for example, for site owners

"predefined_time_slots": [
  {
      "name": "Guest RCI D 7am-7pm",
      "prefix": 0,
      "is_master": false,
      "is_24_hour": false,
      "is_one_shot": false,
      "check_in_time": "07:00:00[America/Los_Angeles]",
      "check_out_time": "19:00:00[America/Los_Angeles]",
      "is_biweekly_mode": false,
      "dormakaba_oracode_user_level_id": "f23721ec-6dce-4c54-8971-40d58449a366",
      "ext_dormakaba_oracode_user_level_prefix": 0
  },
  ...
]

Time Zones

For example, suppose that your lock includes the following user level:

"check_in_time": "07:00:00[America/Los_Angeles]",
"check_out_time": "19:00:00[America/Los_Angeles]"

To set an access code that uses this user level, set the times for the starts_at and ends_at properties as follows:

"starts_at": "2024-09-10T07:00:00-07:00",
"ends_at": "2024-09-15T19:00:00-07:00"

View the Time Zone of a dormakaba Oracode Lock

Master Codes

Seam does not currently support dormakaba Oracode master offline access codes.

One-Time-Use Codes

Seam does not currently support dormakaba Oracode one-time-use offline access codes.


Programming dormakaba Oracode Offline Access Codes

You can create hourly- and daily-bound offline access codes for dormakaba Oracode devices.

Hourly-Bound Offline Access Codes

1. Create an Hourly-Bound Offline Access Code

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 hourly-bound offline access code.
  seam.access_codes.create(
    device_id = device.device_id,
    name = "my hourly-bound offline code",
    # Make sure that the validity period matches
    # a user level for the device.
    starts_at = "2024-09-10T07:00:00-07:00",
    ends_at = "2024-09-15T19:00:00-07:00",
    is_offline_access_code = True
  )

Response:

AccessCode(
  access_code_id='11111111-1111-1111-1111-777777777777',
  device_id='11111111-1111-1111-1111-444444444444',
  type='time_bound',
  starts_at='2024-09-10T14:00:00.000Z',
  ends_at='2024-09-16T02:00:00.000Z',
  name='my hourly-bound offline code',
  is_offline_access_code=True,
  ...
)

Request:

# 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 hourly-bound offline access code.
  # Make sure that the validity period matches
  # a user level for the device.
  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 hourly-bound offline code\",
      \"starts_at\": \"2024-09-10T07:00:00-07:00\",
      \"ends_at\": \"2024-09-15T19:00:00-07:00\",
      \"is_offline_access_code\": true
  }";
fi

Response:

{
  "action_attempt": {
    "status": "pending",
    "action_type": "CREATE_ACCESS_CODE",
    "action_attempt_id": "11111111-2222-3333-4444-555555555555",
    "result": null,
    "error": null
  },
  "access_code": {
    "access_code_id": "11111111-1111-1111-1111-777777777777",
    "device_id": "11111111-1111-1111-1111-444444444444",
    "name": "my hourly-bound offline code",
    "type": "time_bound",
    "starts_at": "2024-09-10T14:00:00.000Z",
    "ends_at": "2024-09-16T02:00:00.000Z",
    "is_offline_access_code": true,
    ...
  },
  "ok": true
}

Request:

// Get the device.
const device = await 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 hourly-bound offline access code.
  await seam.accessCodes.create({
    device_id: device.device_id,
    name: "my hourly-bound offline code",
    // Make sure that the validity period matches
    // a user level for the device.
    starts_at: "2024-09-10T07:00:00-07:00",
    ends_at: "2024-09-15T19:00:00-07:00",
    is_offline_access_code: true
  })
};

Response:

{
  access_code_id: '11111111-1111-1111-1111-777777777777',
  device_id: '11111111-1111-1111-1111-444444444444',
  name: 'my hourly-bound offline code',
  type: 'time_bound',
  starts_at: '2024-09-10T14:00:00.000Z',
  ends_at: '2024-09-16T02:00:00.000Z',
  is_offline_access_code: true,
  ...
}

Request:

# 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 hourly-bound offline access code.
  client.access_codes.create(
    device_id: device.device_id,
    name: "my hourly-bound offline code",
    # Make sure that the validity period matches
    # a user level for the device.
    starts_at: "2024-09-10T07:00:00-07:00",
    ends_at: "2024-09-15T19:00:00-07:00",
    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 hourly-bound offline code"
  type="time_bound"
  starts_at=2024-09-10 14:00:00 UTC
  ends_at=2024-09-16 02: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 hourly-bound offline access code.
  $seam->access_codes->create(
    device_id: $device->device_id,
    name: "my hourly-bound offline code",
    // Make sure that the validity period matches
    // a user level for the device.
    starts_at: "2024-09-10T07:00:00-07:00",
    ends_at: "2024-09-15T19:00:00-07:00",
    is_offline_access_code: true
  );
}

Response:

{
  "access_code_id": "11111111-1111-1111-1111-777777777777",
  "device_id": "11111111-1111-1111-1111-444444444444",
  "name": "my hourly-bound offline code",
  "type": "time_bound",
  "starts_at": "2024-09-10T14:00:00.000Z",
  "ends_at": "2024-09-16T02:00:00.000Z",
  "is_offline_access_code": true,
  ...
}

Request:

// 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 hourly-bound offline access code.
  seam.AccessCodes.Create(
    deviceId: device.DeviceId,
    name: "my hourly-bound offline code",
    // Make sure that the validity period matches
    // a user level for the device.
    startsAt: "2024-09-10T07:00:00-07:00",
    endsAt: "2024-09-15T19:00:00-07:00",
    isOfflineAccessCode: true
  );
}

Response:

{
  "type": "time_bound",
  "access_code_id": "11111111-1111-1111-1111-777777777777",
  "device_id": "11111111-1111-1111-1111-444444444444",
  "name": "my hourly-bound offline code",
  "starts_at": "2024-09-10T14:00:00.000Z",
  "ends_at": "2024-09-16T02:00:00.000Z",
  "is_offline_access_code": true,
  ...
}

Request:

// 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 hourly-bound offline access code.
  seam.accessCodes()
    .create(AccessCodesCreateRequest.builder()
      .deviceId(device.getDeviceId())
      .name("my hourly-bound offline code")
      // Make sure that the validity period matches
      // a user level for the device.
      .startsAt("2024-09-10T07:00:00-07:00")
      .endsAt("2024-09-15T19:00:00-07:00")
      .isOfflineAccessCode(true)
      .build());
}

Response:

{
  "access_code_id" : "11111111-1111-1111-1111-777777777777",
  "device_id" : "11111111-1111-1111-1111-444444444444",
  "name" : "my hourly-bound offline code",
  "type" : "time_bound",
  "starts_at" : "2024-09-10T14:00:00.000Z",
  "ends_at" : "2024-09-16T02:00:00.000Z",
  "is_offline_access_code": true,
  ...
}

Request:

// Get the device.
device, uErr := client.Locks.Get(
  context.Background(),
  &api.LocksGetRequest{
    DeviceId: api.String("11111111-1111-1111-1111-444444444444"),
  })

// Confirm that the device supports offline access codes.
if *device.CanProgramOfflineAccessCodes {
  // Create the hourly-bound offline access code.
  client.AccessCodes.Create(
      context.Background(),
      &api.AccessCodesCreateRequest{
        DeviceId: device.DeviceId,
        Name: api.String("my hourly-bound offline code"),
        // Make sure that the validity period matches
        // a user level for the device.
        StartsAt: api.String("2024-09-10T07:00:00-07:00"),
        EndsAt: api.String("2024-09-15T19:00:00-07:00"),
        IsOfflineAccessCode: api.Bool(true),
      },
    )
  }

if uErr != nil {
    return uErr
}

return nil

Response:

{
  "access_code_id": "11111111-1111-1111-1111-777777777777",
  "device_id": "11111111-1111-1111-1111-444444444444",
  "name": "my hourly-bound offline code",
  "type": "time_bound",
  "starts_at": "2024-09-10T14:00:00.000Z",
  "ends_at": "2024-09-16T02:00:00.000Z",
  "is_offline_access_code": true,
  ...
}

2. Verify Successful Time-Bound Code Registration

  1. 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.

  2. 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.

  3. 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:


Daily-Bound Offline Access Codes

1. Create a Daily-Bound Access Code

Because daily-bound offline access codes require day-level duration granularity, you can also set max_time_rounding to 1day (or 1d), instead of the default 1hour (or 1h). Note that the Seam API returns an error if max_time_rounding is 1hour and the necessary rounding amount exceeds one hour.

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 daily-bound offline access code.
  seam.access_codes.create(
    device_id = device.device_id,
    name = "my daily-bound offline code",
    # Make sure that the validity period matches
    # a user level for the device.
    starts_at = "2024-09-16T00:00:00-07:00",
    ends_at = "2024-09-18T23:59:00-07:00",
    max_time_rounding = "1d",
    is_offline_access_code = True
  )

Response:

AccessCode(
  access_code_id='11111111-1111-1111-1111-888888888888',
  device_id='11111111-1111-1111-1111-444444444444',
  type='time_bound',
  starts_at='2024-09-16T07:00:00.000Z',
  ends_at='2024-09-19T06:59:00.000Z',
  name='my daily-bound offline code',
  is_offline_access_code=True,
  ...
)

Request:

# 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 daily-bound offline access code.
  # Make sure that the validity period matches
  # a user level for the device.
  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 daily-bound offline code\",
      \"starts_at\": \"2024-09-16T00:00:00-07:00\",
      \"ends_at\": \"2024-09-18T23:59:00-07:00\",
      \"max_time_rounding\": \"1d\",
      \"is_offline_access_code\": true
  }";
fi

Response:

{
  "action_attempt": {
    "status": "pending",
    "action_type": "CREATE_ACCESS_CODE",
    "action_attempt_id": "11111111-2222-3333-4444-555555555555",
    "result": null,
    "error": null
  },
  "access_code": {
    "access_code_id": "11111111-1111-1111-1111-888888888888",
    "device_id": "11111111-1111-1111-1111-444444444444",
    "name": "my daily-bound offline code",
    "type": "time_bound",
    "starts_at": "2024-09-16T07:00:00.000Z",
    "ends_at": "2024-09-19T06:59:00.000Z",
    "is_offline_access_code": true,
    ...
  },
  "ok": true
}

Request:

// Get the device.
const device = await 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 daily-bound offline access code.
  await seam.accessCodes.create({
    device_id: device.device_id,
    name: "my daily-bound offline code",
    // Make sure that the validity period matches
    // a user level for the device.
    starts_at: "2024-09-16T00:00:00-07:00",
    ends_at: "2024-09-18T23:59:00-07:00",
    max_time_rounding: "1d",
    is_offline_access_code: true
  })
};

Response:

{
  access_code_id: '11111111-1111-1111-1111-888888888888',
  device_id: '11111111-1111-1111-1111-444444444444',
  name: 'my daily-bound offline code',
  type: 'time_bound',
  starts_at: '2024-09-16T07:00:00.000Z',
  ends_at: '2024-09-19T06:59:00.000Z',
  is_offline_access_code: true,
  ...
}

Request:

# 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 daily-bound offline access code.
  client.access_codes.create(
    device_id: device.device_id,
    name: "my daily-bound offline code",
    # Make sure that the validity period matches
    # a user level for the device.
    starts_at: "2024-09-16T00:00:00-07:00",
    ends_at: "2024-09-18T23:59:00-07:00",
    max_time_rounding: "1d",
    is_offline_access_code: true
  )
end

Response:

<Seam::AccessCode:0x00438
  access_code_id="11111111-1111-1111-1111-888888888888"
  device_id="11111111-1111-1111-1111-444444444444"
  name="my daily-bound offline code"
  type="time_bound"
  starts_at=2024-09-16 07:00:00.00 UTC
  ends_at=2024-09-19 06:59: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 daily-bound offline access code.
  $seam->access_codes->create(
    device_id: $device->device_id,
    name: "my daily-bound offline code",
    // Make sure that the validity period matches
    // a user level for the device.
    starts_at: "2024-09-16T00:00:00-07:00",
    ends_at: "2024-09-18T23:59:00-07:00",
    max_time_rounding: "1d",
    is_offline_access_code: true
  );
}

Response:

{
  "access_code_id": "11111111-1111-1111-1111-888888888888",
  "device_id": "11111111-1111-1111-1111-444444444444",
  "name": "my daily-bound offline code",
  "type": "time_bound",
  "starts_at": "2024-09-16T07:00:00.000Z",
  "ends_at": "2024-09-19T06:59:00.000Z",
  "is_offline_access_code": true,
  ...
}

Request:

// 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 daily-bound offline access code.
  seam.AccessCodes.Create(
    deviceId: device.DeviceId,
    name: "my daily-bound offline code",
    // Make sure that the validity period matches
    // a user level for the device.
    startsAt: "2024-09-16T00:00:00-07:00",
    endsAt: "2024-09-18T23:59:00-07:00",
    maxTimeRounding: "1d",
    isOfflineAccessCode: true
  );
}

Response:

{
  "type": "time_bound",
  "access_code_id": "11111111-1111-1111-1111-888888888888",
  "device_id": "11111111-1111-1111-1111-444444444444",
  "name": "my daily-bound offline code",
  "starts_at": "2024-09-16T07:00:00.000Z",
  "ends_at": "2024-09-19T06:59:00.000Z",
  "is_offline_access_code": true,
  ...
}

Request:

// 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 daily-bound offline access code.
  seam.accessCodes()
    .create(AccessCodesCreateRequest.builder()
      .deviceId(device.getDeviceId())
      .name("my daily-bound offline code")
      // Make sure that the validity period matches
      // a user level for the device.
      .startsAt("2024-09-16T00:00:00-07:00")
      .endsAt("2024-09-18T23:59:00-07:00")
      .maxTimeRounding("1d")
      .isOfflineAccessCode(true)
      .build());
}

Response:

{
  "access_code_id" : "11111111-1111-1111-1111-888888888888",
  "device_id" : "11111111-1111-1111-1111-444444444444",
  "name" : "my daily-bound offline code",
  "type" : "time_bound",
  "starts_at" : "2024-09-16T07:00:00.000Z",
  "ends_at" : "2024-09-19T06:59:00.000Z",
  "is_offline_access_code": true,
  ...
}

Request:

// Get the device.
device, uErr := client.Locks.Get(
  context.Background(),
  &api.LocksGetRequest{
    DeviceId: api.String("11111111-1111-1111-1111-444444444444"),
  })

// Confirm that the device supports offline access codes.
if *device.CanProgramOfflineAccessCodes {
  // Create the daily-bound offline access code.
  client.AccessCodes.Create(
      context.Background(),
      &api.AccessCodesCreateRequest{
        DeviceId: device.DeviceId,
        Name: api.String("my daily-bound offline code"),
        // Make sure that the validity period matches
        // a user level for the device.
        StartsAt: api.String("2024-09-16T00:00:00-07:00"),
        EndsAt: api.String("2024-09-18T23:59:00-07:00"),
        MaxTimeRounding: api.String("1d"),
        IsOfflineAccessCode: api.Bool(true),
      },
    )
  }

if uErr != nil {
    return uErr
}

return nil

Response:

{
  "access_code_id": "11111111-1111-1111-1111-888888888888",
  "device_id": "11111111-1111-1111-1111-444444444444",
  "name": "my daily-bound offline code",
  "type": "time_bound",
  "starts_at": "2024-09-16T07:00:00.000Z",
  "ends_at": "2024-09-19T06:59:00.000Z",
  "is_offline_access_code": true,
  ...
}

2. Verify Successful Time-Bound Code Registration

  1. 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.

  2. 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.

  3. 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:

When you create a dormakaba Oracode offline access code, you must set the duration of the code to match—exactly—one of the time slots on the device. To view a list of all available time slots for a specific device, and view the device.properties.dormakaba_oracode_metadata.predefined_time_slots property for the device.

All time zone configuration and display for dormakaba Oracode locks occur in the local time zone of the lock, itself. When you initially, you specify the time zone in which the site is located. Consequently, when you configure an access code for a dormakaba Oracode lock, you set the starts_at and ends_at properties using a time and offset that match the local time zone of the lock.

To view the local time zone of a dormakaba Oracode lock, and see the check_in_time and check_out_time within each time slot in the device.properties.dormakaba_oracode_metadata.predefined_time_slots property for the device. You can also see the local time zone for a dormakaba Oracode lock in the dormakaba_oracode_device_metadata.iana_timezone property.

To , issue an access code creation request. Then, poll or use a webhook to confirm that the code was registered successfully in the dormakaba Oracode offline access code server.

To create an hourly-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_at timestamps to define the active time window for the offline code. Make sure to set the duration of the code to match—exactly—one of the on the device. You can also assign an optional name to the offline access code.

Make sure to set the starts_at and ends_at times and offsets to match the local time zone of the lock, as configured when the corresponding .

For more details, see the .

The is marked by distinct phases:

Polling: Continuously query the access code until the status is updated. For instructions, see .

Webhook: Wait for updates to arrive using webhook requests from the Seam API. For instructions, see .

To , first issue a creation request. Then, poll or use a webhook to confirm that the code was registered successfully in the dormakaba Oracode offline access code server.

To create a daily-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_at timestamps to define the active time window for the offline code. Make sure to set the duration of the code to match—exactly—one of the on the device. For a daily-bound offline access code, you must specify the same time (but not the same date) in the starts_at and ends_at properties.

Make sure to set the starts_at and ends_at times and offsets to match the local time zone of the lock, as configured when the corresponding .

You can also assign an optional name to the offline access code. For more details, see the .

The is marked by distinct phases:

Polling: Continuously query the access code until the status is updated. For instructions, see .

Webhook: Wait for updates to arrive using webhook requests from the Seam API. For instructions, see .

🎛️
get the lock
get the lock
Create Access Code endpoint
lifecycle of a time-bound access code
Create Access Code endpoint
lifecycle of a time-bound access code
ISO 8601
user levels
ISO 8601
user levels
offline access codes
Managing Offline Access Codes
offline access codes
Offline Access Code Requirements
connect your dormakaba Oracode site to Seam
dormakaba Oracode site was connected to Seam
dormakaba Oracode site was connected to Seam
Offline Access Codes
create an hourly-bound offline access code
create a daily-bound offline access code
Polling Method
Webhook Events Method
Polling Method
Webhook Events Method