ENGAGE Gateway 410IP Mode - Getting Started

Table of Contents

Getting Started Guide: Schlage ENGAGE Gateway 410IP Mode Integration

Introduction

This guide provides step-by-step instructions for integrating with Schlage ENGAGE devices using Gateway IP Mode (410-IP). In this mode, ENGAGE locks communicate with a Gateway device over Bluetooth Low Energy (BLE), and the Gateway communicates with your access control system via IP/Ethernet connectivity.

What You’ll Learn

  • How to set up and configure ENGAGE Gateway devices
  • Creating and managing user credentials
  • Understanding JSON data structures for device communication
  • Encoding, sorting, and encrypting credentials properly
  • Testing your integration with Postman
  • Troubleshooting common issues

Prerequisites

  • ENGAGE Gateway device (GWE or GWE2)
  • ENGAGE locks (410-IP compatible: NDE, NDEB, LE, LEB, Control, ControlB, etc.)
  • Network access (Ethernet connection for Gateway)
  • API credentials for your ENGAGE account
  • Postman or similar API testing tool

Table of Contents

Getting Started

  1. Understanding the System Architecture
  2. Understanding and Creating Sites
  3. Initial Gateway Setup
  4. Linking ENGAGE Locks to the Gateway

Credentials and Access Control

  1. Understanding Credentials
  2. Creating and Encoding Credentials
  3. Creating User Databases
  4. Credential Schedules
  5. Holidays and Auto-Unlock
  6. Sending Database to Locks

Configuration and Testing

  1. Lock Configuration
  2. Testing with Postman
  3. Monitoring and Auditing
  4. Door Control
  5. Firmware Updates

Operations and Maintenance

  1. Troubleshooting
  2. Best Practices
  3. Common Integration Patterns
  4. Advanced Topics
  5. Websockets - Gateway as Client

Reference

  1. Reference Documentation
  2. Next Steps
  3. Getting Help

Appendices


1. Understanding the System Architecture

Communication Flow

[Access Control System] <---> [ENGAGE Gateway] <---> [ENGAGE Locks]
     (IP/Ethernet)              (BLE)

410-IP Mode means:

  • 410: The lock’s firmware operation mode
  • IP: The Gateway communicates with your system via IP protocol

Key Components

  1. ENGAGE Gateway (GWE/GWE2): Central hub that bridges IP network to BLE devices
  2. ENGAGE Locks: Door locks with BLE capability (NDE, LE, Control, etc.)
  3. Access Control Host: Your system that manages users, credentials, and policies
  4. JSON API: Communication protocol between Gateway and your system

For detailed architecture information, see ENGAGE_SAM_API_Integration_2.37.pdf.


2. Understanding and Creating Sites

What is a Site?

In the ENGAGE ecosystem, a site is the fundamental container for ENGAGE devices and the essential starting point for any deployment. Each site is an abstract container that includes:

  • Devices and links: All Gateways, locks, and their relationships
  • Unique encryption key: A 32-byte (256-bit) symmetric AES site key
  • Default settings: Configuration templates and metadata

Key characteristics of a site:

  • Unique Identifier: Each site receives a unique reference ID (GUID) when created
  • Site Key: A 32-byte encryption key used to encrypt all credentials for devices in that site
  • Security Isolation: Credentials encrypted with one site’s key cannot be used on devices belonging to another site
  • Required for Communication: Sites are the starting point for any use of ENGAGE devices

Site Types: Managed vs. Unmanaged

ENGAGE supports two types of sites with fundamentally different management models:

Managed Sites (IsEngageManaged = “True”)

  • Used by: Simple ENGAGE ACS, testing, tinkering, debugging
  • NOT used by: Production PACS integrations
  • Key visibility: The encryption key is hidden from all users
  • Creation methods: Mobile app, web portal, or API
  • Use case: Personal use, small installations, prototyping

Unmanaged Sites (IsEngageManaged = “False”)

  • Used by: All production PACS integrations ← This is what you need
  • Key visibility: The encryption key is visible and must be stored securely
  • Creation method: REST API ONLY (cannot be created via mobile app or website)
  • Use case: Professional access control system integrations

IMPORTANT FOR INTEGRATORS: If you’re building a PACS integration, you MUST create unmanaged sites.

Why Sites Matter

The site is the fundamental security unit in ENGAGE:

  1. Credential Encryption: All user credentials (PrimeCr values) are encrypted using the site key
  2. Device Commissioning: Locks and Gateways must be commissioned to a specific site to receive its site key
  3. Security Boundary: A compromised site key only affects devices within that site, not the entire system

CRITICAL: Once a site is created, its site key cannot be changed. It is very important not to lose the key — without it, you cannot create new credentials for devices in that site.

Creating an Unmanaged Site (For PACS Integrations)

Unmanaged sites must be created using the ENGAGE cloud API. They cannot be created via the mobile app or web portal.

Prerequisites:

  • ENGAGE account credentials (email and password)
  • Generated site key (see next section)
  • Your company/software name for metadata

API Endpoint: POST https://partner.lockwebserv.com/engage/sites/register

Authentication: HTTP Basic Auth with your ENGAGE account credentials

Request Body:

{
  "SiteName": "Main Office Building",
  "Base64Key": "ABEiM0RVZneImaq7zN3u/wARIjNEVWZ3iJmqu8zd7v8=",
  "IsEngageManaged": "False",
  "SiteSoftwareKey": "YourCompanyName"
}

Field Descriptions:

FieldDescriptionRequiredExample
SiteNameHuman-readable name for the siteYes”Main Office Building”
Base64KeyThe site encryption key encoded as Base64 (32 bytes = 44 chars)Yes”ABEiM0RVZneImaq7zN3u/w…”
IsEngageManagedMust be “False” for PACS integrationsYes”False”
SiteSoftwareKeyYour company/software identifier - must be preregistered with AllegionYes”YourCompanyName”

IMPORTANT - SiteSoftwareKey Registration:

The SiteSoftwareKey value must be preregistered with Allegion before you can create sites. This identifier is used for SAM (Software Asset Management) metadata and tracking.

To verify your company is registered:

Query the registered software keys endpoint:

GET https://partner.lockwebserv.com/engage/lookup/sitesoftware
Authorization: Basic <base64(your-email@company.com:your-password)>

Response:

{
  "siteSoftwareKeys": [
    "CompanyA",
    "CompanyB_PACS",
    "AcmeAccessControl",
    "YourCompanyName"
  ]
}

If your company is not in the list:

  • Contact your Allegion OEM Integration Engineer
  • Provide your company name and intended software identifier
  • Allegion will register your SiteSoftwareKey value
  • Once registered, you can use it for site creation

Best practices:

  • Use a consistent identifier across all your sites (e.g., “AcmeCorp_PACS”)
  • Include your company name for easy identification
  • Avoid special characters; use only letters, numbers, and underscores
  • Document which identifier is registered for your organization

Response:

{
  "SiteReference": "886182ed-0395-4236-8dcf-50cc89e813d2",
  "SiteName": "Main Office Building"
}

The SiteReference GUID is your site’s unique identifier. Save this value—you’ll need it for subsequent API calls.

Generating a Site Key

The site key must be a random 32-byte (256-bit) value. Generate it using a cryptographically secure random number generator.

Example using OpenSSL:

# Generate 32 random bytes in hex format (64 hex characters)
openssl rand -hex 32
# Output: 123456789abcdef123456789abcdef123456789abcdef123456789abcdef12

# Convert to Base64 for API registration
echo -n "123456789abcdef123456789abcdef123456789abcdef123456789abcdef12" | xxd -r -p | base64
# Output: EjRWeJq83u8SRFZneJmqu8zd7v8SRFZneJmqu8zd7v8=

Example using Python:

import os
import base64

# Generate 32 random bytes
site_key_bytes = os.urandom(32)

# Convert to hex (for your records)
site_key_hex = site_key_bytes.hex()
print(f"Site Key (Hex): {site_key_hex}")

# Convert to Base64 (for API registration)
site_key_base64 = base64.b64encode(site_key_bytes).decode('ascii')
print(f"Site Key (Base64): {site_key_base64}")

Storing the Site Key

CRITICAL SECURITY REQUIREMENTS:

  1. Store both formats: Keep both the hex and Base64 versions of your site key
  2. Secure storage: Use a key management system or secure vault (e.g., HashiCorp Vault, AWS Secrets Manager)
  3. Never in version control: Never commit site keys to git or any version control system
  4. Backup: Maintain secure offline backups—losing the site key means you cannot create new credentials
  5. Access control: Limit access to site keys to only essential personnel

Example secure storage locations:

  • Hardware Security Module (HSM)
  • Cloud key management service (AWS KMS, Azure Key Vault)
  • Enterprise password manager
  • Encrypted configuration management system

Complete Example: Creating Your First Site

# Step 1: Generate site key
SITE_KEY_HEX=$(openssl rand -hex 32)
SITE_KEY_BASE64=$(echo -n "$SITE_KEY_HEX" | xxd -r -p | base64)

echo "Generated Site Key (HEX): $SITE_KEY_HEX"
echo "Generated Site Key (Base64): $SITE_KEY_BASE64"
echo "SAVE THESE VALUES SECURELY!"

# Step 2: Create site via API
curl -X POST https://partner.lockwebserv.com/engage/sites/register \
  -u "your-email@company.com:your-password" \
  -H "Content-Type: application/json" \
  -d "{
    \"SiteName\": \"Main Office Building\",
    \"Base64Key\": \"$SITE_KEY_BASE64\",
    \"IsEngageManaged\": \"False\",
    \"SiteSoftwareKey\": \"YourCompanyName\"
  }"

# Step 3: Save the returned SiteReference GUID

Response example:

{
  "SiteReference": "886182ed-0395-4236-8dcf-50cc89e813d2",
  "SiteName": "Main Office Building"
}

Using the Site Key for Credential Encryption

Once your site is created, use the hex format of the site key for encrypting credentials:

from Crypto.Cipher import AES

# Your site key in hex format (64 hex characters = 32 bytes)
site_key_hex = "123456789abcdef123456789abcdef123456789abcdef123456789abcdef12"
site_key = bytes.fromhex(site_key_hex)

# Credential to encrypt (16 bytes)
credential = bytes.fromhex("8F166040FFFFFFFFFFFFFFFFFFFFFFFF")

# Encrypt with AES-256 CBC, IV = all zeros
iv = bytes(16)  # 16 zero bytes
cipher = AES.new(site_key, AES.MODE_CBC, iv)
encrypted_credential = cipher.encrypt(credential)

print(f"Encrypted: {encrypted_credential.hex().upper()}")

Account Management for PACS Integrators

When managing sites for multiple customers, you have two options:

Option 1: Central Account

  • Use one “main” ENGAGE account to create all sites for all customers
  • Simpler to manage, centralized control
  • May need additional lower-permission accounts for end users to enroll devices

Option 2: One Account Per Premises

  • Create separate ENGAGE accounts for each customer location
  • Better isolation between customers
  • More accounts to manage

Both approaches require: Multiple account types with different permission levels, as some end users need lower-permission accounts specifically for device enrollment.

Device Enrollment Requirements

CRITICAL GOTCHA: Before enrolling devices into a site:

  1. Factory reset required: All devices (Gateways and locks) must be factory reset (FDR’ed) before enrollment
  2. Remove from previous site: Any software records in the ENGAGE cloud referring to that device must be deleted from any previous site
  3. Clean slate only: Devices can only be enrolled in one site at a time

This is easy to forget and very difficult to debug. Always verify devices are factory reset and removed from previous sites before attempting enrollment.

Creating ENGAGE Accounts

If you need to create an ENGAGE account:

Next Steps After Site Creation

After creating your site:

  1. Save the SiteReference: Store the GUID returned from the API securely
  2. Commission devices: Factory reset and enroll Gateways and locks to the site (using mobile app or the Device Communiation SDK and your own app)
  3. Configure Gateways: Set up network and host connection parameters (see next section)
  4. Link locks: Associate locks with Gateways for communication
  5. Create credentials: Encrypt user credentials with the site key and distribute to locks

See also: Creating Engage Accounts and using Mobile App

Postman Collections for API Testing

To help you test and explore the ENGAGE APIs, download these Postman collections:

  1. Allegion APIs.postman_collection_11-6-2019.json

    • Complete collection of ENGAGE Cloud API endpoints (site creation, device management, etc.)
    • Gateway API endpoints (lock control, configuration, audits, etc.)
    • Pre-configured request templates with example payloads
    • Import into Postman to get started quickly
  2. allegionApiEnvironment.postman_environment-10_18_2022.json

    • Postman environment file with variable templates
    • Configure your site keys, Gateway IPs, and credentials
    • Easily switch between test and production environments

