Many APIs relate to Building Management but some basic calls that are very useful include:
Building Management
The /buildings endpoint supports GET to fetch a list of buildings and building Id values or POST to create a Building if so privileged. Further, with a given building Id, one can call PUT or PATCH on the endpoint /buildings/<id> to make changes.
Issue Types
For Work Orders, work is categorized into specific Issue Types and Categories which are defined by the Account over the set of Buildings. Each Building has associated to it a relevant subset of these types. These can be fetched with the call:
GET /buildings/<id>/issue_types
TODO: reference the reference
The result is a JSON-encoded array of objects with nested children representing the parent-child relations of Issue Types and sub-types. For each object, the data includes:
- id – The GUID value of the Issue Type used in requests
- name – The name of this type; the name should be used in conjunction with the names of the parent type as in “Cleaning / Cleaning – After Hours”
- description – A more detailed description of the type
- assignable – A true/false value representing if this type can be used or should only be a parent of other, subordinate types
- hidden – A true/false value allowing the type to be associated with the building but generally hidden from tenant views for assignment
A short example of an Issue Type result follows:
[
{
"id": "046e2b11-9c27-443f-959e-0b5fd49d200a",
"name": "Cleaning",
"description": "Cleaning",
"assignable": false,
"hidden": false,
"priority": 3,
"children": [
{
"id": "3a1b9496-0891-4755-adae-e3b9892db1bf",
"created_at": "2018-12-09T00:52:27.864309Z",
"updated_at": "2018-12-09T00:52:27.864341Z",
"name": "Cleaning - After Hours",
"description": "Cleaning - After Hours",
"assignable": true,
"hidden": false,
"priority": 3,
"parent": "046e2b11-9c27-443f-959e-0b5fd49d200a"
},
{
"id": "a6f41d2e-d561-4a6a-b741-0dd1309cbb63",
"created_at": "2018-12-09T00:52:27.865085Z",
"updated_at": "2018-12-09T00:52:27.865117Z",
"name": "Cleaning / Janitorial",
"description": "Cleaning / Janitorial",
"assignable": true,
"hidden": false,
"priority": 3,
"parent": "046e2b11-9c27-443f-959e-0b5fd49d200a"
},
...
In the future, additional data will be returned including a standardized Issue Category which is assigned to a type from a fixed set. This allows better reporting and aggregation of issues in the future. Other data will relate to the Service Level Agreements (SLAs) which may be set related to a Work Order of a given Issue Type.
Building Spaces / Floors
Each Building has a set of identified Spaces. These include Suites where tenants are occupants, common spaces such as a lobby, a rest room, or an elevator and Floors which are the basic, parent unit of a space.
To get the list of floors for a Building, use the building Id and hit the endpoint:
GET /buildings/<id>/floors
The resultant array will include all the spaces that are floors in the given building including the Id and names. The Id can be used in creating a Work Order as a space_id to identify an issue as simply being reported against a floor.
When more detailed locations are required, the API below will return all non-floor spaces within a Building.
GET /buildings/<id>/spaces
As with Floors, the result includes Id values usable to create a Work Order and other details including potential identification of the Tenant of a Suite and the Floor related to a given space.
Bulk API for Building, Space, and User Import/Update
Several API calls exist to support synchronizing data into the Building Engines environment in
large, bulk uploads. These uploads are JSON payloads but allow creation/update of a large
number of buildings, spaces, and users.
All bulk operations perform a create or update pass where, if the payload includes either a
Building Engines ID (id) or an External Key (external_key) string, we will seek an existing
record to update before creating a new one. In this way, repeated entries are not duplicated,
and existing values can be updated.
IMPORTANT: POST calls to the building endpoint for a single building given an external key will not update and instead duplicate. The behavior of a create or update pass is specific to the bulk API.
Each successful call will return a response containing a single job_id UUID value in a JSON
object. This indicates the bulk request is queued for processing. Background processing time
may vary due to system load and the size of the request. The calling application can then perform:
GET baseURL/jobs/<Job ID>
Authorization: Bearer <Token>
Accept: application/json;version=1.0
And will get back either a response value with a single key “detail” indicating the job is still
processing or your will get back a response with both a detail element, describing the result in a
string, and an array of objects which will include:
- id: The Building Engines ID of the created or updated object
- name: The name of the object in question
- external_key: The external key, or blank if not given for the object
Example response:
{
"detail": "2 objects successfully created",
"objects": [
{
"id": "xxxx-xxxx-xxxx-xxxx",
"name": "Building 1",
"external_key": "test_external_1"
},
{
"id": "xxxx-xxxx-xxxx-xxxx",
"name": "Building 2",
"external_key": "test_external_2"
}
]
}
At present, both in-progress and completed return an HTTP 200 (OK) but in the near future we
will return HTTP 200 (OK) for a completed job and HTTP 202 (ACCEPTED) for an incomplete job.
If any error exists in the payload being processed, we will return an HTTP 400 (BAD REQUEST)
with the payload directing what fields or data is in error.
Creating Buildings
Given your Manager Organization UUID value, address the following URL:
POST /bulk/<PMO ID>/buildings
The payload is an array of JSON objects including the following fields:
- id: Building Engines ID UUID if updating an existing record
- external_key: External unique identification string used to created a new record or update an existing one
- pmo_id: Building Engines ID of the management organization responsible for this building. This allows specification of an alternative management organization if one exists in the account. The default is the account primary management organization.
- account_id: Building Engines ID of the account related to this building
- phone
- website
- organizational_goal: Must be one of: mixed, responsive, lean
- is_active: Indicates this building is active. This is the default. A PATCH with a False value will indicate the building should be deactivated.
- created_at: ISO 8601 formatted date and time
- updated_at: ISO 8601 formatted date and time
- primary_contact_id: Prism UUID of the Primary Contact of this building
- primary_contact_external_key: External key of the Primary Contact for this building
- is_synchronized: Indicates this data has been synchronized and should not be edited directly in the Prism UI
- custom_fields: An array of JSON objects including a field_name and a value to set custom fields on the building. The custom field must have been created prior to this usage.
Required fields:
- name: Name of the building
- street_address: Street address
- street_address_2: 2nd line of street address
- city: City of the building
- state: State should use the standard, ISO short form
- industry: Must be one of: commercial, retail, industrial, land, medical, mixed, other
- measured_area: Volume of the property in square feet or square meters. Specify as a string with an integer followed by units which must be sq_ft or sq_m.
- Example: “12500 sq_ft”
Example payload:
buildings_data”: [
{
"external_key": "142808",
"is_synchronized": true,
“is_active”: true,
“pmo_id”: “62d093f8-4fdd-4c1b-b23f-e7710a995b85”,
"name": "Stone Oak Bldg A",
"street_address": "20855 Stone Oak Pkwy",
"street_address_2": "Building 1",
"city": "San Antonio",
"state": "TX",
"zip_code": "78258",
"country": "USA",
"industry": "commercial",
"num_floors": 1,
"measured_area": "99852 sq_ft",
"timezone": "US/Central",
"latitude": 29.652174,
"longitude": -98.458659,
"custom_fields": [{
"field_name": "cost_center",
"value": "CC/XXX"
}],
"primary_contact_external_key": "78123"
},
]
In the above example, the “pmo_id” can be obtained by querying the /organization endpoint.
Example response:
{
"job_id": "xxxx-xxxx-xxxx-xxxx"
}
FAQs
How to update the list of buildings a user has access to?
Answer: This is done via a PATCH to /users/:id and the payload is an array of building ids. This will overwrite the buildings the user has access to:
curl --location --request PATCH 'https://api.dev.v2.beifederation.com/users/b1433ee1-fe18-4324-b724-df170e0b9ffd' \
--header 'accept: application/json' \
--header 'accept-language: en-US' \
--header 'authorization: Bearer xxxx' \
--header 'content-type: application/json' \
--header 'origin: https://dev.v2.beifederation.com' \
--header 'referer: https://dev.v2.beifederation.com/' \
--header 'sec-ch-ua: "Google Chrome";v="123", "Not:A-Brand";v="8", "Chromium";v="123"' \
--header 'sec-ch-ua-mobile: ?0' \
--header 'sec-ch-ua-platform: "macOS"' \
--header 'sec-fetch-dest: empty' \
--header 'sec-fetch-mode: cors' \
--header 'sec-fetch-site: same-site' \
--header 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36' \
--data '{"building_ids":["3b7114dc-1577-48ab-a688-bc8034532ea2","cd249146-5bbe-40d7-9507-0037b1f39cb1","46f24996-d89b-43eb-8fd5-dd448f40a89b","5789e77e-7592-49c5-89cb-8abd4e733092"]}'
How does the Tenant Organization API and Spaces API interact with each other?
Answer: Sample request PATCH call to /spaces/:uuid/
{
"name": "TEST PATCH API",
"floor": {
"id": "xxxx-xxxx-xxxx-xxxx-xxxx",
"name": "22nd Floor",
"order": 22, # refers to where in the stack the floor is
"is_active": true
},
"floor_id": "xxxx-xxxx-xxxx-xxxx-xxxx",
"resourcetype": "Suite"
}
Sample request PATCH call to /organizations/tenants/:uuid/
{
"spaces": [
{
"id": "xxxx-xxxx-xxxx-xxxx-xxxx",
"name": "TEST PATCH API",
"building_id": "xxxx-xxxx-xxxx-xxxx-xxxx",
"floor": {
"id": "xxxx-xxxx-xxxx-xxxx-xxxx",
"name": "22nd Floor",
"order": 22,
"is_active": true
},
"floor_id": "xxxx-xxxx-xxxx-xxxx-xxxx"
}
]
}
IMPORTANT: The floor and space must reside in the respective building the building_id is referencing. Otherwise, you will receive an error stating the floor and/or suite are not found.
If a PATCH call is made to /spaces/:uuid/, the changes will reflect in the GET call to /organizations/tenants/:uuid/ and vice versa with the caveat that changes to the space’s details will not update and only which space the tenant resides in will update.
IMPORTANT: The space must exist within the current buildings the tenant has access to.
The PATCH calls above can also remove associations to spaces. Nullify either the spaces field in the /organizations/tenants/:uuid/ call or the tenant field in /spaces/:uuid/ call.