Workplace Management: Generic web services
Bobby van ter Beek
Sergio Karijodinomo
Rogier Nota
Julie Isebaert
General
Webservices can fetch, create and update data in a Workplace Management environment.
The Workplace Management API uses a REST-based framework. Authorization is based on Bearer tokens and a preshared key.
Web services are available out of the box and documented in the following parts for some of the most often-used objects. These objects are:@
Masterdata:
Organizations
Contact persons
Buildings
Areas
Assets
Problem types
Processes:
Requests
Corrective work orders
Preventive work orders
Currently, these APIs use generic endpoints. Domain-specific endpoints might be created in the future, as is the case for the reservations domain.
Pre-conditions
To be able to use the APIs, some Pre-conditions apply. A (technical) consultant can help with these pre-conditions.
A Workplace management environment with the following sub-conditions:
Incoming web services are enabled via the following access rules (Authentication tab on general settings) (this is done via customer support):
An external app object (which can also be created via the Authentication tab on the general settings as a level 3 admin) with a trust relation (key type = AES shared key) is available with the authorized system user of the trust relation also linked to the external app in the system user tab:
Make sure to add the domain in the 'Allowed origins for REST web services' field (Client settings, authentication) if you want to allow external domains to access the generic web services asynchronously (Cross-origin resource sharing (CORS)Cross-origin resource sharing (CORS))
Required parameters
The following parameters are needed to set up the API calls successfully:
Parameter | Description | Example |
---|
Parameter | Description | Example |
---|---|---|
server | the base URL of the tenant, either the tenant-specific domain or a general server | |
authentication-mode | Fixed value: “GENERIC. “ Relevant for the OAuth 2.0-based bearer token authentication. This is ONLY required for the automated scripting for token requests in Postman. | GENERIC |
clientRef | The reference of the Environment | demotenant |
username | The username of the system user on behalf of which you want to authenticate. Relevant for the bearer token authentication. (This user must be linked to the external app via the systemuser tab) | demo_api |
app-id | The reference of the external app. Relevant for the bearer token authentication | DTW-EA-001 |
x-access-id-value | The Access Id of the trust relation. Relevant for the bearer token authentication | demo_api_id |
secret-key | The key of the trust relation. Relevant for the bearer token authentication | DB2E51543E463290B946602B8047CC9E16048E2C99728DB2E51543E463290B946602B8047CC9E16048E2C99728 |
API OAuth 2.0 authorization scheme
General
To obtain access to the resources exposed by the Workplace Management REST API, clients must first request a bearer token. The procedure for this is outlined below:
Grant type
Bearer tokens can be obtained using the OAuth grant type “Resource Owner Password Credentials.” Even though this grant type suggests that a password is used, this is not the case in this authorization scheme. Instead of a password, a token request message should be encrypted using a preshared AES key, which the endpoint will validate, and a bearer token will be returned when authentication succeeds. Resource data returned by the resource endpoints depends on user access rights to the relevant resources.
Token request message
The token request message is a JSON message which should contain the following data where terms between brackets should be replaced by their literal values:
{
"grant_type": "password,""
"username": "[username of the resource owner]",
"password": "",
"scope": "session v1 v2 v3",
"app_id": "[external app id]"
}
It’s possible to use the literal alias “axx::access::admin” as username (without the additional quotes). When doing this, instead of using the actual username of the user requesting the resources, access will be requested on behalf of the default authorized system user linked to the (AES preshared key based) trust relation used by the external application.
Encrypting the token request message
The token request message should now be encrypted using the preshared AES key, which can be generated in Workplace management using AES-CBC mode, resulting in a ciphertext and an IV (initialization vector). Now build a string using the following format:
[length of the base64 encoded ciphertext]:[base64 encoded ciphertext][base64 encoded IV]
This resulting string should be sent in the actual token request as “encrypted-params”; see next paragraph.
Create an actual HTTP request for the token endpoint
Now to form the HTTP request for the token endpoint, a POST
request should be generated to the following endpoint (where the server should be replaced by the server domain):
https://[server]/axxerion/aaa/registration/oauth2/token
The request should contain at least the following headers (where the terms between brackets should again be replaced by the actual values):
The request body should contain form URL-encoded data as described in the table below:
key | value |
---|
key | value |
---|---|
| [encrypted-params] |
When the server grants the authorization request, 200 OK
responses should be received containing the bearer token that can be used for accessing the resource endpoints as long as the token is valid.
An example of the script can be found via the example Postman Collections in the Pre-request script tab, which can be downloaded at the bottom of this document.
Overview of APIs
Every endpoint consists of a base URL: https://{server}/webservices/{{clientRef}}/rest
Both ‘server' and ‘clientRef’ are to be filled in based on the environment parameters.
Based on the type of endpoint, the second part of the endpoint URL is determined:
Currently, two types of endpoints are available:
Getting data from Workplace management. This uses the generic 'completereportresult' function. This is the same endpoint for every call; the specific data request (Report) is added to the body of the call via a reference value (Mandatory and fixed value per call).
Endpoint: https://{server}/webservices/{{clientRef}}/rest/functions/completereportresult
Example endpoint: https://demotenant.axxerion.com/webservices/demotenant/rest/functions/completereportresult
Creating an object (Asset or Request). This uses the generic ‘createupdate’ function. The actual object and category of the object (e.g., Create Asset in category “Furniture”) that is to be created is also added to the endpoint after the createupdate part.
Endpoint: https://{server}/webservices/{{clientRef}}/rest/functions//createupdate{ObjectName}/{ObjectCategoryId}
Example endpoint: https://demotenant.axxerion.com/webservices/demotenant/rest/functions/Asset/710000000172835
The objectName can be either “Asset” or “Request”, the ObjectCategoryId is only relevant for Assets (fixed value for Requests). The options for assets can be fetched via one of the APIs below.
The following APIs are currently available out of the box:
Get a list of organizations
This POST call will fetch all the organizations (Own organizations and suppliers) in the tenant with the relevant information per organization.
Endpoint: https://{server}/webservices/{{clientRef}}/rest/functions/completereportresult
Body:
{
"reference":"API_Report_Organizations_01",
"filterFields":["Email"],
"filterValues":["example@email.com"]
}
The reference is mandatory; this determines the correct report to be executed: API_Report_Organizations_01
The filter fields are optional.
Available filter fields:
It is possible to filter the organizations based on an email address: Email
Example result:
Get a list of persons
This POST call will fetch all the persons in the tenant with the relevant information per person.
Endpoint: https://{server}/webservices/{{clientRef}}/rest/functions/completereportresult
Body:
{
"reference":"API_Report_Contacts_01",
"filterFields":["Email"],
"filterValues":["noreply@spacewell.com"]
}
The reference is mandatory; this determines the correct report to be executed: API_Report_Contacts_01
The filter fields are optional.
Available filter fields:
It is possible to filter the persons based on an email address: Email
Example result:
Get a list of buildings
This POST call will fetch all the buildings in the tenant with the relevant information per building.
Endpoint: https://{server}/webservices/{{clientRef}}/rest/functions/completereportresult
Body:
{
"reference":"API_Report_Properties_01"
}
The reference is mandatory; this determines the correct report to be executed: API_Report_Properties_01
This call does not support any additional filter fields
Example result:
Get a list of areas
This POST call will fetch all the areas in the tenant with the relevant information per area.
Endpoint: https://{server}/webservices/{{clientRef}}/rest/functions/completereportresult
Body:
{
"reference":"API_Report_Areas_01",
"filterFields":["Property"],
"filterValues":[[1210000000000849]]
}
The reference is mandatory; this determines the correct report to be executed: API_Report_Areas_01
The filter fields are optional.
Available filter fields:
It is possible to filter the areas based on a specific building: Property
The filter value needs to be the Id of the building, as fetched via the building API call.
Example result:
Get a list of assets
This POST call will fetch all the assets in the tenant with the relevant information per asset.
Endpoint: https://{server}/webservices/{{clientRef}}/rest/functions/completereportresult
Body:
{
"reference":"API_Report_Asset_01",
"filterFields":["Property","Area"],
"filterValues":[[1000066632],[1000212917]]
}
The reference is mandatory; this determines the correct report to be executed: API_Report_Asset_01
The filter fields are optional.
Available filter fields:
It is possible to filter the assets based on a specific building: Property
It is possible to filter the assets based on a specific area: Area
The filter value needs to be the Id of the building and/or area, as fetched via building and area API calls.
Example result:
Get a list of asset categories
This POST call will fetch all the asset categories in the tenant. The Id of an asset category can be used to create a new asset in the desired category (See Create an Asset). E.g., Car, Bike, Coffee machine.
Endpoint: https://{server}/webservices/{{clientRef}}/rest/functions/completereportresult
Body:
{
"reference":"API_Report_Asset_Categories_01"
}
The reference is mandatory; this determines the correct report to be executed: API_Report_Asset_Categories_01
This call does not support any additional filter fields
Example result:
Get a list of requests.
This POST call will fetch all the requests in the tenant with the relevant information per request.
Endpoint: https://{server}/webservices/{{clientRef}}/rest/functions/completereportresult
Body:
{
"reference":"API_Report_Requests_01",
"filterFields":["CreatedSince","CreatedUntil"],
"filterValues":["2023-01-01T00:00:00Z","2023-08-01T00:00:00Z"]
}
The reference is mandatory; this determines the correct report to be executed: API_Report_Requests_01
The filter fields are optional.
Available filter fields:
It is possible to filter the requests based on the create times: CreatedSince and CreatedUntil
Date/time filters must be entered in ISO 8610 Combined date and time representations (See ISO 8601)
The following filter fields can also be used (not shown in the body above):
Asset (Specify the ID value of an Asset, to get the requests linked to this asset)
Area (Specify the ID value of an Area, to get the requests linked to this area)
Property (Specify the ID value of a Property, to get the requests linked to this property)
Example result:
Get a list of problem types
This POST call will fetch all the problem types (A problem type is used to determine the type of request and which service group will be assigned to handle the request) in the tenant with the relevant information per problem type.
Endpoint: https://{server}/webservices/{{clientRef}}/rest/functions/completereportresult
Body:
{
"reference":"API_Report_ProblemTypes_01"
}
The reference is mandatory; this determines the correct report to be executed: API_Report_ProblemTypes_01
This call does not support any additional filter fields
Example result:
Get a list of members per service group
This POST call will fetch all the contacts in a service group (A service group is used in a problem type and will be used to determine which group will be assigned to handle the request) in the tenant with the relevant information per service group.
Endpoint: https://{server}/webservices/{{clientRef}}/rest/functions/completereportresult
Body:
{
"reference":"API_Report_ServiceGroupMembers_01"
}
The reference is mandatory; this determines the correct report to be executed: API_Report_ServiceGroupMembers_01
This call does not support any additional filter fields
Example result:
Get a list of corrective work orders
This POST call will fetch all the corrective work orders (work orders created on a request) in the tenant with the relevant information per work order.
Endpoint: https://{server}/webservices/{{clientRef}}/rest/functions/completereportresult
Body:
{
"reference":"API_Report_Corrective_WorkOrders_01",
"filterFields":["CreatedSince","CreatedUntil"],
"filterValues":["2023-01-01T00:00:00Z","2023-09-01T00:00:00Z"]
}
The reference is mandatory; this determines the correct report to be executed: API_Report_Corrective_WorkOrders_01
The filter fields are optional.
Available filter fields:
It is possible to filter the work orders based on the create times: CreatedSince and CreatedUntil
Date/time filters must be entered in ISO 8610 Combined date and time representations (See ISO 8601)
The following filter fields can also be used (not shown in the body above):
Asset (Specify the ID value of an Asset, to get the corrective work orders linked to this asset)
Area (Specify the ID value of an Area, to get the corrective work orders linked to this area)
Property (Specify the ID value of a Property, to get the corrective work orders linked to this property)
Request (Specificy the ID value of a Request, to get the corrective work orders for this Request)
Example result:
Get a list of preventive work orders
This POST call will fetch all the preventive work orders (work orders created via a maintenance schedule) in the tenant with the relevant information per work order.
Endpoint: https://{server}/webservices/{{clientRef}}/rest/functions/completereportresult
Body:
{
"reference":"API_Report_Preventive_WorkOrders_01",
"filterFields":["CreatedSince","CreatedUntil"],
"filterValues":["2023-01-01T00:00:00Z","2024-01-01T00:00:00Z"]
}
The reference is mandatory; this determines the correct report to be executed: API_Report_Corrective_WorkOrders_01
The filter fields are optional.
Available filter fields:
It is possible to filter the work orders based on the create times: CreatedSince and CreatedUntil
Date/time filters must be entered in ISO 8610 Combined date and time representations (See ISO 8601)
The following filter fields can also be used (not shown in the body above):
(Since preventive work orders can be linked to multiple objects (e.g. maintenance for 10 elevators), the filtering works a bit differently for corrective work orders. One preventive work order can be returned more than once, depending on the number of objects it is linked to. To filter on a specific object, the ID of the object can be added. This can be an Asset, Area, or building (Be aware, if the work order is linked to a specific asset, it won’t return results if filtered on the building on that asset, it must be filtered specifically on that asset (Or no filter)).
Object (Specify the ID value of an Asset, Area, or Building to get the preventive work orders linked to this object)
Example result:
Create an asset
This Post call is used to create a new asset
Endpoint: https://{server}/webservices/{{clientRef}}/rest/functions/createupdate/Asset/{{assetCategory}}
The '{{assetCategory}' in the endpoint URL should be set to an asset category id value (Fetched via the get a list of Asset categories call)
Body with example values:
{
"name": "Example laptop 2",
"externalReference": "987654321",
"serialNumber": "123456789",
"tradeName": "DTwin turbo",
"modelName": "model X1",
"quantity": "1",
"manufacturerContactId": "1210000000005286",
"supplierContactId": "",
"purchaseDate": "2023-01-01T00:00:00Z",
"propertyId": "1210000000000849",
"areaId": "1210000000048836",
"parentAssetId": "1210000000008548"
}
The following fields can be set via the body (all optional):
Parameter | Description |
---|
Parameter | Description |
---|---|
Name | Free text (255 characters max) |
ExternalReference | Free text (255 characters max) |
serialNumber | Free text (255 characters max) |
modelName | Free text (255 characters max) |
quantity | Integer |
manufacturerContactId | Id value of an organization or person (Fetched via the get a list of organizations or get a list of persons API calls) |
supplierContactId | Id value of an organization or person (Fetched via the get a list of organizations or get a list of persons API calls) |
purchaseDate | Date/time filters must be entered in ISO 8610 Combined date and time representations (See ISO 8601) |
propertyId | Id value of a building (Fetched via the get a list of a buildings API call) |
areaId | Id value of an area ( Fetched via the get a list of an areas API call) |
parentAssetId | Id value of an asset ( Fetched via the get a list of an assets API call) |
The response will be the Id value of the newly created asset:
Create a request
This Post call is used to create a new request
Endpoint: https://{server}/webservices/{{clientRef}}/rest/functions/createupdate/Request/1000000786
Body with example values:
{ "fromContactId": "1210000000004567",
"name": "Test request",
"description": "Test request",
"problemTypeId": "1210000000005757",
"propertyId": "12100000000057634",
"areaId": "1210000000005764",
"assetId": "1210000000005734"
}
The following fields can be set via the body (all optional):
Parameter | Description |
---|
Parameter | Description |
---|---|
fromContactId | Id value of an organization or person (Fetched via the get a list of organizations or get a list of persons API |
name | Free text (255 characters max) |
description | Free text (255 characters max) |
problemTypeId | Id value of a problem type (Fetched via the get a list of problem types API call) |
propertyId | Id value of a building (Fetched via the get a list of buildings API call) |
areaId | Id value of an area ( Fetched via the get a list of areas API call) |
assetId | Id value of an asset( Fetched via the get a list of assets API call) |
The response will be the Id value of the newly created request
Updating an existing object
Via a PUT call, it is possible to update one of the objects above.
This requires the following endpoint:https://{server}/webservices/{{clientRef}}/rest/functions/update/{ObjectType}/{ID}
The {ObjecType} should be the Name of the object type. E.g ‘Asset' or 'Request’.
The {ID} should be the ID value of the object you want to update
The body of the call should contain the relevant fields to update. See examples above in the create calls.
Postman project
The following links contain an example Postman project and a (dummy) environment based on the API calls described above. The environment should be filled in based on the environment parameters actually to use.