How to Use:

  1. Download both files
  2. Open Postman
  3. Import the collection: File → Import → Select Allegion APIs.postman_collection_11-6-2019.json
  4. Import the environment: File → Import → Select allegionApiEnvironment.postman_environment-10_18_2022.json
  5. Select the imported environment from the environment dropdown
  6. Update environment variables with your values (Gateway IP, credentials, site keys, etc.)
  7. Start testing API endpoints

3. Initial Gateway Setup

Step 1: Physical Installation

  1. Mount the Gateway in a central location with good BLE coverage to all locks
  2. Connect Gateway to your network via Ethernet cable
  3. Power on the Gateway (Either POE or 12/24V)

Step 2: Establish Gateway Credentials

When a Gateway is new or factory reset, it auto-generates a unique username and random password. You must retrieve these credentials and commit them to the Gateway for ongoing use. This two-step process establishes secure access to the Gateway API.

Default Authentication Credentials

Both the GET and PUT credential requests use these default credentials for authentication:

  • Username: EngageGatewayDefaultUser
  • Password: EngageGatewayDefaultPassword

Purpose: These are temporary credentials used only to retrieve and commit the auto-generated Gateway credentials. After the two-step process is complete, you’ll use the auto-generated credentials for all subsequent API access.

Step 2a: Retrieve Auto-Generated Credentials

API Endpoint: GET {{gatewayIP}}/gateway/newCredentials

When the Gateway is first powered on or factory reset, it automatically generates a unique username and random password. Retrieve these using the default credentials.

Request:

GET http://192.168.1.100/gateway/newCredentials
Authorization: Basic <base64(EngageGatewayDefaultUser:EngageGatewayDefaultPassword)>

Example with curl:

curl -u "EngageGatewayDefaultUser:EngageGatewayDefaultPassword" \
  http://192.168.1.100/gateway/newCredentials

Example with Postman:

  1. Method: GET
  2. URL: http://192.168.1.100/gateway/newCredentials
  3. Authorization tab:
    • Type: “Basic Auth”
    • Username: EngageGatewayDefaultUser
    • Password: EngageGatewayDefaultPassword

Response:

{
  "credentials": {
    "username": "gateway_b100000000011d96",
    "password": "9EAgj5m859KMwP+W962hPFZHU2QJqAR1"
  }
}

Credential Format:

  • Username: gateway_ + Gateway serial number or MAC address
    • Example: gateway_b100000000011d96
    • Unique to this specific Gateway hardware
  • Password: Randomly generated 32-character string
    • Mix of uppercase, lowercase, numbers, and special characters
    • Example: 9EAgj5m859KMwP+W962hPFZHU2QJqAR1
    • Cryptographically random

CRITICAL: Save these credentials immediately! You’ll need them for Step 2b and all future Gateway access.

Step 2b: Commit the Auto-Generated Credentials

API Endpoint: PUT {{gatewayIP}}/gateway/newCredentials

After retrieving the auto-generated credentials, you must commit them by sending a PUT request. This activates the credentials and disables the default authentication.

Request:

PUT http://192.168.1.100/gateway/newCredentials
Authorization: Basic <base64(EngageGatewayDefaultUser:EngageGatewayDefaultPassword)>
Content-Type: application/json

{}

Important: The request body is empty ({}). You are not setting custom credentials—you’re committing the auto-generated credentials from Step 2a.

Example with curl:

curl -X PUT http://192.168.1.100/gateway/newCredentials \
  -u "EngageGatewayDefaultUser:EngageGatewayDefaultPassword" \
  -H "Content-Type: application/json" \
  -d '{}'

Example with Postman:

  1. Method: PUT
  2. URL: http://192.168.1.100/gateway/newCredentials
  3. Authorization tab:
    • Type: “Basic Auth”
    • Username: EngageGatewayDefaultUser
    • Password: EngageGatewayDefaultPassword
  4. Body tab:
    • Type: “raw”
    • Format: “JSON”
    • Content: {}

Response:

{
  "status": "success",
  "message": "Credentials committed successfully"
}

What Happens After PUT:

  1. The auto-generated credentials from Step 2a become the permanent Gateway credentials
  2. The default credentials (EngageGatewayDefaultUser / EngageGatewayDefaultPassword) are disabled
  3. All future API requests must use the auto-generated credentials from Step 2a
  4. The GET endpoint will no longer return credentials (they’re now committed)

Complete Credential Setup Workflow

1. Power on new/factory-reset Gateway

2. Connect Gateway to network (Ethernet)

3. Discover Gateway IP address (DHCP server, network scan, etc.)

4. GET /gateway/newCredentials
   - Authenticate with: EngageGatewayDefaultUser / EngageGatewayDefaultPassword
   - Receive: auto-generated username/password
   - Example response: gateway_b100000000011d96 / 9EAgj5m859KMwP+W962hPFZHU2QJqAR1

5. SAVE the auto-generated credentials in secure storage immediately!

6. PUT /gateway/newCredentials (blank body)
   - Authenticate with: EngageGatewayDefaultUser / EngageGatewayDefaultPassword
   - Body: {} (empty JSON object)
   - This commits the auto-generated credentials

7. Test access with the auto-generated credentials from step 4

8. Update all API clients, Postman collections, etc. with new credentials

9. Document which Gateway uses which credentials

Verifying Credential Setup

After completing the PUT request, immediately verify you can access the Gateway with the auto-generated credentials:

# Test with the auto-generated credentials from GET response
curl -u "gateway_b100000000011d96:9EAgj5m859KMwP+W962hPFZHU2QJqAR1" \
  http://192.168.1.100/gateway/deviceInfo

Expected: Successful response with Gateway information

If this fails: The credentials may not have been committed properly. You may need to factory reset and try again.

Security Best Practices

  1. Act quickly:

    • Complete both GET and PUT steps immediately after Gateway installation
    • Default credentials are publicly documented and work until PUT is executed
    • Window between power-on and credential commit is a security vulnerability
    • Ideally complete within minutes of Gateway boot
  2. Secure storage: Store auto-generated Gateway credentials in:

    • Enterprise password managers (1Password, LastPass Enterprise, Keeper)
    • Secret management systems (HashiCorp Vault, AWS Secrets Manager, Azure Key Vault)
    • Encrypted configuration management databases
    • Never in plain text files, scripts, or version control
  3. Access control:

    • Limit who has access to Gateway credentials
    • Principle of least privilege
    • Role-based access control (RBAC)
    • Audit credential access and usage
  4. Network security:

    • Place Gateways on a secure VLAN isolated from general network traffic
    • Use firewall rules to restrict Gateway API access to authorized systems only
    • Consider network segmentation between Gateway network and untrusted networks
    • Disable Gateway access from the internet unless absolutely necessary
  5. Documentation:

    • Maintain secure documentation mapping each Gateway to its credentials
    • Include: Gateway serial number, IP address, MAC address, installation location
    • Keep credential documentation separate from network diagrams
    • Use credential references/IDs rather than actual passwords in documentation
  6. Backup credentials:

    • Store credentials in multiple secure locations (primary + backup)
    • Ensure business continuity if primary credential storage fails
    • Test credential recovery procedures
  7. Credential rotation:

    • Note: Auto-generated Gateway credentials cannot be changed without factory reset
    • If compromise is suspected, you must factory reset the Gateway
    • This will erase all configuration and require complete reconfiguration
    • Plan credential compromise response procedures in advance
  8. Multi-Gateway deployments:

    • Each Gateway has unique auto-generated credentials
    • Organize credentials by site, building, or zone
    • Use naming conventions in your password manager (e.g., “GW-Building_A-Front_Entrance”)
    • Test each Gateway’s credentials individually during deployment

Important Limitations

Cannot Change Credentials: Unlike many systems, ENGAGE Gateway credentials are fixed to the auto-generated values. You cannot set custom usernames or passwords.

To “change” credentials, you must:

  1. Factory reset the Gateway
  2. Gateway generates new random credentials
  3. Retrieve new credentials via GET
  4. Commit new credentials via PUT
  5. Warning: This erases all configuration, linked devices, etc.

Why this matters:

  • Plan for credential compromise differently than systems with changeable passwords
  • Factory reset is the only “credential rotation” mechanism
  • Emphasizes importance of protecting credentials and securing network access
  • Makes physical security of Gateway important (prevents unauthorized factory reset)

Troubleshooting Credentials

Problem: GET /gateway/newCredentials returns 401 Unauthorized

Solutions:

  1. Verify exactly: EngageGatewayDefaultUser / EngageGatewayDefaultPassword (case-sensitive)
  2. Credentials may have already been committed (PUT already executed)
  3. Try accessing other endpoints with the auto-generated credentials if you saved them
  4. Check network connectivity (ping the Gateway)
  5. Verify correct IP address
  6. Factory reset if necessary

Problem: GET returns empty, null, or error response

Solutions:

  1. Credentials may have already been committed via prior PUT request
  2. Check if you can authenticate to /gateway/deviceInfo with possible saved credentials
  3. Verify Gateway is fully booted (wait 60-120 seconds after power-on)
  4. Factory reset if credentials are unknown

Problem: PUT /gateway/newCredentials returns 401 Unauthorized

Solutions:

  1. Verify you’re using EngageGatewayDefaultUser / EngageGatewayDefaultPassword
  2. Double-check spelling and case
  3. Ensure Authorization header is properly formatted
  4. Credentials may have already been committed
  5. Try GET first to see if default credentials still work

Problem: PUT returns success but cannot authenticate with auto-generated credentials

Solutions:

  1. Verify you saved the credentials exactly as returned from GET (including case and special characters)
  2. Wait 10-30 seconds after PUT for credentials to fully activate
  3. Try GET /gateway/deviceInfo to test credentials
  4. Check for copy/paste errors in credentials (extra spaces, line breaks)
  5. Factory reset and retry if credentials aren’t working

Problem: Forgot to save credentials before PUT, or lost saved credentials

Solution:

  1. Factory reset the Gateway (consult hardware manual for reset button/procedure)
  2. WARNING: Factory reset will erase:
    • All Gateway configuration (network settings, host protocol, device name)
    • Linked device records (locks must be re-linked)
    • All custom settings and configurations
  3. After reset:
    • Gateway generates new auto-generated credentials (different from before)
    • Repeat GET → Save → PUT workflow
    • Reconfigure all Gateway settings
    • Re-link all locks to Gateway
    • Resend all lock configurations and databases

Problem: PUT request seems to succeed but default credentials still work

Solutions:

  1. Verify PUT request completed successfully (check response status)
  2. Wait a few seconds and retry with auto-generated credentials
  3. Check Gateway logs if accessible
  4. Reboot Gateway and verify behavior
  5. Contact Allegion support if issue persists

Subsequent Authentication

After committing credentials via PUT, all subsequent API requests must use the auto-generated credentials from Step 2a:

Using Basic Auth:

GET http://192.168.1.100/gateway/deviceInfo
Authorization: Basic <base64(gateway_b100000000011d96:9EAgj5m859KMwP+W962hPFZHU2QJqAR1)>

Example with curl:

curl -u "gateway_b100000000011d96:9EAgj5m859KMwP+W962hPFZHU2QJqAR1" \
  http://192.168.1.100/gateway/deviceInfo

Example with Postman:

  1. Open your collection or request
  2. Select “Authorization” tab
  3. Type: “Basic Auth”
  4. Username: gateway_b100000000011d96
  5. Password: 9EAgj5m859KMwP+W962hPFZHU2QJqAR1

Using Postman Environment Variables (Recommended):

For managing multiple Gateways efficiently:

  1. Create environment (e.g., “Building A - Gateway 1”)

  2. Add variables:

    • gateway_ip = 192.168.1.100
    • gateway_username = gateway_b100000000011d96
    • gateway_password = 9EAgj5m859KMwP+W962hPFZHU2QJqAR1
    • gateway_serial = b100000000011d96 (for documentation)
    • gateway_location = Building A - Main Entrance (for documentation)
  3. Update request URLs to: http://{{gateway_ip}}/...

  4. In Authorization tab:

    • Username: {{gateway_username}}
    • Password: {{gateway_password}}
  5. Benefits:

    • Switch between Gateways by changing active environment
    • Credentials stored securely in Postman
    • Easy to update if Gateway is replaced
    • Documented location for each Gateway

Step 3: Network Configuration

The Gateway supports two discovery methods (these are often set in the engage app when commissioning the device to the site):

