Skip to content

Access Control

Manage Rhombus access control through the API — list access-controlled doors, remotely unlock, issue and assign credentials, build access groups and grants, and activate lockdown plans.

On this page

Overview

Rhombus access control lets you manage physical entry across your facilities from a single API. Access-controlled doors are backed by Rhombus door controllers and readers, and every unlock, credential, and grant is tied to the same platform that records your camera footage — so each entry event has visual context.

Through the API, you can:

  • List access-controlled doors and inspect their configuration and live state
  • Remotely unlock a door for a momentary entry
  • Issue credentials (such as Wiegand cards) and assign them to users
  • Build access groups and grants that tie users, doors, and schedules together
  • Activate lockdown plans to secure a location during an emergency

Prerequisites

All requests are POST, target the base URL https://api2.rhombussystems.com, and require these headers:

bash
x-auth-scheme: api-token
x-auth-apikey: YOUR_API_KEY
Content-Type: application/json

List access-controlled doors

Retrieve the access-controlled doors in your organization. The response is paginated: pass an empty body for the first page, then send the returned lastEvaluatedKey on subsequent requests until it comes back empty.

import requests

headers = {
    "x-auth-scheme": "api-token",
    "x-auth-apikey": "YOUR_API_KEY",
    "Content-Type": "application/json"
}

response = requests.post(
    "https://api2.rhombussystems.com/api/component/findAccessControlledDoors",
    headers=headers,
    json={
        "maxPageSize": 100
    }
)

data = response.json()
for door in data.get("accessControlledDoors", []):
    print(f"{door['name']} ({door['uuid']}) - default state: {door.get('defaultState')}")

# Paginate if more doors remain
next_key = data.get("lastEvaluatedKey")

Request parameters

maxPageSizeintegerpath

Maximum number of doors to return in a single page.

lastEvaluatedKeystringpath

Pagination cursor returned by a previous call. Omit it on the first request; supply it to fetch the next page.

Response

accessControlledDoorsarray

The list of access-controlled doors. Key fields per door:

Show door fields
uuidstring

Unique identifier for the door. Use this value wherever an accessControlledDoorUuid is required.

namestring

Display name of the door (for example, "Main Entrance").

locationUuidstring

The location the door belongs to.

defaultStatestring

Baseline access mode, one of ACCESS_CONTROLLED or UNLOCKED.

remoteUnlockEnabledboolean

Whether the door accepts remote unlock requests through the API.

unlockTimeSecinteger

How long the door stays unlocked after a standard unlock, in seconds.

lastEvaluatedKeystring

Pagination cursor. When present, pass it back in the next request to retrieve additional doors.

Tip

If you only need lightweight door status rather than full configuration, use /api/component/findMinimalStateAccessControlledDoors, which returns each door plus a compact state shadow.

Remotely unlock a door

Trigger a momentary unlock on an access-controlled door. The door relocks automatically after its configured unlock time. Remote unlock only works when remoteUnlockEnabled is true for the target door.

import requests

headers = {
    "x-auth-scheme": "api-token",
    "x-auth-apikey": "YOUR_API_KEY",
    "Content-Type": "application/json"
}

response = requests.post(
    "https://api2.rhombussystems.com/api/accesscontrol/unlockAccessControlledDoor",
    headers=headers,
    json={
        "accessControlledDoorUuid": "YOUR_DOOR_UUID"
    }
)

result = response.json()
print(result.get("type"))  # SUCCESS or ERROR
accessControlledDoorUuidstringpathrequired

The UUID of the door to unlock, from the door listing endpoint.

typestring

Outcome of the request, either SUCCESS or ERROR.

Issue and assign a credential

Credentials are the physical cards or fobs that a reader accepts. This example creates a Wiegand credential and assigns it to a user. Rhombus supports several credential formats — the createWiegandCredential endpoint takes a wiegandFormat and the fields relevant to that format.

Create a Wiegand credential

import requests
import time

headers = {
    "x-auth-scheme": "api-token",
    "x-auth-apikey": "YOUR_API_KEY",
    "Content-Type": "application/json"
}

now_sec = int(time.time())
one_year_sec = 365 * 24 * 60 * 60

response = requests.post(
    "https://api2.rhombussystems.com/api/accesscontrol/createWiegandCredential",
    headers=headers,
    json={
        "wiegandFormat": "H10301",
        "facilityCode": 42,
        "cardNumber": 10537,
        "userUuid": "YOUR_USER_UUID",
        "startDateEpochSecInclusive": now_sec,
        "endDateEpochSecExclusive": now_sec + one_year_sec
    }
)

credential = response.json().get("credential", {})
print(f"Created credential {credential.get('uuid')} - status {credential.get('workflowStatus')}")
wiegandFormatstringpathrequired

The Wiegand card format. One of H10301, D10202, H10304, HID_CORP1000_STD_35, HID_CORP1000_STD_48, WIEGAND_64BIT_RAW, or CUSTOM. The fields you populate depend on the format — for the standard 26-bit H10301 format, supply facilityCode and cardNumber.

