Skip to content
OAOpenAppPhysical Security as a Service
Login

Devices

Device operations live under the Devices tag in the canonical OpenAPI bundle (operationId values below). Responses are DeviceResponse (or lists/pagination wrappers) unless noted — see schemas in the API reference.

Organization scope, X-Org, output_options, and pagination are required on several routes exactly as documented in OpenAPI. Start with Organization context & pagination before calling org-scoped device APIs.

ConcernHTTPoperationIdNotes
ListGET /deviceslist_devicesRequires X-Org, output_options, pagination; optional filters (integration_id, device_kind, q, …).
CreatePOST /devicescreate_deviceBody matches CreateDeviceRequest (see bundle). X-Org header required.
GetGET /devices/{id}get_deviceRequires X-Org and output_options query.
UpdatePUT /devices/{id}update_device
Soft deleteDELETE /devices/{id}delete_device
RestorePOST /devices/{id}/restorerestore_device
Hard deleteDELETE /devices/{id}/purgehard_delete_device
Door restrictionsGET /devices/{id}/door-restrictionsget_door_restrictions400 if the device is not a virtual_access_portal; 404 if missing.
Metadata schemaGET /devices/{id}/metadata-definitionget_device_metadata_definitionRequires X-Org.
CapabilityPythonRust (openapp_sdk)GoTypeScript (AsyncClient)
List / CRUD + purge / restoreclient.devices.*client.devices() thin JSON helpersFull generated DevicesAPIlistDevices facade only (GET /devices); no typed CRUD helpers yet
Filters & pagination on listlist(..., org_id=, integration_id=, …)High-level list() sends bare GET /devices — use transport() + RequestSpec for full OpenAPI query/header parityListDevices builderParameter reserved; wire call does not send X-Org — prefer Python or Go for full control
Imagesupload_image, upload_image_from_urlUse transport or RESTGenerated operationsNot exposed on façade

For Python-only image uploads and scripting patterns, see Python — Resources.

In addition to 401 (bad or missing API key), device routes commonly return 403 (role/org mismatch), 404 (unknown id), or 400 (validation / wrong device kind, e.g. door restrictions on non-portals). Shapes follow ApiErrorResponse — see Errors & retries.

devices.list forwards query params to list_devices. Pass org_id so the bridge can align org context with the wire contract where your deployment expects it.

page = await client.devices.list(
org_id="01HORG00000000000000000000",
integration_id="01HINT00000000000000000000",
limit=50,
)

CreateDeviceRequest requires org_id, integration_id, and name (localized map). X-Org must match the org you are creating in.

device = await client.devices.create(
org_id="01HORG00000000000000000000",
integration_id="01HINT00000000000000000000",
name={"en": "LAN controller"},
)

Ensure the bridge sends X-Org for this route (same org_id as in the body is typical).

device = await client.devices.get("01HDEV00000000000000000000")
updated = await client.devices.update(
"01HDEV00000000000000000000",
name={"en": "Front door"},
)
await client.devices.delete("01HDEV00000000000000000000")
restored = await client.devices.restore("01HDEV00000000000000000000")
await client.devices.purge("01HDEV00000000000000000000")
rules = await client.devices.door_restrictions("01HDEV00000000000000000000")
await client.devices.set_door_restrictions(
"01HDEV00000000000000000000",
apartment_entity_ids=["01JENT00000000000000000000"],
)
schema = await client.devices.metadata_definition("01HDEV00000000000000000000")