{
  "gatewayConfig": {
    "gatewayIpModeConfig": {
      "interfaceId": "eth0",
      "interfaceEnable": "T",
      "discoveryMethod": "dhcp"
    }
  }
}
{
  "gatewayConfig": {
    "gatewayIpModeConfig": {
      "interfaceId": "eth0",
      "interfaceEnable": "T",
      "discoveryMethod": "staticIP",
      "fixedIpAddr": "192.168.1.100",
      "defGatewayIpAddr": "192.168.1.1",
      "netmask": "255.255.255.0",
      "ipDnsAddr": "8.8.8.8"
    }
  }
}

Step 3: Configure Host Connection

Set the connection protocol for communication with your access control system. In typical usage, the Gateway acts as a server and your access control system connects to it:

{
  "gatewayConfig": {
    "genGatewayConfig": {
      "hostProtocol": "ipEngage",
      "deviceName": "Main-Building-Gateway"
    }
  }
}

Host Protocol Options:

  • "ipEngage": Gateway acts as IP server (typical for 410-IP mode)
  • "rs485Rsi": RSI protocol over RS-485
  • "ipClient": Gateway acts as websocket client (see Advanced Topics section)

Important: See ENGAGE_JSON_Data_Structures - 2.18.pdf pages 57-65 for complete Gateway configuration options.


4. Linking ENGAGE Locks to the Gateway

Step 1: Discover Available Locks

Link using the Engage Mobile app, or use the Gateway’s scan functionality to discover nearby ENGAGE locks:

API Endpoint: GET /gateway/scanList

Response:

{
  "gatewayScanList": [
    {
      "mainSn": "A0B1000000000123",
      "deviceName": "Front Door",
      "signalQuality": "High",
      "modelType": "nde"
    }
  ]
}

API Endpoint: POST /edgeDevices

Request:

{
  "linkInfo": {
    "linkId": "door_001",
    "deviceId": "A0B1000000000123",
    "deviceName": "Front Door"
  }
}

Response:

{
  "linkInfo": {
    "linkId": "door_001",
    "deviceId": "A0B1000000000123",
    "deviceName": "Front Door",
    "linkCommStatus": "connected",
    "modelType": "nde"
  }
}

Step 3: Verify Connection

API Endpoint: GET /edgeDevices

Check that linkCommStatus shows "connected" for your devices.


5. Understanding Credentials

What is a PrimeCr?

A PrimeCr (Primary Credential) is a 16-byte encrypted data structure that represents a user’s access credential. It can contain:

  • Primary credential: Card number or PIN (first 8 bytes)
  • Secondary credential: Optional second factor (last 8 bytes)

Credential Structure

PrimeCr = [Primary (8 bytes)] + [Secondary (8 bytes)]
         = 16 bytes total

Example:

  • Card only: 0x8F166040FFFFFFFFFFFFFFFFFFFFFFFF
  • Card + PIN: 0x8F166040FFFFFFFF823456FFFFFFFFFF

Credential Types

  • “card”: Physical access card
  • “pin”: PIN code
  • “null”: No credential (used when only one factor needed)

Critical Reference: Schlage ENGAGE Credential Sort and Encryption-1.34.pdf provides the complete specification for credential encoding.


6. Creating and Encoding Credentials

Understanding Credentials

A credential is any object that transmits a series of bits to a reader to gain access or privileges. Common credential types include:

TypeInterfaceSecurity LevelNotes
ProximityTouchlessLowNot encrypted, vulnerable to replay/cloning
Smart CardTouch/TouchlessHighEncrypted, contains storage
Mobile BluetoothTouchlessHighRequires app, encrypted
NFCTouchlessHighNo app required, encrypted
MagstripeTouchVery LowNot encrypted, easily counterfeited

Important ENGAGE Distinction: Unlike traditional access control systems where readers parse facility codes, card IDs, and verify parity bits, ENGAGE locks simply compare the entirety of the expected credential data to the presented credential data. The lock does not parse individual fields or check parity — it performs a complete binary match.

Credential Data Components

Access cards contain multiple data elements encoded in their bit patterns:

  • Card ID / Cardholder ID: The unique card number (often printed on the card)
  • Site Code / Facility Code: Identifies the organization or site
  • Parity Bits: Error detection mechanism (even and odd parity)
  • Issue Codes: Optional, tracks card replacements (rarely used in modern systems)

Common Wiegand Formats

26-Bit Standard Wiegand

The most common format, used by millions of installations worldwide:

Structure (26 bits total):

Bit 0:       Even parity bit
Bits 1-8:    Facility code (8 bits = 0-255)
Bits 9-24:   Card number (16 bits = 0-65,535)
Bit 25:      Odd parity bit

Parity Configuration:

  • Even parity: Covers first 13 bits (parity bit + first 12 data bits)
  • Odd parity: Covers last 13 bits (last 12 data bits + parity bit)

Example:

  • Facility Code: 123 (decimal)
  • Card Number: 45678 (decimal)

37-Bit HID H10304 Format (also called Schlage 37X Format)

A more advanced format with larger capacity:

Structure (37 bits total, indexed 0-36):

Bit 0:       Even parity bit
Bits 1-16:   Facility/Site code (16 bits = 0-65,535)
Bits 17-35:  Card ID (19 bits = 0-524,287)
Bit 36:      Odd parity bit

Parity Configuration:

  • Even parity mask: Bits 0-18 (19 bits total)
  • Odd parity mask: Bits 18-36 (19 bits total, with 1-bit overlap at position 18)

Example - Real Card:

  • Stamped Card Number: 200802
  • Site Code: 700

Working Example: Building a Complete 37-Bit Credential

Let’s walk through encoding a real card with complete bit-level detail.

Step 1: Convert Decimal to Binary

Card Number (200802 decimal):
  Binary: 0110001000001100010 (19 bits)

Site Code (700 decimal):
  Binary: 0000001010111100 (16 bits)

Step 2: Build the 37-Bit Structure

Position the data according to H10304 format specification:

INDEX:           0  1                16 17                  35 36
                 P  [Site Code      ]  [Card ID             ]  P
POSITIONS:       0  1234567890123456   1234567890123456789 36
SITE CODE:          0000001010111100
CARD ID:                               0110001000001100010
PARITY BITS:     ?                                         ?

Expanded with padding:

INDEX:           0123456789012345678901234567890123456
EVEN PAR MASK:   1111111111111111111000000000000000000
ODD PAR MASK:    0000000000000000001111111111111111111
DATA (no par):   ?00000010101111000110001000001100010?

Step 3: Calculate Even Parity (Bit 0)

Count the 1s in positions covered by even parity mask (bits 0-18):

Bits 1-18:  0000001010111100001
Count of 1s: 7 (odd number)

Since we have an odd count and need even parity, set bit 0 to 1 to make the total even (8).

Result: Bit 0 = 1

Step 4: Calculate Odd Parity (Bit 36)

Count the 1s in positions covered by odd parity mask (bits 18-36):

Bits 18-35: 100110001000001100010
Count of 1s: 6 (even number)

Since we have an even count and need odd parity, set bit 36 to 1 to make the total odd (7).

Result: Bit 36 = 1

Step 5: Complete 37-Bit Credential

Complete binary (37 bits):
1000000101011110001100010000011000101

Breakdown:
  Bit 0:        1 (even parity)
  Bits 1-16:    0000001010111100 (site code 700)
  Bits 17-35:   0110001000001100010 (card 200802)
  Bit 36:       1 (odd parity)

Convert to hexadecimal:

Binary:  1000000101011110001100010000011000101
Hex:     0x102BC620C5

Understanding PrimeCR Structure

PrimeCR (Primary Credential) is a 16-byte field in the ENGAGE JSON that contains credential data:

PrimeCR = [Primary (8 bytes)] + [Secondary (8 bytes)]
        = 16 bytes total (128 bits)

Usage:

  • Single-factor credentials: Use first 8 bytes, fill last 8 bytes with 0xFF
  • Two-factor credentials: First 8 bytes = card, last 8 bytes = PIN
  • Dual credentials: First 8 bytes = card 1, last 8 bytes = card 2

Encoding PrimeCR: Byte Alignment and Padding

Critical Concept: All credential data must be aligned to byte boundaries (multiples of 8 bits).

Alignment Process

  1. Count your credential bits (e.g., 37 bits)
  2. Calculate bits needed to reach next byte boundary:
    • 37 bits ÷ 8 = 4.625 bytes
    • Round up to 5 bytes = 40 bits needed
    • Need to add 3 bits (40 - 37 = 3)
  3. Perform 3 left shifts (aka multiply by 2³ = 8):
    • Append 3 zero bits to the right
    • This aligns data to a byte boundary

Worked Example: 37-Bit Card to PrimeCR

Starting data (37 bits):

Binary: 1000000101011110001100010000011000101
Hex:    0x102BC620C5

Step 1: Left shift 3 positions (append 3 zeros):

Original:  1000000101011110001100010000011000101    (37 bits)
Shifted:   1000000101011110001100010000011000101000 (40 bits = 5 bytes)
Hex:       0x815E310628

Step 2: Pad to 8 bytes with 0xFF:

0x815E310628FFFFFFFFFF

Step 3: Add secondary credential (8 bytes of 0xFF for single-factor):

0x815E310628FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

Result: 16-byte PrimeCR

Breakdown:
  0x815E310628   - Card data (37 bits left-shifted by 3)
  FFFFFFFFFF     - Padding to fill first 8 bytes
  FFFFFFFFFFFFFFFF - Secondary credential (none = 0xFF)

Quick Reference: Common Format Shifts

FormatBitsShift ByResult Bytes
26-bit266 bits (×64)4 bytes
34-bit346 bits (×64)5 bytes
35-bit355 bits (×32)5 bytes
37-bit373 bits (×8)5 bytes
48-bit480 bits (×1)6 bytes

Formula: bits_to_shift = (8 - (credential_bits % 8)) % 8

Encoding Multi-Factor Credentials

Card + PIN Example

Scenario: User must present both card and 6-digit PIN.

Card data (26-bit):

Raw: 0x23C5981
Shifted left 6: 0x8F166040
Padded to 8 bytes: 0x8F166040FFFFFFFF

PIN data (123456 decimal = 0x1E240):

Raw: 0x1E240
Shifted and padded: 0x001E2400FFFFFFFF

Combined PrimeCR:

0x8F166040FFFFFFFF001E2400FFFFFFFF

Breakdown:
  Primary (card):    0x8F166040FFFFFFFF
  Secondary (PIN):   0x001E2400FFFFFFFF

JSON Configuration:

{
  "usrID": 50,
  "primeCr": "ENCRYPTED_VALUE_HERE",
  "prCrTyp": "card",
  "scndCrTyp": "pin"
}

Credential Sorting (CRITICAL)

Before encryption, credentials MUST be sorted in ascending order by their unencrypted PrimeCR values.

Why this matters:

  • Locks use binary search for credential lookup
  • Sorted database: ~100ms lookup time for 5000+ users
  • Unsorted database: Several seconds (linear search)

Sorting Process:

  1. Build all unencrypted PrimeCR values
  2. Sort by comparing PrimeCR as unsigned 128-bit integers (lowest to highest)
  3. Encrypt each credential with site key
  4. Preserve the sorted order in final JSON
  5. Send to lock

Example Sort Order:

0x001E2400FFFFFFFFFFFFFFFFFFFFFFFF  (lowest)
0x8F166040FFFFFFFFFFFFFFFFFFFFFFFF
0x9A250750FFFFFFFFFFFFFFFFFFFFFFFF  (highest)

Encryption with Site Key

Use AES-256 CBC encryption per Schlage ENGAGE specification:

Encryption Parameters:

  • Algorithm: AES-256
  • Mode: CBC (Cipher Block Chaining)
  • Key: 32-byte site key (from site creation)
  • IV (Initialization Vector): All zeros (0x00000000000000000000000000000000)

Example:

Site Key (hex):  00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF
Unencrypted:     815E310628FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
Encrypted:       7a749873c4b3f54dfdd31b3f82e67e55

Tools for Encryption:

  • Allegion’s Encrypt/Decrypt NoTourPayload tool (PC app included in training materials)
  • Online tools: aes.online-domain-tools.com (set to CBC mode, IV=0)
  • Programming libraries: PyCryptodome (Python), CryptoJS (JavaScript), etc.

IMPORTANT: Never send unencrypted PrimeCR values to locks. Always encrypt before transmission.

Complete Encoding Workflow

1. Obtain card data (from enrollment reader or audit trail)

2. Parse facility code and card number