facilityCodeintegerpath

Facility (site) code encoded on the card. Used by formats such as H10301.

cardNumberintegerpath

Card number encoded on the card.

siteCodeintegerpath

Site code, used by formats that encode one separately from the facility code.

companyIdintegerpath

Company ID, used by HID Corporate 1000 formats.

valuestringpath

Raw credential value. Used by the WIEGAND_64BIT_RAW and CUSTOM formats.

userUuidstringpath

The user the credential belongs to. When set, the credential is created already assigned to that user.

startDateEpochSecInclusiveintegerpath

Start of the credential's validity window, in epoch seconds (inclusive).

endDateEpochSecExclusiveintegerpath

End of the credential's validity window, in epoch seconds (exclusive).

Warning

Credential validity dates are expressed in epoch seconds, not milliseconds. Most other Rhombus endpoints use epoch milliseconds, so convert carefully.

The response returns the created credential object, including its uuid, lowercaseHexValue, and workflowStatus (ACTIVE, UNASSIGNED, SUSPENDED, or REVOKED).

Assign an existing credential to a user

If a credential already exists (for example, it was created unassigned), assign it to a user by its hex value.

import requests

headers = {
    "x-auth-scheme": "api-token",
    "x-auth-apikey": "YOUR_API_KEY",
    "Content-Type": "application/json"
}

response = requests.post(
    "https://api2.rhombussystems.com/api/accesscontrol/assignAccessControlCredential",
    headers=headers,
    json={
        "credentialHexValue": "002a2929",
        "userUuid": "YOUR_USER_UUID"
    }
)
print(response.json())
credentialHexValuestringpathrequired

The hex value of the credential to assign.

userUuidstringpathrequired

The user to assign the credential to.

Grant access with groups and schedules

Rhombus models "who can open which doors, and when" as an access grant. A grant links a set of users (directly or through access groups) to a set of doors, optionally constrained by a schedule. The typical flow is: create a group, add users, then create a grant that ties the group to doors and a schedule.

Create an access group and add users

import requests

headers = {
    "x-auth-scheme": "api-token",
    "x-auth-apikey": "YOUR_API_KEY",
    "Content-Type": "application/json"
}

# Create the group
create = requests.post(
    "https://api2.rhombussystems.com/api/accesscontrol/createAccessControlGroup",
    headers=headers,
    json={
        "name": "Warehouse Staff",
        "description": "Employees allowed into the warehouse"
    }
)
group_uuid = create.json()["group"]["uuid"]

# Add users to it
requests.post(
    "https://api2.rhombussystems.com/api/accesscontrol/addUsersToAccessControlGroup",
    headers=headers,
    json={
        "groupUuid": group_uuid,
        "userUuids": ["USER_UUID_1", "USER_UUID_2"]
    }
)
namestringpathrequired

Name of the access group.

descriptionstringpath

Optional description of the group.

userUuidsarraypath

Optional list of user UUIDs to seed the group with at creation time. You can also add members later with addUsersToAccessControlGroup.

(Optional) Create a weekly schedule

To restrict a grant to specific hours, first create a schedule and reference its UUID in the grant. Weekly schedules use the WEEKLY_REPEATING_MINUTES strategy.

import requests

headers = {
    "x-auth-scheme": "api-token",
    "x-auth-apikey": "YOUR_API_KEY",
    "Content-Type": "application/json"
}

response = requests.post(
    "https://api2.rhombussystems.com/api/schedule/createWeeklySchedule",
    headers=headers,
    json={
        "schedule": {
            "name": "Business Hours",
            "strategy": "WEEKLY_REPEATING_MINUTES"
        }
    }
)
schedule_uuid = response.json().get("scheduleUuid")
print(schedule_uuid)

The response returns a scheduleUuid. Use /api/schedule/getSchedules and /api/schedule/getScheduleDataV2 to review schedules, and manage the detailed weekly time intervals in the Rhombus Console.

Create the access grant

Tie the group, doors, and (optionally) a schedule together. Use mode DEFAULT for a standard access grant.

import requests

headers = {
    "x-auth-scheme": "api-token",
    "x-auth-apikey": "YOUR_API_KEY",
    "Content-Type": "application/json"
}

response = requests.post(
    "https://api2.rhombussystems.com/api/accesscontrol/createAccessGrant",
    headers=headers,
    json={
        "accessGrant": {
            "name": "Warehouse Staff - Business Hours",
            "locationUuid": "YOUR_LOCATION_UUID",
            "mode": "DEFAULT",
            "groupUuids": ["GROUP_UUID"],
            "accessControlledDoorUuids": ["DOOR_UUID_1", "DOOR_UUID_2"],
            "scheduleUuid": "SCHEDULE_UUID"
        }
    }
)

data = response.json()
if data.get("error"):
    print("Error:", data.get("errorMsg"))
