The core functionality of the Work Order is to track requests from management employees or tenants for work to be done by property management staff or other vendors. Work Orders are associated to a given Building and can be requested on behalf of the Management Company itself or by or on behalf of a Tenant User.
Each Work Order is categorized by an Issue Type which is a categorized list of types such as Electrical / Fixture Replacement, or Cleaning / Carpet Cleaning.
Key Work Order data elements in request include the following but always cross-check the reference documentation to ensure you have the latest information.
- id: Identifier
- identifier: Human readable identifier
- allowed_statuses: List of possible statuses
- next_suggested_status: Next status in ideal workflow
- created_by: Object with id and name of creator
- assignee_id: GUID of assigned user
- assignee: Object with id and info about assigned user
- requester_id: GUID of requesting user
- requester: Object with id and info about requesting user
- comments: Array of comment objects
- attachments: Array of attachment objects
- followers: Array of users following changes to the Work Order
- organization_id: GUID of organization requesting the Work Order
- organization: Object with information about the requesting organization
- time_in_status: Amount of time in the current status expressed in a relative string
- status_history: List of statuses and historical time spent in each state
- permissions: Permissions include create, update, write, read, et al.
- building_id: GUID of the building
- building: Information about building
- issue_type_id: GUID of the Issue Type
- issue_type: Information about the Issue Type of the Work Order
- space_id: GUID of the space of the Work Order (Floor, Suite, etc.)
- space: Expanded object of the associated Space
- floor: Name of the associated Floor to the Space
- ephemeral_container_ id: Write-Only Used if a photo/attachment has been uploaded prior to Work Order creation
- email: Email of the requestor or able to be overridden if desired
- phone: Phone of the requestor of able to be overridden if desired
- status: Status of the Work Order
- source: Where the Work Order was logged from
- priority: Priority from 1-4
- due_date: ISO8801 datetime when the Work Order is due
- assigned_at: Date when last assignment took place
- acknowledged_at: Date when acknowledged (Not implement)
- completed_at: Date when Work Order was completed or cancelled
- commented_at: Date when the last Comment was added to the Work Order
- hold_start: Date when item was put on hold if applicable
- updated_by: GUID of last user to alter the Work Order
- total_labor_cost_currency: Currency used for cost of total labor
- total_labor_cost: Total labor cost as a floating point value in string form
- total_material_cost_currency: Currency used for cost of total materials
- total_material_cost: Total materials cost as a floating point value in string form
- total_cost_currency: Currency used for cost
- total_cost: Total cost as a floating-point value in string form
Creating Work Orders
A Work Order is created with the POST directive and must include the following fields:
- building_id – The Id of the Building the Work Order must be completed in
- issue_type_id – The Id of the Issue Type from the Building for this Work Order
- space_id – The Id of the Space or Floor the work must be completed in
- description – A description of the work to be completed
An example POST body:
POST /work_orders
{
"description": "Simple cleaning request tonight",
"building_id": "1b2c6c4b-1fa5-434d-a54e-0af40731982a",
"issue_type_id": "3a1b9496-0891-4755-adae-e3b9892db1bf",
"space_id": "d0d2777b-2dfa-48c3-8201-b9f57020cf22",
"location_details": "Near the north windows"
}
The result is a full Work Order record as documented below.
Retrieving Work Orders
Work Orders can be retrieved as a paged list via:
GET /work_orders
Or can be retrieved individually by Id with a request such as:
GET /work_orders/2661eaf5-e942-4972-9b64-475c25e5b37a
In the former case, the paged results will follow standard paging style as described above with each Work Order represented in the array of results. In the latter case, the resultant body is a single Work Order.
Filters can be applied including searching for Work Orders for a given building or buildings. This would be represented as follows:
GET /work_orders?building_id=1b2c6c4b-1fa5-434d-a54e-0af40731982a
Other filtering options exist and be combined such as building_id=<id>&priority__in=1,2,3. More details will be available in the API reference documentation.
Work Order Result Body
An example of the Work Order Result body follows. Notice this contains many fields for reading that allow for detailed information to be retrieved such as what applicable status values exist, the time spent in various states for Service Level Agreement (SLA) tracking, and partial information for related objects such as Buildings or Issue Types so a program can easily display such information.
NOTE: This is for illustration purposes only! The detailed, specific fields should be found in the Reference documentation for the /work_orders endpoint.
{
"id": "18ddce5b-abc4-44cc-bb84-d9cfeafa8fa9",
"identifier": "W-00004-000008",
"allowed_statuses": [
"open",
"onhold",
"completed",
"cancelled",
"closed"
],
"next_suggested_status": "open",
"created_by": {
"id": "c0e11945-9dc6-4671-ae92-6f3b8e0263d4",
"name": "Teddy R. Tenant",
"email": "teddy.tenant@example.org"
},
"assignee": null,
"assignee_id": null,
"requester": {
"id": "c0e11945-9dc6-4671-ae92-6f3b8e0263d4",
"name": "Teddy R. Tenant",
"email": "teddy.tenant@example.org"
},
"requester_id": "c0e11945-9dc6-4671-ae92-6f3b8e0263d4",
"comments": [],
"attachments": [],
"followers": [{
"id": "117960a1-dd94-420b-9b3f-678a2bb5f13b",
"user": {
"id": "c0e11945-9dc6-4671-ae92-6f3b8e0263d4",
"name": "Teddy R. Tenant",
"email": "teddy.tenant@example.org"
},
}],
"organization": {
"id": "340c74e1-3758-4718-966f-53243275603b",
"name": "CRE Management, Inc.",
"organization_type": "pmo"
},
"organization_id": "340c74e1-3758-4718-966f-53243275603b",
"time_in_status": null,
"status_history": {
"new": {
"last_date_captured": "2018-12-27T17:58:48.745419Z",
"elapsed_seconds": 0,
"time_since": "0 minutes"
},
"open": {
"last_date_captured": null,
"elapsed_seconds": 0,
"time_since": null
},
"onhold": {
"last_date_captured": null,
"elapsed_seconds": 0,
"time_since": null
},
"completed": {
"last_date_captured": null,
"elapsed_seconds": 0,
"time_since": null
},
"cancelled": {
"last_date_captured": null,
"elapsed_seconds": 0,
"time_since": null
},
"closed": {
"last_date_captured": null,
"elapsed_seconds": 0,
"time_since": null
}
},
"permissions": {
"create": true,
"update": true,
"write": true,
"read": true,
"assign": true,
"status_open": true,
"status_onhold": true,
"status_completed": true,
"status_cancelled": true,
"status_closed": true
},
"building": {
"id": "1b2c6c4b-1fa5-434d-a54e-0af40731982a",
"name": "123 Fake Street"
},
"building_id": "1b2c6c4b-1fa5-434d-a54e-0af40731982a",
"issue_type": {
"id": "3a1b9496-0891-4755-adae-e3b9892db1bf",
"name": "Cleaning - After Hours",
"description": "Cleaning - After Hours"
},
"issue_type_id": "3a1b9496-0891-4755-adae-e3b9892db1bf",
"space": {
"id": "d0d2777b-2dfa-48c3-8201-b9f57020cf22",
"name": "1st Floor"
},
"floor": "1st Floor",
"space_id": "d0d2777b-2dfa-48c3-8201-b9f57020cf22",
"identifier_number": 8,
"created_at": "2018-12-27T17:58:48.737369Z",
"updated_at": "2018-12-27T17:58:48.737460Z",
"description": "Simple cleaning request tonight",
"source": "web",
"location_details": "Near the north windows",
"phone": "",
"email": "",
"status": "new",
"priority": 3,
"due_date": "2018-12-29T17:58:48.732785Z",
"assigned_at": null,
"acknowledged_at": null,
"arrived_at": null,
"completed_at": null,
"commented_at": null,
"hold_start": null,
"updated_by": "c0e11945-9dc6-4671-ae92-6f3b8e0263d4"
}
Updating a Work Order
To update a Work Order, you can use PUT /work_orders/<id> to update the entire body or you can selectively update using PATCH /work_orders/<id>. The fields should match those named on retrieval.
An example would be:
PATCH /work_orders/18ddce5b-abc4-44cc-bb84-d9cfeafa8fa9
{
“priority”: 1
}
If so privileged, this would allow you to change the priority value from the former value to the new value of 1.
FAQs
How to create a work order via API
Work orders are created via /work_orders
Payload data
- issue_type_id: uuid of issue type
- building_id: uuid of building
- space_id: uuid of space
- description: description of the work order
- organization_id: uuid of organization
- priority: int referring to the level of priority
- serdy_form: should be set to null if a serdy form is not required
- status: status of the work order
- Available statuses are new, open, onhold, cancelled, completed, and closed
Optional fields:
- nte_limit_original: original amount
- nte_limit: current/final amount
- nte_limit_original_currency
- nte_limit_currency
Sample curl example below:
curl 'https://api.dev.v2.beifederation.com/work_orders' \
--compressed -X POST -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:125.0) Gecko/20100101 Firefox/125.0' \
-H 'Accept: application/json' \
-H 'Accept-Language: en-US' \
-H 'Accept-Encoding: gzip, deflate, br' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer xxxx \
-H 'Origin: https://dev.v2.beifederation.com' \
-H 'Connection: keep-alive' -H 'Referer: https://dev.v2.beifederation.com/' \
-H 'Sec-Fetch-Dest: empty' \
-H 'Sec-Fetch-Mode: cors' \
-H 'Sec-Fetch-Site: same-site' \
-H 'TE: trailers' \
--data-raw '{"phone":"+15085844793","email":"test@mailinator.com","serdy_form":null,"building_id":"376e651e-0c08-4500-95d8-9c2ca7a36df2","organization_id":"9360ae80-7fbf-4ef5-868f-2bd579b5f3db","requester_id":"a821a197-04a0-4a8b-b86d-b1bfa211fcc4","space_id":"1dec45fc-8251-49ec-b938-6f34b7d30de7","issue_type_id":"57b8c40b-e7a0-459c-aedb-fd10e34ef111","description":"Test","timezone":"America/New_York","source":"web"}'
How to get labor associated with a work order?
This is done via GET /work_orders/:id/labor_records. Sample request and response below:
curl --location 'https://api.connect.buildingengines.com/work_orders/71479fc6-0672-42e1-84af-4e619c96382a/labor_records' \
--header 'Authorization: JWT xxx'
[
{
"id": "xxxx-xxxx-xxxx-xxxx-xxxx",
"time_tracked": "0.00",
"hours": "2.00",
"billable": true,
"taxable": true,
"performed_by": {
"id": "xxxx-xxxx-xxxx-xxxx-xxxx",
"name": "John Smith",
"email": "jsmith@email.com",
"identifier": "",
"external_key": null,
"is_online": true,
"image_url": null,
"last_login": "2024-05-13T18:21:56.008227Z",
"first_name": "John",
"last_name": "Smith"
},
"performed_by_id": "xxxx-xxxx-xxxx-xxxx-xxxx",
"performed_on": "2024-05-07T04:00:00Z",
"markup_mode": "markup_fixed",
"markup_fixed": null,
"markup_percent": null,
"labor_rate": null,
"labor_rate_name": "John Smith",
"labor_rate_id": null,
"tax_cost": "0.0000",
"total_cost": "0.0000",
"total_cost_currency": "USD",
"notes": "",
"created_at": "2024-05-07T17:52:55.439033Z",
"updated_at": "2024-05-07T17:52:55.439041Z",
"created_by": {
"id": "xxxx-xxxx-xxxx-xxxx-xxxx",
"name": "John Smith",
"email": "jsmith@email.com",
"identifier": "",
"external_key": null,
"is_online": true,
"image_url": null,
"last_login": "2024-05-13T18:21:56.008227Z",
"first_name": "John",
"last_name": "Smith"
},
"updated_by": {
"id": "xxxx-xxxx-xxxx-xxxx-xxxx",
"name": "John Smith",
"email": "jsmith@email.com",
"identifier": "",
"external_key": null,
"is_online": true,
"image_url": null,
"last_login": "xxxx-xxxx-xxxx-xxxx-xxxx",
"first_name": "John",
"last_name": "Smith"
},
"permissions": {
"write": true,
"read": true,
"can_edit_tracked_time": true,
"can_change_labor_rate": true
},
"charge_code": null,
"charge_code_id": null,
"income_code": null,
"applied_labor_rate": "0.0000",
"applied_labor_rate_currency": "USD",
"bill_to_organization_id": "xxxx-xxxx-xxxx-xxxx-xxxx",
"bill_to_organization": {
"id": "xxxx-xxxx-xxxx-xxxx-xxxx",
"account_id": "xxxx-xxxx-xxxx-xxxx-xxxx",
"is_active": true,
"image_url": null,
"name": "My Company",
"organization_type": "pmo",
"organization_identifier": null,
"external_key": null,
"is_suspended": false
},
"batch_locked": null,
"record_type": "Labor",
"credit": null,
"actual_labor_rate": "0.0000",
"actual_hours": "22.00",
"labor_quantity": 2.0,
"applied_tax_rate": null,
"markup_after_tax": true
}
]
How to add a file
Ensure that attachment is of File type and not text.
curl --location {{baseURL}} \
--header 'Authorization: {{bearerToken}} \
--form 'attachment=@"{{locationOfFileLocally}}"' \
--form 'account_id="xxxx-xxxx-xxxx-xxxx-xxxx"' \
--form 'category_id="xxxx-xxxx-xxxx-xxxx-xxxx"'
How to associate a file to a work order
Sample request POST call to work_orders/<wo_order_id>/file_associations
{
"file_id": "xxxx-xxxx-xxxx-xxxx-xxxx"
}
To get all available file categories, make a GET call to /files_categories.
If the file is uploaded under the Photo category, the file will also appear under the Photo section of the work order.
How to get the original and final NTE of a work order
Calling a GET on work_orders/<work_order_id> will return the following fields related to NTEs
- nte_limit_original_currency: currency of the original NTE
- nte_limit_original: original NTE amount
- nte_limit_currency: currency of the current NTE
- nte_limit: current NTE amount