3. Convert to binary representation

4. Calculate and add parity bits

5. Convert to hexadecimal

6. Left-shift to align to byte boundary

7. Pad with 0xFF to complete 16-byte PrimeCR

8. Sort all credentials (unencrypted)

9. Encrypt each PrimeCR with site key

10. Build JSON with encrypted values in sorted order

11. Send to lock via Gateway API

Verifying Your Encoding (Testing Method)

Use audit trails to verify correctness:

  1. Using a test credential
  2. Send database to lock without that credential
  3. Present the physical card/credential to lock
  4. Lock will deny access and generate audit event
  5. Audit contains raw card data captured by reader
  6. Compare audit data to your calculated values

Example Audit:

{
  "audits": [
    {
      "event": "13000025",  // Card not in database, length=37 bits
      "event": "13010628",  // Card data bytes (reverse order)
      "event": "13025e31",
      "event": "13030081"
    }
  ]
}

Reconstruct: 0x00815e310628 → matches our calculated value ✓

Best Practices for Credential Encoding

  1. Always calculate parity last: Fill all data bits first, then calculate parity to ensure masks sum correctly

  2. Document your format: Record the exact Wiegand format (26-bit, 37-bit, etc.) used in your deployment

  3. Test with real cards: Verify encoding by capturing audit events from actual card presentations

  4. Understand byte alignment: Don’t blindly shift — understand why alignment to byte boundaries is necessary

  5. Never skip sorting: Always sort before encryption, even for small databases

  6. Verify encryption parameters: Confirm IV=0 and correct site key are used

  7. Send complete databases: Prefer sending full sorted databases over incremental updates

  8. Monitor database limits:

    • NDEB/LEB locks: 5000 credentials
    • Control locks: 2000 credentials
    • Watch for audit code 0x06000004 (database full)
  9. Facility code limitations: Don’t rely on facility codes alone for security with standard 125 kHz proximity cards (easily cloned)

  10. Maintain sort order: After encryption, keep the same ordering based on unencrypted values

Additional Resources

  • Schlage Credential Formats-200624.pdf: Complete specifications for some common Wiegand formats
  • 04 - Examining Card Data: Detailed examples of parsing card data
  • 05 - More on PrimeCR: Advanced credential encoding techniques
  • Credential Sort and Encryption: Official sorting and encryption specification

7. Creating User Databases

Minimum Required User Record

{
  "db": {
    "usrRcrd": {
      "deleteAll": 1,
      "delete": [],
      "update": [],
      "add": [
        {
          "usrID": 1,
          "adaEn": 0,
          "fnctn": "norm",
          "crSch": [1],
          "actDtTm": "20000101000000",
          "expDtTm": "21350101000000",
          "primeCr": "34110EA549AA549AA73FF06DC93B63B4",
          "prCrTyp": "card",
          "scndCrTyp": "null"
        }
      ]
    },
    "schedules": [
      {
        "days": ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"],
        "strtHr": 0,
        "strtMn": 0,
        "lngth": 1439
      }
    ],
    "holidays": [],
    "autoUnlock": [],
    "nxtDbVerTS": "0x0000000000000001"
  }
}

Key Fields Explained

FieldDescription
deleteAll1 = Replace entire database, 0 = Update existing
usrIDUnique user identifier (1-1,048,575)
fnctnCredential function: “norm”, “toggle”, “freeze”, etc.
crSchArray of schedule IDs (minimum one schedule required)
actDtTmActivation date/time (YYYYMMDDHHMMSS)
expDtTmExpiration date/time
primeCrEncrypted and sorted 16-byte credential
prCrTypPrimary credential type: “card” or “pin”
scndCrTypSecondary credential type: “card”, “pin”, or “null”
nxtDbVerTSVersion timestamp for synchronization

Adding Multiple Users

{
  "db": {
    "usrRcrd": {
      "deleteAll": 1,
      "delete": [],
      "update": [],
      "add": [
        {
          "usrID": 1,
          "primeCr": "34110EA549AA549AA73FF06DC93B63B4",
          ...
        },
        {
          "usrID": 2,
          "primeCr": "45220FB65ABB65ABB84GG17ED04C74C5",
          ...
        }
      ]
    }
  }
}

Remember: Credentials in the add array must be sorted by unencrypted value before encryption.


8. Credential Schedules

Default 24/7 Schedule

Every database must include at least one schedule. Schedule ID 1 is typically 24/7 access:

{
  "schedules": [
    {
      "days": ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"],
      "strtHr": 0,
      "strtMn": 0,
      "lngth": 1439
    }
  ]
}

Business Hours Schedule

Schedule ID 2: Monday-Friday, 8 AM to 5 PM (9 hours = 540 minutes)

{
  "schedules": [
    {
      "days": ["Mo", "Tu", "We", "Th", "Fr"],
      "strtHr": 8,
      "strtMn": 0,
      "lngth": 540
    }
  ]
}

Assigning Schedules to Users

{
  "usrID": 1,
  "crSch": [1, 2],
  ...
}

This user has access during schedule 1 OR schedule 2 time windows.

Two-Factor Authentication Schedules

Require both card and PIN during certain hours:

{
  "schedules": [
    {
      "days": ["Mo", "Tu", "We", "Th", "Fr"],
      "strtHr": 18,
      "strtMn": 0,
      "lngth": 720,
      "auth": "2f"
    }
  ]
}

Authentication modes:

  • "1f": Single factor (card OR PIN)
  • "2f": Two factor (card AND PIN, same user)
  • "1fx2": Single factor twice (two different users)
  • "2fx2": Two factor twice (two different users, each with card+PIN)

9. Holidays and Auto-Unlock

Holiday Records

Override normal schedules on specific dates:

{
  "holidays": [
    {
      "strtDtTm": "20261225000000",
      "endDtTm": "20261226000000",
      "action": "pass"
    },
    {
      "strtDtTm": "20260704000000",
      "endDtTm": "20260705000000",
      "action": "sec"
    }
  ]
}

Actions:

  • "pass": Unlock door (passage mode)
  • "sec": Lock door (secure mode)
  • "rstrctSec": Restricted secure (only freeze and pass-through credentials work)

Auto-Unlock Events

Automatically lock/unlock doors at specific times:

{
  "autoUnlock": [
    {
      "action": "pass",
      "strtHr": 8,
      "strtMn": 0,
      "days": ["Mo", "Tu", "We", "Th", "Fr"]
    },
    {
      "action": "sec",
      "strtHr": 17,
      "strtMn": 0,
      "days": ["Mo", "Tu", "We", "Th", "Fr"]
    }
  ]
}

10. Sending Database to Locks

Via Gateway API

Endpoint: PUT /edgeDevices/{linkId}/lockData

Request:

{
  "edgeDevice": [
    {
      "linkId": "door_001",
      "db": {
        "usrRcrd": { ... },
        "schedules": [ ... ],
        "holidays": [ ... ],
        "autoUnlock": [ ... ]
      },
      "nxtDbVerTS": "0x0000000000000001"
    }
  ]
}

Database Synchronization

The nxtDbVerTS (Next Database Version Timestamp) keeps the lock and host synchronized:

  1. Lock requests database with current nxtDbVerTS value (starts at 0 for new locks)
  2. Host sends database with new nxtDbVerTS value
  3. Lock stores new nxtDbVerTS
  4. On next request, lock includes updated nxtDbVerTS

Important: Always increment the nxtDbVerTS value when sending database updates.

Partial Database Updates

For updating individual users without replacing the entire database:

{
  "db": {
    "usrRcrd": {
      "deleteAll": 0,
      "delete": [
        {
          "primeCr": "34110EA549AA549AA73FF06DC93B63B4",
          "prCrTyp": "card"
        }
      ],
      "update": [
        {
          "usrID": 2,
          "primeCr": "45220FB65ABB65ABB84GG17ED04C74C5",
          "expDtTm": "20271231235959",
          ...
        }
      ],
      "add": [
        {
          "usrID": 100,
          "primeCr": "56330GC76BCC76BCC95HH28FE15D85D6",
          ...
        }
      ]
    }
  }
}

Processing order: Delete → Update → Add


11. Lock Configuration

Common Configuration Parameters

{
  "edgeDevice": [
    {
      "linkId": "door_001",
      "config": {
        "name": "Front Door",
        "type": "office",
        "relock": 5,
        "doorProp": 30,
        "ada": 10,
        "rtcTime": "20260401120000",
        "gatewayCommFail": "sec",
        "tamperFail": "sec"
      }
    }
  ]
}

Key Configuration Tags

TagDescriptionValues
relockAuto-relock delay (seconds)1-60 for Control, 1-30 for others
doorPropDoor propped alarm delay (seconds)1-255
adaADA compliant unlock time (seconds)1-255
typeLock function type”strm”, “office”, “apt”, “prvcy”
gatewayCommFailFailsafe mode when Gateway offline”asIs”, “sec”, “safe”
tamperFailFailsafe mode on tamper”asIs”, “sec”, “safe”

Reader Configuration

Enable/disable credential types:

{
  "config": {
    "proxConfHID": "T",
    "uid14443": "T",
    "noc14443": "T",
    "iClsUID40b": "F",
    "bleCredEn": "T",
    "pinEn": "T",
    "pinLength": 6
  }
}

CRITICAL: Enable Access Denied Audits

IMPORTANT: By default, locks do NOT generate audit events for invalid/denied credentials. You must explicitly enable this feature.

Set invCrdAudEn to "T" to receive access denied events:

{
  "config": {
    "invCrdAudEn": "T"
  }
}

Why this matters:

  • Default value: "F" (disabled) - invalid credential presentations generate NO audit events
  • When enabled: "T" - lock generates audit events when unknown/invalid credentials are presented
  • Security monitoring: Essential for detecting unauthorized access attempts, cloned cards, or compromised credentials
  • Compliance: Many security policies require logging of failed access attempts
  • Troubleshooting: Critical for debugging credential encoding issues or determining why a card doesn’t work

Common use cases for access denied audits:

  • Detecting unauthorized access attempts
  • Identifying expired or revoked credentials still in use
  • Debugging credential encoding or encryption issues
  • Compliance reporting for security incidents
  • Monitoring for lost or stolen credentials

Example: Enable access denied auditing in complete doorfile:

{
  "edgeDevice": [
    {
      "linkId": "door_001",
      "db": {
        "usrRcrd": {
          "deleteAll": 1,
          "add": [ ... ]
        },
        "schedules": [ ... ],
        "holidays": [ ... ],
        "autoUnlock": [ ... ]
      },
      "config": {
        "invCrdAudEn": "T",
        "name": "Front Door",
        "type": "office"
      },
      "nxtDbVerTS": "0x0000000000000001"
    }
  ]
}

Note: The config section appears after the db, schedules, holidays, and autoUnlock sections in the doorfile structure.

Audit event codes for denied access (when invCrdAudEn is enabled):

  • Event code 13xxxxxx: Invalid credential presented, includes credential data in subsequent audit records
  • See ENGAGE Audit & Alert Definitions for complete event code details

RECOMMENDATION: Always set invCrdAudEn to "T" in production deployments for security monitoring and troubleshooting.

How Configuration Updates Work

IMPORTANT: Understanding how configuration updates are applied is critical to avoid unintended changes.

Configuration in the Lock Data Structure

Configuration parameters are sent within the lock data structure (often called the “doorfile”). The config section appears after the database sections:

{
  "edgeDevice": [
    {
      "linkId": "door_001",
      "db": {
        "usrRcrd": { ... },
        "schedules": [ ... ],
        "holidays": [ ... ],
        "autoUnlock": [ ... ]
      },
      "config": {
        "name": "Front Door",
        "invCrdAudEn": "T"
      },
      "nxtDbVerTS": "0x0000000000000001"
    }
  ]
}

The config section appears alongside the db (database) section in the same request.

Partial Configuration Updates

Key concept: Only parameters explicitly included in the config object are updated. Omitted parameters remain unchanged at their current values.

Example 1: Update only audit setting

{
  "edgeDevice": [
    {
      "linkId": "door_001",
      "config": {
        "invCrdAudEn": "T"
      }
    }
  ]
}

Result:

  • invCrdAudEn is updated to "T"
  • All other settings (name, type, relock, doorProp, etc.) remain at their current values
  • No other parameters are affected

Example 2: Update multiple parameters

{
  "edgeDevice": [
    {
      "linkId": "door_001",
      "config": {
        "invCrdAudEn": "T",
        "relock": 10,
        "doorProp": 45
      }
    }
  ]
}