else:
    print("Created grant:", data["accessGrant"]["uuid"])
accessGrant.namestringpath

Human-readable name for the grant.

accessGrant.locationUuidstringpath

The location the grant applies to.

accessGrant.modestringpath

Grant mode, one of DEFAULT or GUEST_PASS_INDIVIDUAL. Use DEFAULT for standard employee access.

accessGrant.groupUuidsarraypath

Access groups whose members receive access. Combine with userUuids to grant individual users directly.

accessGrant.userUuidsarraypath

Individual users to grant access to, in addition to any groups.

accessGrant.accessControlledDoorUuidsarraypath

The doors this grant opens. You can also target doors by label with doorLabelIds.

accessGrant.scheduleUuidstringpath

Optional schedule that constrains when the grant is active. Omit for 24/7 access.

accessGrantobject

The created grant, including its generated uuid.

errorboolean

true if the grant could not be created. Check errorMsg for details and warningMsg for non-fatal notes.

Activate a lockdown plan

Lockdown plans let you instantly change the access state of many doors at a location during an emergency. First list the plans configured for your organization, then activate one or more for a location.

Find available lockdown plans

import requests

headers = {
    "x-auth-scheme": "api-token",
    "x-auth-apikey": "YOUR_API_KEY",
    "Content-Type": "application/json"
}

response = requests.post(
    "https://api2.rhombussystems.com/api/accesscontrol/lockdownPlan/findLockdownPlans",
    headers=headers,
    json={}
)
for plan in response.json().get("lockdownPlans", []):
    print(f"{plan.get('name')}: {plan.get('uuid')}")

Activate lockdown for a location

import requests
import time

headers = {
    "x-auth-scheme": "api-token",
    "x-auth-apikey": "YOUR_API_KEY",
    "Content-Type": "application/json"
}

response = requests.post(
    "https://api2.rhombussystems.com/api/accesscontrol/lockdownPlan/activateLockdownForLocation",
    headers=headers,
    json={
        "locationUuid": "YOUR_LOCATION_UUID",
        "lockdownPlanUuids": ["LOCKDOWN_PLAN_UUID"],
        "stateUpdatedAtMillis": int(time.time() * 1000)
    }
)

data = response.json()
print("Result:", data.get("result"))
print("Location state:", data.get("state", {}).get("state"))
locationUuidstringpathrequired

The location to place into lockdown.

lockdownPlanUuidsarraypathrequired

The lockdown plans to activate. Use UUIDs from findLockdownPlans.

stateUpdatedAtMillisintegerpathrequired

The current lockdown state timestamp in epoch milliseconds, used for optimistic concurrency. Pass the current time when initiating a lockdown.

resultstring

Outcome of the activation, one of SUCCESS, INVALID_LOCKDOWN_PLANS, or OPTIMISTIC_CONCURRENCY.

stateobject

The location's resulting lockdown state, including state (STANDARD_SECURITY or LOCKED_DOWN) and the list of activeLockdownPlans.

Warning

Activating a lockdown changes physical access at the location immediately. Test your integration with /api/accesscontrol/lockdownPlan/enableLockdownTestModeForLocation before using it in production, and end a lockdown with /api/accesscontrol/lockdownPlan/deactivateLockdownForLocation.

Use cases

Remote entry for visitors

Let front-desk software unlock a door on demand when a visitor is verified, with camera footage attached to every unlock.

Automated onboarding

Provision a new hire's badge and group membership from your HR system so their access is ready on day one.

Contractor time windows

Issue credentials with explicit start and end dates, and constrain access to business hours with a schedule.

Emergency lockdown

Wire a panic button or safety system to activate a lockdown plan across a location in a single API call.

Troubleshooting

Remote unlock returns ERROR

Confirm the door has remoteUnlockEnabled set to true in the door listing response, that the accessControlledDoorUuid is correct, and that your API key has access control permissions. Doors that are offline cannot be unlocked remotely.

Credential is created but access is denied

Creating and assigning a credential is not enough on its own — the user must also fall under an access grant that covers the target door. Verify a DEFAULT grant links the user (directly or via a group) to the door, and that any attached schedule is currently active. Also confirm the credential's workflowStatus is ACTIVE and the current time falls within its start/end window.

Credential validity dates behave unexpectedly

startDateEpochSecInclusive and endDateEpochSecExclusive use epoch seconds, not milliseconds. If a credential expires immediately or never activates, check that you did not pass a millisecond value.

Lockdown activation returns OPTIMISTIC_CONCURRENCY

The location's lockdown state changed between your read and your write. Re-fetch the current state (for example, with getOrCreateLocationLockdownState), then retry the activation with an updated stateUpdatedAtMillis.

Access grant response has error set to true

Inspect errorMsg in the response. Common causes are referencing a door that has no available access control license (see unassignedACDLicensesDoorUuids and expiredACDLicensesDoorUuids in the response) or an invalid locationUuid.

Next steps