Result:

  • invCrdAudEn is updated to "T"
  • relock is updated to 10 seconds
  • doorProp is updated to 45 seconds
  • All other settings (name, type, ada, gatewayCommFail, etc.) remain unchanged

Combining Database and Configuration Updates

Common pattern: Send database and configuration together in a single request:

{
  "edgeDevice": [
    {
      "linkId": "door_001",
      "db": {
        "usrRcrd": {
          "deleteAll": 1,
          "add": [ ... ]
        },
        "schedules": [ ... ],
        "holidays": [ ... ],
        "autoUnlock": [ ... ]
      },
      "config": {
        "invCrdAudEn": "T",
        "rtcTime": "20260415120000"
      },
      "nxtDbVerTS": "0x0000000000000001"
    }
  ]
}

Result:

  • Database sections are updated (users, schedules, holidays, auto-unlock)
  • Configuration parameters are updated
  • Both operations happen in a single transaction

Best Practices for Configuration Updates

  1. Update only what you need: Don’t include parameters you’re not changing—this avoids accidental overwrites and keeps requests smaller

  2. Track current configuration: Maintain a record of each lock’s current configuration to know what values are already set

  3. Verify after update: After sending configuration, retrieve lock data to verify the update was applied:

    GET {{gatewayIP}}/edgeDevices/{{linkId}}/lockData
  4. Test configuration changes: Test on a single lock before applying to all locks in your deployment

  5. Document configuration standards: Maintain documentation of your standard lock configuration (which parameters you always set)

  6. Initial setup vs. updates:

    • Initial setup: Send all desired configuration parameters
    • Ongoing updates: Send only parameters that need to change

Common Configuration Update Scenarios

Scenario 1: Enable auditing on existing locks (configuration only)

{
  "edgeDevice": [
    {
      "linkId": "door_001",
      "config": {
        "invCrdAudEn": "T"
      }
    }
  ]
}

All other settings remain unchanged. No database sections needed.

Scenario 2: Update clock and auditing (configuration only)

{
  "edgeDevice": [
    {
      "linkId": "door_001",
      "config": {
        "rtcTime": "20260415143000",
        "invCrdAudEn": "T"
      }
    }
  ]
}

Only RTC time and audit setting are updated.

Scenario 3: Full initial configuration with database

{
  "edgeDevice": [
    {
      "linkId": "door_001",
      "db": {
        "usrRcrd": {
          "deleteAll": 1,
          "add": [ ... ]
        },
        "schedules": [ ... ],
        "holidays": [ ... ],
        "autoUnlock": [ ... ]
      },
      "config": {
        "name": "Front Door",
        "type": "office",
        "relock": 5,
        "doorProp": 30,
        "ada": 10,
        "invCrdAudEn": "T",
        "gatewayCommFail": "sec",
        "tamperFail": "sec",
        "proxConfHID": "T",
        "pinEn": "T",
        "rtcTime": "20260415143000"
      },
      "nxtDbVerTS": "0x0000000000000001"
    }
  ]
}

During initial setup, specify all desired configuration parameters along with the complete database.

Complete configuration reference: JSON Data Structures document, pages 13-21.


12. Testing with Postman

Setting Up Postman

  1. Create a new Collection: “ENGAGE Gateway API”
  2. Set Base URL Variable: {{gateway_url}} = http://192.168.1.100 (your Gateway IP)
  3. Add Authentication (if required by your Gateway configuration)

Essential API Requests

1. Get Gateway Information

GET {{gateway_url}}/gateway/deviceInfo

Expected response includes firmware version, network settings, and linked devices.

2. Scan for Locks

GET {{gateway_url}}/gateway/scanList

Returns nearby ENGAGE devices available for linking.

POST {{gateway_url}}/edgeDevices
Content-Type: application/json

{
  "linkInfo": {
    "linkId": "test_door_01",
    "deviceId": "A0B1000000000123",
    "deviceName": "Test Door"
  }
}

4. Get Lock Status

GET {{gateway_url}}/edgeDevices/test_door_01/lockData

Returns current lock state, battery level, and configuration.

5. Send Test Database

PUT {{gateway_url}}/edgeDevices/test_door_01/lockData
Content-Type: application/json

{
  "edgeDevice": [
    {
      "linkId": "test_door_01",
      "db": {
        "usrRcrd": {
          "deleteAll": 1,
          "delete": [],
          "update": [],
          "add": [
            {
              "usrID": 1,
              "adaEn": 0,
              "fnctn": "norm",
              "crSch": [1],
              "actDtTm": "20000101000000",
              "expDtTm": "21350101000000",
              "primeCr": "YOUR_ENCRYPTED_CREDENTIAL_HERE",
              "prCrTyp": "card",
              "scndCrTyp": "null"
            }
          ]
        },
        "schedules": [
          {
            "days": ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"],
            "strtHr": 0,
            "strtMn": 0,
            "lngth": 1439
          }
        ],
        "holidays": [],
        "autoUnlock": []
      },
      "nxtDbVerTS": "0x0000000000000001"
    }
  ]
}

6. Retrieve Audit Trail

GET {{gateway_url}}/edgeDevices/test_door_01/lockData

Look for audits array in response.

Postman Tips

  • Save Responses: Use Postman’s “Save Response” feature to build examples
  • Environment Variables: Store linkId, deviceId, etc. as variables
  • Pre-request Scripts: Auto-generate timestamps for rtcTime
  • Tests: Add assertions to verify successful responses

Reference: See [03 - What are json files and further postman usage](ip-gateway-info/Slideshows for engage training/PPT slideshows/) presentation for detailed Postman workflows.


13. Monitoring and Auditing

Retrieving Audit Logs

Locks store audit events locally and report them to the Gateway:

{
  "audits": [
    {
      "event": "008A0000",
      "time": "20260401143022",
      "auditId": "145"
    }
  ]
}

Retrieving Audits Endpoint

API Endpoint: GET {{gatewayIP}}/edgeDevices/{{linkId}}/audits

Retrieve audit events from a specific lock:

Request:

GET http://192.168.1.100/edgeDevices/door_001/audits
Authorization: Basic <base64(username:password)>

Response:

{
  "edgeDevice": [
    {
      "linkId": "door_001",
      "audits": [
        {
          "event": "008A0000",
          "time": "20260415143022",
          "auditId": "145"
        },
        {
          "event": "008B0001",
          "time": "20260415143045",
          "auditId": "146"
        }
      ]
    }
  ]
}

Common Audit Events

Refer to the ENGAGE Audit & Alert Definitions document for complete event codes. Common examples:

  • Valid credential access: User successfully unlocked door
  • Invalid credential: Unknown credential presented
  • Door forced: Door opened without valid credential
  • Low battery: Battery voltage below threshold
  • Tamper alert: Lock cover removed

Polling for Audit Events and Lock Status

IMPORTANT: The Gateway API uses a polling model for monitoring audits and lock status. There is no push notification or webhook mechanism in 410-IP mode.

Audit and Status Monitoring:

  • Recommended frequency: Every 5 to 10 seconds
  • Minimum interval: 5 seconds (do not poll more frequently)
  • Maximum interval: Up to 60 seconds for non-critical monitoring

Why These Limits?

  1. Too frequent (< 5 seconds):

    • Unnecessary load on Gateway
    • Minimal benefit (lock events don’t change that rapidly)
    • Can impact Gateway performance, especially with many locks
    • May cause network congestion
  2. Recommended range (5-10 seconds):

    • Balances responsiveness with system load
    • Captures most events in near real-time
    • Allows Gateway to process BLE communication with locks
    • Suitable for most access control applications
  3. Too infrequent (> 60 seconds):

    • May miss time-sensitive events
    • Delayed notification of security incidents
    • Poor user experience for monitoring dashboards

When to Discontinue Polling

CRITICAL: Stop polling during firmware updates

When performing firmware updates (ONR - Over-the-Network Reflash):

  • Discontinue all polling to Gateway and locks during firmware flash operations
  • Gateway and lock resources are consumed by firmware transfer and flashing
  • Polling during firmware updates can:
    • Interfere with firmware transfer
    • Cause update failures
    • Extend update duration significantly
    • Risk corrupting the firmware flash

Resume polling after:

  • Gateway firmware update: Wait 2-3 minutes after Gateway reboots
  • Lock firmware update: Wait until lock status shows update complete
  • Verify firmware version updated successfully before resuming normal polling

See Firmware Updates section for detailed update procedures.

Polling Endpoints

Get Audits Only:

GET http://{{gatewayIP}}/edgeDevices/{{linkId}}/audits

Get Lock Data (includes audits and status):

GET http://{{gatewayIP}}/edgeDevices/{{linkId}}/lockData

Get All Locks Status:

GET http://{{gatewayIP}}/edgeDevices

Implementing Polling

Example polling implementation:

// Poll interval: 5 seconds (5000 ms)
const POLL_INTERVAL = 5000;
let pollingEnabled = true;

async function pollLockAudits(linkId) {
  if (!pollingEnabled) {
    console.log('Polling disabled (firmware update in progress)');
    return;
  }
  
  try {
    const response = await fetch(
      `http://192.168.1.100/edgeDevices/${linkId}/audits`,
      {
        headers: {
          'Authorization': 'Basic ' + btoa('username:password')
        }
      }
    );
    
    const data = await response.json();
    
    // Process audits
    if (data.edgeDevice?.[0]?.audits) {
      processAudits(data.edgeDevice[0].audits);
    }
    
  } catch (error) {
    console.error('Polling error:', error);
  }
}

// Control polling state
function stopPolling() {
  pollingEnabled = false;
  console.log('Polling stopped for firmware update');
}

function resumePolling() {
  pollingEnabled = true;
  console.log('Polling resumed');
}

// Start polling
setInterval(() => {
  pollLockAudits('door_001');
}, POLL_INTERVAL);

Polling Best Practices

  1. Use consistent intervals: Don’t vary polling frequency randomly—maintain steady intervals

  2. Handle errors gracefully:

    • Don’t stop polling if one request fails
    • Implement exponential backoff if Gateway becomes unresponsive
    • Log errors but continue polling
  3. Track processed audits:

    • Store the last auditId processed
    • Only process new audits (higher auditId values)
    • Prevents duplicate event processing
  4. Disable during maintenance:

    • Stop polling before firmware updates
    • Pause polling during Gateway configuration changes
    • Resume after verifying Gateway is operational
  5. Batch operations:

    • If monitoring multiple locks, stagger requests
    • Don’t poll all locks simultaneously
    • Spread requests across the polling interval
  6. Connection pooling:

    • Reuse HTTP connections when possible
    • Implement connection timeout (5-10 seconds)
    • Close idle connections to avoid resource exhaustion

14. Door Control

ENGAGE locks can be remotely controlled via the Gateway API, allowing your access control system to command doors into different states (unlock, lock, passage mode, etc.) without requiring a physical credential presentation.

Overview

The lockControl endpoint provides real-time control over lock states. This is useful for:

  • Remote unlock: Granting temporary access to visitors via intercom/video system
  • Emergency lockdown: Securing all doors during security incidents
  • Passage mode: Unlocking doors during business hours or events
  • Scheduled state changes: Automating door modes based on time or events
  • Integration with other systems: Fire alarm integration, building automation, etc.

Lock Control Endpoints

The Gateway provides two endpoint variants for controlling locks:

Broadcast to All Locks

PUT {{gatewayIP}}/edgeDevices/lockControl

Commands all linked locks on the Gateway simultaneously. Useful for facility-wide lockdown or passage mode.

Control Specific Lock

PUT {{gatewayIP}}/edgeDevices/{{linkId}}/lockControl

Commands a single lock identified by its linkId. Useful for individual door control.

Request Structure

JSON Payload:

{
  "lockControl": {
    "lockState": {
      "nextLockState": "momentaryUnlock"
    }
  }
}

Field Descriptions:

FieldDescriptionRequired
lockControlTop-level container for lock control commandsYes
lockStateContainer for state change commandsYes
nextLockStateTarget state for the lockYes

Available Lock States

StateDescriptionDurationUse Case
momentaryUnlockTemporarily unlock, then relockRelock delay periodRemote unlock for visitor entry
secSecure (locked) modeUntil next eventLock down door, end passage mode
passPassage (unlocked) modeUntil next eventBusiness hours, events
rstrctSecRestricted secureUntil next eventLockdown with passthrough credentials only

Note: Available states depend on the lock’s configured door mode (office, storeroom, apartment, privacy). See Door Modes document for state compatibility.

State Persistence

IMPORTANT: Lock control commands put the device into the commanded state until a recalculation event occurs.

Recalculation Events (triggers lock to re-evaluate its state):

  • Special credentials presented (freeze, toggle, lockdown, passthrough functions)
  • Holiday schedule begins or ends
  • Auto-unlock schedule event fires
  • Time zone change or RTC update

Frozen States: If the door is in a “frozen” state (via freeze credential), lock control commands may be ignored until the freeze is released.

Examples

Example 1: Remote Unlock Single Door

Scenario: Visitor arrives, security guard remotely unlocks the front door.

PUT http://192.168.1.100/edgeDevices/front_door/lockControl
Content-Type: application/json

{
  "lockControl": {
    "lockState": {
      "nextLockState": "momentaryUnlock"
    }
  }
}

Result: Front door unlocks for the configured relock delay period (e.g., 5 seconds), then automatically relocks.

Example 2: Facility-Wide Passage Mode

Scenario: Enable passage mode on all doors for a company event.

PUT http://192.168.1.100/edgeDevices/lockControl
Content-Type: application/json

{
  "lockControl": {
    "lockState": {
      "nextLockState": "pass"
    }
  }
}

Result: All linked locks enter passage (unlocked) mode and remain unlocked until another command or recalculation event occurs.

Example 3: Emergency Lockdown

Scenario: Security incident requires immediate lockdown of all doors.

PUT http://192.168.1.100/edgeDevices/lockControl
Content-Type: application/json

{
  "lockControl": {
    "lockState": {
      "nextLockState": "rstrctSec"
    }
  }
}

Result: All doors enter restricted secure mode. Only passthrough/freeze credentials will work until lockdown is cleared.

Example 4: Return to Normal Operation

Scenario: Event ends, return all doors to secure mode.

PUT http://192.168.1.100/edgeDevices/lockControl
Content-Type: application/json

{
  "lockControl": {
    "lockState": {
      "nextLockState": "sec"
    }
  }
}

Result: All doors return to locked (secure) mode. Normal credentials will unlock as configured.

Response Format

Successful lock control commands return confirmation:

{
  "lockControl": {
    "lockState": {
      "nextLockState": "momentaryUnlock"
    }
  },
  "status": "success"
}

Verification

After sending a lock control command, verify the lock state changed:

GET http://192.168.1.100/edgeDevices/{{linkId}}/lockData

Check the response for current lock state in the lockState field:

{
  "edgeDevice": [
    {
      "linkId": "front_door",
      "lockState": {
        "currentLockState": "pass"
      }
    }
  ]
}

Best Practices

  1. Verify connectivity: Check linkCommStatus is "connected" before sending lock control commands

  2. Monitor response: Always verify the API response indicates success

  3. Coordinate with schedules: Be aware that auto-unlock/holiday schedules may override manual lock control commands

  4. Audit trail: Lock control commands generate audit events—monitor these to track who/what changed door states

  5. Emergency procedures: Document procedures for emergency lockdown and ensure operators are trained

  6. Test regularly: Periodically test lock control functionality to ensure integration is working correctly

  7. Failsafe configuration: Set appropriate gatewayCommFail mode to determine lock behavior if Gateway goes offline

  8. Understand door modes: Different door types (office, storeroom, apartment) respond differently to lock control commands

Integration Patterns

Pattern 1: Intercom/Video Integration

// Visitor presses intercom button
async function remoteUnlock(doorLinkId) {
  // Send unlock command
  await fetch(`http://${gatewayIP}/edgeDevices/${doorLinkId}/lockControl`, {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      lockControl: {
        lockState: {
          nextLockState: 'momentaryUnlock'
        }
      }
    })
  });
  
  // Log the event
  console.log(`Door ${doorLinkId} remotely unlocked at ${new Date()}`);
}

Pattern 2: Scheduled Passage Mode

// Business hours automation
async function setBusinessHoursMode() {
  const now = new Date();
  const hour = now.getHours();
  const day = now.getDay();
  
  // Monday-Friday, 8 AM to 5 PM
  if (day >= 1 && day <= 5 && hour >= 8 && hour < 17) {
    await setAllDoorsState('pass');
  } else {
    await setAllDoorsState('sec');
  }
}

async function setAllDoorsState(state) {
  await fetch(`http://${gatewayIP}/edgeDevices/lockControl`, {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      lockControl: {
        lockState: {
          nextLockState: state
        }
      }
    })
  });
}

Limitations and Considerations

  1. No individual override: Broadcast commands affect all linked locks—you cannot exclude specific locks from a broadcast command

  2. State persistence: Locks remain in commanded state until a recalculation event—plan for how to return to normal operation

  3. Network dependency: Lock control requires Gateway connectivity—locks should have appropriate failsafe configuration

  4. BLE latency: Commands must traverse IP → Gateway → BLE → Lock, introducing latency (typically 1-3 seconds)

  5. Conflicting schedules: Auto-unlock and holiday schedules may interfere with manual lock control commands

  6. Door mode limitations: Some lock states are not compatible with all door modes (e.g., passage mode on privacy function locks)

Troubleshooting

Lock doesn’t respond to control command:

  1. Verify linkCommStatus shows "connected"
  2. Check BLE signal strength between Gateway and lock
  3. Ensure lock is not in frozen state
  4. Verify door mode supports the requested state
  5. Check for active holiday/auto-unlock schedules overriding the command

Lock enters state but immediately reverts:

  1. Check for conflicting auto-unlock schedules
  2. Verify no special credentials are being presented
  3. Review recent audit logs for recalculation events
  4. Ensure holiday schedules aren’t overriding the command

Broadcast command only affects some locks:

  1. Check linkCommStatus for all locks
  2. Verify all locks are actually linked to the Gateway
  3. Check BLE connectivity for locks that didn’t respond
  4. Review Gateway logs for command delivery status

15. Firmware Updates

Firmware updates can be performed over-the-network (ONR - Over-the-Network Reflash) for both the Gateway itself and for locks linked to the Gateway.

Understanding Firmware Update Fields

All firmware updates use three key fields for scheduling and control:

FieldFormatDescriptionExample
fwurlString (256 max)URL path to firmware binary filehttp://fw.lockwebserv.com/...
fwDwnldTmString (14 chars)When to download the firmware"20260403020000" or "0"
fwImplTmString (14 chars)When to flash/implement the firmware"20260404030000" or "0"

Time Format: YYYYMMDDHHMMS

  • Example: "20260403020000" = April 3, 2026, 2:00:00 AM
  • Use "0" for immediate download/implementation

Why Two Timing Fields?

  • Download Time: Schedule when to download firmware (during high-bandwidth periods)
  • Implementation Time: Schedule when to flash firmware (during maintenance windows)
  • This two-stage approach minimizes service disruption

Updating Gateway Firmware

Step 1: Retrieve Available Firmware Versions

GET https://partner.lockwebserv.com/engage/firmware/gwe

Response includes firmware version and download URL.

Step 2: Command Gateway to Update

API Endpoint: PUT {{gateway_url}}/gateway/config

Request:

{
  "gatewayConfig": {
    "genGatewayConfig": {
      "fwurl": "http://fw.lockwebserv.com/firmwarecontainer/gwe_01.51.24_gw_image_v1_1.51.24.bin",
      "fwDwnldTm": "0",
      "fwImplTm": "0"
    }
  }
}

Immediate Update:

  • Set both fwDwnldTm and fwImplTm to "0"
  • Gateway downloads and flashes firmware immediately

Scheduled Update:

{
  "gatewayConfig": {
    "genGatewayConfig": {
      "fwurl": "http://fw.lockwebserv.com/firmwarecontainer/gwe_01.51.24_gw_image_v1_1.51.24.bin",
      "fwDwnldTm": "20260403020000",
      "fwImplTm": "20260404030000"
    }
  }
}

This downloads firmware at 2:00 AM on April 3rd, then implements at 3:00 AM on April 4th.

Step 3: Monitor Gateway Update Status

GET {{gateway_url}}/gateway/deviceInfo

Check response for current firmware version and update status.

Important Notes for Gateway Updates:

  • Gateway will briefly go offline during the flash process
  • All connected access control systems will lose connection temporarily
  • Schedule updates during maintenance windows to minimize disruption
  • Verify the firmware URL is correct and accessible before scheduling

Updating Lock Firmware via Gateway

The Gateway can distribute firmware updates to all linked locks.

Step 1: Retrieve Available Lock Firmware

GET https://partner.lockwebserv.com/engage/firmware/nde

Replace nde with your device model: ndeb, leb, fe410bm, fe410b, fe410, cte, rmru

Step 2: Command Locks to Update

API Endpoint: PUT {{gateway_url}}/gateway/config

Request - Single Device Model:

{
  "gatewayConfig": {
    "edgeDeviceFwUrls": [
      {
        "fwurl": "http://fw.lockwebserv.com/firmwarecontainer/nde_02.11.29_Releasepkg_02.11.29.bin",
        "mdl": "nde",
        "fwDwnldTm": "0",
        "fwImplTm": "0",
        "fwVer": "02.11.29"
      }
    ]
  }
}

Request - Multiple Device Models:

{
  "gatewayConfig": {
    "edgeDeviceFwUrls": [
      {
        "fwurl": "http://fw.lockwebserv.com/firmwarecontainer/nde_02.11.29_Releasepkg_02.11.29.bin",
        "mdl": "nde",
        "fwDwnldTm": "20260403020000",
        "fwImplTm": "20260404030000",
        "fwVer": "02.11.29"
      },
      {
        "fwurl": "http://fw.lockwebserv.com/firmwarecontainer/le_02.11.29_Releasepkg_02.11.29.bin",
        "mdl": "le",
        "fwDwnldTm": "20260403020000",
        "fwImplTm": "20260404030000",
        "fwVer": "02.11.29"
      }
    ]
  }
}

Edge Device Firmware Fields:

FieldRequiredDescriptionExample
fwurlYesFirmware binary URLhttp://fw.lockwebserv.com/...
mdlYesDevice model type"nde", "le", "control", etc.
fwVerYesFirmware version (must match binary)"02.11.29"
fwDwnldTmYesDownload schedule"0" or "20260403020000"
fwImplTmYesImplementation schedule"0" or "20260404030000"

CRITICAL: The fwVer field must exactly match the version encoded in the firmware binary filename. Mismatches will cause update failures.

Monitoring Lock Firmware Update Progress

API Endpoint: GET {{gateway_url}}/gateway/deviceInfo

Check the edgeDeviceFwUrlsextendedStatus array for per-device update status:

{
  "gatewayConfig": {
    "edgeDeviceFwUrls": [
      {
        "mdl": "nde",
        "fwVer": "02.11.29",
        "extendedStatus": [
          {
            "linkId": "door_001",
            "fwUpdateStatus": "inProgress",
            "fwTransferCmpltPercentage": 45
          },
          {
            "linkId": "door_002",
            "fwUpdateStatus": "completed",
            "fwTransferCmpltPercentage": 100
          }
        ]
      }
    ]
  }
}

Update Status Values:

  • "pendingUpdate": Waiting to start (scheduled or queued)
  • "inProgress": Currently downloading/transferring firmware
  • "completed": Successfully updated
  • "failed": Update failed (check lock logs for details)

Transfer Percentage:

  • fwTransferCmpltPercentage: 0-100 indicating download progress
  • Updates incrementally as firmware transfers over BLE

Firmware Update Workflow

Complete Update Process:

1. Retrieve firmware information from cloud API

2. Verify firmware URL is accessible

3. Schedule download time (immediate or future)

4. Schedule implementation time (immediate or future)

5. Send update command to Gateway

6. Gateway downloads firmware from URL

7. [For locks] Gateway transfers firmware to locks via BLE

8. Device implements/flashes firmware at scheduled time

9. Device reboots with new firmware

10. Verify new firmware version via deviceInfo

Scheduling Best Practices

When to Schedule Updates:

  1. Immediate Updates ("0" for both fields):

    • Testing environments
    • Critical security patches
    • Single device updates during low-traffic periods
  2. Scheduled Download, Immediate Implementation:

    {
      "fwDwnldTm": "20260403020000",  // Download at 2 AM
      "fwImplTm": "0"                 // Flash immediately after download
    }
    • Bandwidth-constrained environments
    • Want to pre-stage firmware before flashing
  3. Scheduled Download and Implementation:

    {
      "fwDwnldTm": "20260403020000",  // Download at 2 AM
      "fwImplTm": "20260404030000"    // Flash at 3 AM next day
    }
    • Production environments
    • Allows verification before implementation
    • Maximizes uptime during business hours

Recommended Timing:

  • Schedule during off-peak hours (2:00 AM - 5:00 AM)
  • Avoid business-critical times
  • Allow sufficient time between download and implementation for monitoring
  • Update locks in phases (test subset first, then full deployment)

Gateway vs Lock Update Comparison

AspectGateway UpdateLock Update
Config SectiongenGatewayConfigedgeDeviceFwUrls (array)
Model FieldNot requiredRequired (mdl)
Version FieldEmbedded in URLExplicit (fwVer)
Multiple DevicesN/A (single Gateway)Array supports multiple models
DowntimeGateway temporarily offlineIndividual locks reboot
Transfer MethodDirect from URLGateway → BLE → Lock
Cloud API Endpoint/engage/firmware/gwe/engage/firmware/{model}

Troubleshooting Firmware Updates

Gateway Update Fails:

  1. Verify firmware URL is accessible (test with curl or browser)
  2. Check Gateway has internet connectivity
  3. Ensure sufficient storage space on Gateway
  4. Verify firmware binary matches Gateway model (GWE/GWE2)
  5. Check Gateway logs for detailed error messages

Lock Update Fails:

  1. Version mismatch: Verify fwVer matches binary filename exactly
  2. BLE connectivity: Check linkCommStatus is "connected"
  3. Low battery: Locks may reject updates if battery is low
  4. Insufficient storage: Lock storage full (rare)
  5. Transfer timeout: Improve BLE signal strength or retry
  6. Model mismatch: Ensure mdl field matches actual device model

Status Remains “pendingUpdate”:

  • Check scheduled time hasn’t passed
  • Verify Gateway received the configuration
  • Ensure Gateway has connectivity to firmware URL
  • Check for queued updates (Gateway processes sequentially)

Status Shows “failed”:

  • Retrieve detailed error via device logs
  • Common causes:
    • Incorrect firmware URL (404 error)
    • Corrupted firmware binary
    • Version incompatibility
    • Interrupted transfer (connectivity loss)

Firmware Update Example: Production Deployment

Scenario: Update 50 NDE locks and 1 Gateway during weekend maintenance window.

Step 1: Update Gateway (Friday night)

{
  "gatewayConfig": {
    "genGatewayConfig": {
      "fwurl": "http://fw.lockwebserv.com/firmwarecontainer/gwe_01.51.24_gw_image_v1_1.51.24.bin",
      "fwDwnldTm": "20260404020000",  // Saturday 2:00 AM
      "fwImplTm": "20260404030000"    // Saturday 3:00 AM
    }
  }
}

Step 2: Update Locks (Saturday night)

{
  "gatewayConfig": {
    "edgeDeviceFwUrls": [
      {
        "fwurl": "http://fw.lockwebserv.com/firmwarecontainer/nde_02.11.29_Releasepkg_02.11.29.bin",
        "mdl": "nde",
        "fwDwnldTm": "20260405020000",  // Sunday 2:00 AM
        "fwImplTm": "20260405040000",   // Sunday 4:00 AM
        "fwVer": "02.11.29"
      }
    ]
  }
}

Step 3: Monitor Progress

# Saturday morning - check Gateway updated
curl http://192.168.1.100/gateway/deviceInfo

# Sunday morning - check lock updates
curl http://192.168.1.100/gateway/deviceInfo | jq '.gatewayConfig.edgeDeviceFwUrls[0].extendedStatus'

Step 4: Verify Success

  • Gateway shows new version: 01.51.24
  • All 50 locks show status: "completed"
  • All locks show new version: 02.11.29

Important Warnings

  1. Gateway Updates Cause Downtime: During Gateway firmware flash, all communication with locks is interrupted. Plan accordingly.

  2. Version Matching is Critical: For lock updates, fwVer field must match exactly. Use the exact version string from the firmware API.

  3. Test Before Production: Always test firmware updates on a subset of devices before full deployment.

  4. Backup Configurations: Document current Gateway and lock configurations before updating.

  5. Do Not Interrupt: Do not power cycle devices during firmware flash. This can brick the device.

  6. BLE Range Matters: Lock updates require stable BLE connection. Ensure good signal quality before initiating updates.

  7. Sequential Processing: Gateway processes edge device updates sequentially, not in parallel. Large deployments take time.

  8. Firmware Rollback: Firmware rollback is not typically supported. Thoroughly test new firmware before deploying.

Additional Resources

  • ONR_IP.pdf: Complete Over-the-Network Reflash documentation
  • ENGAGE Cloud API: Firmware version listings at GET https://partner.lockwebserv.com/engage/firmware/{deviceType}
  • Gateway deviceInfo endpoint: Real-time status via GET {{gateway_url}}/gateway/deviceInfo

16. Troubleshooting

Lock Not Linking to Gateway

Symptoms: Lock appears in scan list but won’t link, or linkCommStatus shows “disconnected”

Solutions:

  1. Check BLE signal strength in scan results
  2. Verify lock has fresh batteries (low battery prevents linking)
  3. Ensure lock is in range (typically <30 feet with clear line of sight)
  4. Check if lock is already linked to another Gateway (locks can only link to one Gateway)
  5. Power cycle the Gateway

Database Update Fails

Symptoms: Database update API returns error or lock doesn’t reflect changes

Solutions:

  1. Verify credential sorting: Credentials must be sorted by unencrypted value before encryption
  2. Check encryption: Ensure you’re using correct site key and AES-256 CBC with IV=0
  3. Validate JSON: Use a JSON validator to check for syntax errors
  4. Required schedules: At least one credential schedule must be present
  5. Check nxtDbVerTS: Must be a valid hex string starting with “0x”

Credentials Don’t Work at Lock

Symptoms: Valid credential is rejected, lock beeps/flashes red

Solutions:

  1. Verify credential is in database: Check user record was successfully added
  2. Check activation/expiration dates: Ensure current time is within actDtTm and expDtTm
  3. Verify schedule: Confirm current time matches assigned credential schedule
  4. Check clock sync: Lock’s RTC may be incorrect (update via rtcTime config)
  5. Reader configuration: Ensure correct credential type is enabled (e.g., proxConfHID = “T”)
  6. Encryption mismatch: Verify site key matches what lock was commissioned with

Slow Credential Response

Symptoms: Lock takes several seconds to respond to credential presentation

Root Cause: Database is not properly sorted, causing linear search instead of binary search

Solution:

  1. Verify credential sort order before encryption
  2. Rebuild database with proper sorting
  3. See Credential Sort and Encryption document for detailed sorting algorithm

Gateway Offline or Unreachable

Symptoms: Cannot connect to Gateway IP address

Solutions:

  1. Check physical Ethernet connection
  2. Verify Gateway has power (check LED indicators)
  3. Confirm IP address with network scan: nmap -sn 192.168.1.0/24
  4. Check DHCP server logs for Gateway MAC address
  5. Try factory reset if Gateway is unresponsive (consult hardware manual)

Audit Events Not Reporting

Symptoms: Lock generates events but they don’t appear in API responses

Solutions:

  1. Ensure lock is connected to Gateway (linkCommStatus = “connected”)
  2. Check if lock’s audit buffer is full (retrieve audits to clear buffer)
  3. Verify Gateway can communicate with your host system
  4. For 410-IP mode, confirm immediate alerts are configured if needed

17. Best Practices

Security

  1. Protect Site Keys: Store site keys securely, never in plain text or version control
  2. Use HTTPS: Always use HTTPS for Gateway communication in production
  3. Unique Credentials: Never reuse credential values across multiple users
  4. Avoid 0xFFFFFFFF: This value is reserved and cannot be used as a credential
  5. Regular Audits: Review audit logs regularly for suspicious activity

Performance

  1. Sort Credentials: Always sort before encryption for optimal lock performance
  2. Batch Updates: Use partial database updates instead of full replacements when possible
  3. Limit Database Size: Keep user databases under 5,000 users per lock for best performance
  4. Schedule Sync: Sync lock clocks regularly to prevent schedule drift
  5. Monitor Battery: Replace batteries before they reach critical level

Reliability

  1. Gateway Redundancy: Consider deploying backup Gateways for mission-critical doors
  2. Failsafe Configuration: Set appropriate gatewayCommFail mode (recommend “sec”)
  3. Test Regularly: Periodically test credentials and schedules
  4. Monitor Signal Quality: Ensure strong BLE signal between Gateway and locks
  5. Keep Firmware Updated: Apply firmware updates during maintenance windows

Development Workflow

  1. Use Postman Collections: Build comprehensive test suites
  2. Test Environments: Use separate Gateways/locks for development vs. production
  3. Version Control: Track nxtDbVerTS values to maintain database history
  4. Error Handling: Implement robust error handling for API failures
  5. Logging: Log all API interactions for troubleshooting

18. Common Integration Patterns

Pattern 1: New User Enrollment

// Pseudo-code for enrolling a new user

// 1. Get card number from enrollment reader
const cardNumber = readCard(); // e.g., 0x23C5981

// 2. Encode credential
const encoded = encodeCredential(cardNumber, 26); // Shift & pad
// Result: 0x8F166040FFFFFFFFFFFFFFFFFFFFFFFF

// 3. Get all existing credentials from database
const existingUsers = await getExistingDatabase();

// 4. Add new user to list
const newUser = {
  usrID: getNextUserId(),
  primeCr: encoded, // Not yet encrypted
  prCrTyp: "card",
  scndCrTyp: "null",
  // ... other fields
};
existingUsers.push(newUser);

// 5. Sort by unencrypted value
existingUsers.sort((a, b) => 
  BigInt("0x" + a.primeCr) - BigInt("0x" + b.primeCr)
);

// 6. Encrypt all credentials
existingUsers.forEach(user => {
  user.primeCr = encryptCredential(user.primeCr, SITE_KEY);
});

// 7. Send to lock
await updateLockDatabase(existingUsers);

Pattern 2: Temporary Access

// Grant access for 24 hours

const tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);

const tempUser = {
  usrID: 9999,
  primeCr: encryptedCredential,
  prCrTyp: "card",
  scndCrTyp: "null",
  fnctn: "oneTm", // One-time use
  crSch: [1],
  actDtTm: formatDateTime(new Date()),
  expDtTm: formatDateTime(tomorrow)
};

await addUser(tempUser);

Pattern 3: Emergency Lockdown

// Put all doors in secure lockdown mode

const lockdownHoliday = {
  strtDtTm: formatDateTime(new Date()),
  endDtTm: "21351231235959", // Far future
  action: "rstrctSec" // Only freeze/passthrough work
};

await Promise.all(
  allDoors.map(door => 
    updateHolidays(door, [lockdownHoliday])
  )
);

Pattern 4: Schedule-Based Access

// Office hours + after-hours with 2FA

const schedules = [
  {
    // Schedule 1: 24/7 (for admins)
    days: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"],
    strtHr: 0,
    strtMn: 0,
    lngth: 1439,
    auth: "1f"
  },
  {
    // Schedule 2: Business hours (9-5)
    days: ["Mo", "Tu", "We", "Th", "Fr"],
    strtHr: 9,
    strtMn: 0,
    lngth: 480,
    auth: "1f"
  },
  {
    // Schedule 3: After hours (requires 2FA)
    days: ["Mo", "Tu", "We", "Th", "Fr"],
    strtHr: 17,
    strtMn: 0,
    lngth: 960,
    auth: "2f"
  }
];

// Admin user gets schedule 1
const adminUser = {
  usrID: 1,
  crSch: [1],
  ...
};

// Regular employee gets schedules 2 & 3
const employeeUser = {
  usrID: 100,
  primeCr: encryptedCard,
  prCrTyp: "card",
  scndCrTyp: "pin", // Has both card and PIN
  crSch: [2, 3], // Business hours + after hours
  ...
};

19. Advanced Topics

Multi-Factor Authentication

ENGAGE supports four authentication modes:

{
  "schedules": [
    {
      "auth": "1f",
      ...
    }
  ]
}
  • 1f (Single Factor): Card OR PIN
  • 2f (Two Factor): Card AND PIN (same user)
  • 1fx2 (Single Factor x2): Two different users each present card OR PIN
  • 2fx2 (Two Factor x2): Two different users each present card AND PIN

Example 2f credential:

{
  "usrID": 50,
  "primeCr": "ENCRYPTED_CARD_AND_PIN",
  "prCrTyp": "card",
  "scndCrTyp": "pin",
  "crSch": [5] // Schedule 5 has auth: "2f"
}

Extended Credential Schedules

Reader-controllers (RC) support up to 32 extended schedules with 32 intervals each:

{
  "schedulesExt": [
    {
      "extScheduleID": 1,
      "intvlID": 1,
      "moStrt": "0800",
      "moEnd": "1700",
      "moAuth": "1f",
      "tuStrt": "0000",
      "tuEnd": "2400",
      "tuAuth": "2f"
    }
  ]
}

Enable with: "extSchedEn": "T"

GPIO Configuration

Configure general purpose inputs/outputs on CT controllers:

{
  "config": {
    "gpi": [
      {
        "iType": "rex",
        "iEn": "T",
        "pol": "high"
      },
      {
        "iType": "dps",
        "iEn": "T",
        "pol": "high"
      }
    ],
    "gpo": [
      {
        "oType": "ttl1",
        "oEn": "T",
        "pol": "low",
        "mode": "puls",
        "src": ["rex"]
      }
    ]
  }
}

HMAC Message Authentication

For enhanced security, enable HMAC authentication:

{
  "config": {
    "asmEn": "T",
    "asmKey": "36353136"
  }
}

Reference: JSON Data Structures document, page 38.

20. Websockets - Gateway as Client

In most 410-IP deployments, the Gateway acts as a server and your access control system connects to it. However, in some architectures, you may want the Gateway to act as a websocket client that initiates connections to a remote server.

When to Use Client Mode

Use hostProtocol: "ipClient" when:

  • Your access control system is cloud-based or behind a firewall
  • You want the Gateway to initiate outbound connections
  • Your network security policies prevent inbound connections to the Gateway
  • You need to connect multiple distributed Gateways to a centralized server

Configuration

{
  "gatewayConfig": {
    "genGatewayConfig": {
      "hostProtocol": "ipClient",
      "deviceName": "Main-Building-Gateway"
    },
    "gatewayIpModeConfig": {
      "ipServerURL": "https://your-server.com/api/engage",
      "caServerURL": "https://your-server.com/api/ca",
      "wsKeepAlive": "60"
    }
  }
}

Client Mode Parameters

ParameterDescription
ipServerURLWebsocket endpoint for ENGAGE API communication
caServerURLWebsocket endpoint for credential authority operations
wsKeepAliveKeepalive interval in seconds (default: 60)

Important Considerations

  1. Server Requirements: Your remote server must support websocket connections and implement the ENGAGE JSON API protocol
  2. Connection Persistence: The Gateway will maintain persistent websocket connections and automatically reconnect if dropped
  3. Latency: Client mode may introduce additional latency compared to direct server mode
  4. Firewall: Ensure outbound HTTPS/WSS connections are allowed on your network

Additional Resources

  • Schlage ENGAGE WebSockets App Note: Complete WebSocket implementation guide
  • Sample Gateway Client Websockets Integration: Reference implementation and examples
  • ENGAGE JSON Data Structures: Gateway configuration options (pages 57-65)

21. Reference Documentation

Primary References

  1. ENGAGE_SAM_API_Integration_2.37.pdf

    • Complete API specification
    • RESTful endpoints and request/response formats
    • Authentication and connection protocols
    • 72 pages of detailed API documentation
  2. ENGAGE_JSON_Data_Structures - 2.18.pdf

    • Comprehensive JSON tag definitions
    • Database, configuration, audit, and status structures
    • Device-specific parameters and exclusions
    • Gateway and edge device data structures
  3. Schlage ENGAGE Credential Sort and Encryption-1.34.pdf

    • Credential encoding methodology
    • Sorting algorithm specification
    • AES-256 CBC encryption details
    • Worked examples with actual values
  4. ENGAGE - Audits - 0.23.xlsm

    • Complete audit event codes and descriptions
    • Alert definitions and categories
    • Database, configuration, and lock status audit events
    • Excel reference for all audit codes

Training Presentations

  1. 01 - Allegion Engage Integrations - System architecture overview
  2. 02 - Creating Engage Accounts and using Mobile App - Account setup and mobile app usage
  3. 03 - What are json files and further postman usage - JSON basics and Postman testing
  4. 04 - Examining Card Data - Understanding card formats and encoding
  5. 05 - More on PrimeCR and advanced gateway lock communication - Advanced credential topics

Postman Collections

Complete API testing collections for both ENGAGE Cloud API and Gateway API:

  1. Allegion APIs.postman_collection_11-6-2019.json

    • ENGAGE Cloud API: Site registration, device management, firmware listings
    • Gateway API: Lock data, configuration, audits, lock control, network settings
    • Pre-configured requests with example JSON payloads
    • Organized by endpoint category for easy navigation
  2. allegionApiEnvironment.postman_environment-10_18_2022.json

    • Environment template with variables for:
      • Gateway IP addresses
      • Authentication credentials
      • Site references and site keys
      • Device IDs and link IDs
    • Easily manage multiple environments (dev, test, production)

Import Instructions:

  1. Download both JSON files
  2. In Postman: File → Import → Select both files
  3. Select the “Allegion API Environment” from the environment dropdown (top-right)
  4. Click the eye icon to edit environment variables
  5. Update with your specific values:
    • gateway_ip: Your Gateway’s IP address (e.g., 192.168.1.100)
    • gateway_username: Auto-generated Gateway username
    • gateway_password: Auto-generated Gateway password
    • cloud_username: Your ENGAGE account email
    • cloud_password: Your ENGAGE account password
    • site_reference: Your site GUID from site creation
    • site_key: Your site encryption key (hex format)
  6. Save the environment
  7. Browse the collection and execute requests

Quick Reference Tables

Device Models

Model CodeDescription
ndeENGAGE Wireless Cylindrical Lock
ndebNDE with BLE credential capability
leENGAGE Wireless Mortise Lock
lebLE with BLE credential capability
controlSchlage Deadbolt/Interconnected Lock (BE467/FE410)
controlbControl with BLE credential capability
cteENGAGE Controller
rcReader-Controller (RC11/RC15)

Credential Functions

FunctionDescription
normNormal unlock with relock delay
toggleToggle between locked/unlocked
freezeDisable reader until freeze presented again
passThruAlways unlock even in lockdown
lockDownPut lock in secure mode
oneTmOne-time use credential

Door Modes

ModeDescription
strmStoreroom (always locked, no interior unlock)
officeOffice (unlocked from inside, locked outside)
aptApartment (privacy function)
prvcyPrivacy (inside lock/unlock button)

See also: Door Modes - Functions Explanation and State Change Table for Apartment Mode


22. Next Steps

For Development

  1. Set up test environment:

    • Install Gateway on test network
    • Link 1-2 test locks
    • Configure Postman collection
  2. Implement credential encoding:

    • Write encoding function for your card format
    • Implement AES-256 encryption
    • Create sorting algorithm
  3. Build database management:

    • Create user CRUD operations
    • Implement schedule management
    • Add holiday/auto-unlock support
  4. Test thoroughly:

    • Test various credential types
    • Verify schedules work correctly
    • Test error conditions

For Production

  1. Security hardening:

    • Enable HTTPS for Gateway communication
    • Secure site key storage
    • Implement HMAC authentication
  2. Monitoring and alerting:

    • Set up audit log collection
    • Configure real-time alerts
    • Monitor Gateway/lock health
  3. Documentation:

    • Document your integration architecture
    • Create runbooks for common operations
    • Train support staff
  4. Scaling:

    • Plan Gateway coverage for all doors
    • Consider redundancy for critical access points
    • Optimize database update strategies

23. Getting Help

Resources

  • Technical Documentation: See references in Section 18
  • API Specification: ENGAGE_SAM_API_Integration_2.37.pdf
  • Training Materials: Presentations in ip-gateway-info/Slideshows for engage training/

Common Issues

Before contacting support, check:

  • Troubleshooting section (Section 16)
  • Gateway and lock firmware versions are up to date
  • Network connectivity between Gateway and your host system
  • BLE signal strength between Gateway and locks
  • Site key is correct and matches lock commissioning

Contacting Support

When contacting Allegion support, have ready:

  • Gateway model and firmware version
  • Lock models and firmware versions
  • Network topology diagram
  • Sample API requests/responses showing the issue
  • Relevant audit logs

Appendix A: Credential Encoding Examples

Example 1: 26-bit Wiegand

Card Number: Facility Code 123, Card Number 45678

Combined Value: 0x1EC56E (26 bits)

Encoding:

1. Raw: 0x1EC56E
2. Shift left 6: 0x7B15B800
3. Pad primary: 0x7B15B800FFFFFFFF
4. Pad secondary: 0xFFFFFFFFFFFFFFFF
5. Combined PrimeCr: 0x7B15B800FFFFFFFFFFFFFFFFFFFFFFFF
6. Encrypt with site key: [encrypted result]

Example 2: Card + PIN (Two-Factor)

Card: 26-bit, value 0x23C5981 PIN: 6-digit, value 823456

Encoding:

Primary (card):
  1. Raw: 0x23C5981
  2. Shift left 6: 0x8F166040
  3. Pad: 0x8F166040FFFFFFFF

Secondary (PIN):
  1. Raw: 823456 decimal = 0xC9150
  2. Shift to fit: 0x00C91500
  3. Pad: 0x00C91500FFFFFFFF

Combined: 0x8F166040FFFFFFFF00C91500FFFFFFFF
Encrypted: [result depends on site key]

Example 3: PIN-Only Credential

PIN: 123456

Encoding:

Primary (PIN):
  1. 123456 decimal = 0x1E240
  2. Shift: 0x001E2400
  3. Pad: 0x001E2400FFFFFFFF

Secondary (null):
  Pad: 0xFFFFFFFFFFFFFFFF

Combined: 0x001E2400FFFFFFFFFFFFFFFFFFFFFFFF
Encrypted: [result depends on site key]

JSON:
{
  "prCrTyp": "pin",
  "scndCrTyp": "null",
  "primeCr": "[encrypted value]"
}

Appendix B: JSON Complete Database Example

{
  "edgeDevice": [
    {
      "linkId": "main_entrance",
      "db": {
        "usrRcrd": {
          "deleteAll": 1,
          "delete": [],
          "update": [],
          "add": [
            {
              "usrID": 1,
              "adaEn": 0,
              "fnctn": "norm",
              "crSch": [1],
              "actDtTm": "20260101000000",
              "expDtTm": "20261231235959",
              "primeCr": "34110EA549AA549AA73FF06DC93B63B4",
              "prCrTyp": "card",
              "scndCrTyp": "null"
            },
            {
              "usrID": 2,
              "adaEn": 1,
              "fnctn": "norm",
              "crSch": [1, 2],
              "actDtTm": "20260101000000",
              "expDtTm": "20261231235959",
              "primeCr": "45220FB65ABB65ABB84GG17ED04C74C5",
              "prCrTyp": "card",
              "scndCrTyp": "pin"
            }
          ]
        },
        "schedules": [
          {
            "days": ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"],
            "strtHr": 0,
            "strtMn": 0,
            "lngth": 1439,
            "auth": "1f"
          },
          {
            "days": ["Mo", "Tu", "We", "Th", "Fr"],
            "strtHr": 8,
            "strtMn": 0,
            "lngth": 540,
            "auth": "1f"
          }
        ],
        "holidays": [
          {
            "strtDtTm": "20260704000000",
            "endDtTm": "20260705000000",
            "action": "pass"
          },
          {
            "strtDtTm": "20261225000000",
            "endDtTm": "20261226000000",
            "action": "pass"
          }
        ],
        "autoUnlock": [
          {
            "action": "pass",
            "strtHr": 8,
            "strtMn": 0,
            "days": ["Mo", "Tu", "We", "Th", "Fr"]
          },
          {
            "action": "sec",
            "strtHr": 17,
            "strtMn": 0,
            "days": ["Mo", "Tu", "We", "Th", "Fr"]
          }
        ]
      },
      "config": {
        "name": "Main Entrance",
        "type": "office",
        "relock": 5,
        "doorProp": 30,
        "ada": 10,
        "gatewayCommFail": "sec",
        "tamperFail": "sec",
        "rtcTime": "20260401120000"
      },
      "nxtDbVerTS": "0x0000000000000001"
    }
  ]
}

Conclusion

This guide has covered the essential concepts and procedures for integrating with Schlage ENGAGE devices using Gateway IP mode. Key takeaways:

  1. Understand the architecture: Gateway bridges IP network to BLE locks
  2. Encode credentials properly: Shift, pad, sort, then encrypt
  3. Always sort before encryption: Critical for lock performance
  4. Test thoroughly: Use Postman to validate your integration
  5. Monitor and maintain: Review audits, update firmware, maintain security

With proper implementation, the ENGAGE Gateway IP mode provides a robust, scalable access control solution. Refer to the detailed technical documentation for advanced features and edge cases.

Happy integrating!