Inbound API - TechnicheGroup/urgent-rest GitHub Wiki
Urgent CMMS REST API
This is documentation for the Urgent CMMS / Asset Management Platform REST API and is aimed at users who wish to integrate with the platform.
Content Type
The API supports JSON payloads and responses.
Endpoints
The endpoints for the staging and production systems will be supplied to you depending on your user & tenant that you are connecting to.
Authentication & Authorization
Authentication uses HMAC. Each API user has a token and secret associated to their account, this is submitted in a header after being hashed with several other items and converted to base64 to create a digest. The digest is re-computed on the server side and if it matches, the user is authenticated and the process moves on to the authorization stage.
Our specific HMAC digest implementation will require the following elements:
Item | Purpose | Notes |
---|---|---|
HTTP VERB | In conjunction with the HTTP URI prevents the digest from being used to access another method. | GET, POST, PUT, DELETE depending on the method being called. In UPPERCASE |
HTTP URI | In conjunction with the HTTP Verb prevents the digest from being used to access another method. | URL path to the method without the protocol, domain and querystring. In lowercase |
UTC Date & Time | Reduces the window in which the digest can be used in replay attacks. It is used in place of a cryptographic nonce as it does not require us to maintain a list of previously used nonces. | ISO-8601 format (yyyy-mm-ddThh:mm:ssZ). Requires that the server times are accurate. There will be a grace window, which will be governed by a setting. This increases the possibility that the method can be used in a replay attack, but only within a small defined window, which is deemed acceptable. |
The user's API secret. | Used as a component to identify the user. | Rotated via the Urgent platform User Profile |
The first three should be concatenated as a single string using UTF-8 with the "+" character as a separator, and then hashed using HMAC-SHA256 with the API Secret as the key and base-64 encoded, which will create the digest.
The following HTTP headers should be submitted in addition to the standard ones.
Header | Value | Notes |
---|---|---|
X-Timestamp | The UTC date & time used in construction of the digest | To allow the receiving party to reconstruct the digest. |
Authorization | TCN {API_TOKEN}:digest | TCN is a unique marker added to the Auth header to the inbound process for Urgent to allow us to guide the login correctly {API_TOKEN} is user-specific and you can get this from the API tab in the User Details of your Urgent login. It is not the username so that it can be revoked or rotated as applicable.The digest is the calculated digest of information as calculated below |
Example
In this example the user is sending a request to read the working hours for the tenant "Urgent SI". The user has the token "c3f132d2-fdaa-4c8c-825d-b33482ffc195" and the secret "JKQby5i3bC4vr8PS0Rp7gk52vV6IBa". Note, that this is not a functional method and is purely for example purposes.
Parameter | Value | Notes |
---|---|---|
HTTP Verb | GET | Uppercase |
HTTP URL | /rest/sites/workinghours/urgent%20si | All characters should be lowercase, including the tenant name, any control characters should be URI encoded |
Timestamp | 2021-03-10T14:23:23Z | ISO-8601 standard in UTC |
API Token | c3f132d2-fdaa-4c8c-825d-b33482ffc195 | |
API Secret | JKQby5i3bC4vr8PS0Rp7gk52vV6IBa |
The digest is formed of the following plain text: GET+/rest/sites/workinghours/urgent%20si+2021-03-10T14:23:23Z which is hashed with the user's secret and base-64 encoded to create the digest. For our example, that results in "MYqMQ+PYgB4PafuHAopEhPMCNuOjKPKVHpc9zHj2O60="
The headers are then set (note that this example will also include headers that are set automatically by the HTTP client)
GET /rest/sites/workinghours/urgent%20si HTTP/1.1
Authorization: TCN c3f132d2-fdaa-4c8c-825d-b33482ffc195:MYqMQ+PYgB4PafuHAopEhPMCNuOjKPKVHpc9zHj2O60=
Content-Type: application/json
X-Timestamp: 2021-03-10T14:23:23Z
Examples
The following examples are clients that can be use as a starting point to connect to the Urgent REST API. These examples are licensed under the MIT License and are provided "as is" without warranty of any kind.
- c# dot net core 3.1
- Postman Pre-request Script
- Go
- The Client Generator at editor.swagger.io can be used to generate sample client code, but this will exclude the authentication digest calculation and would have to be manually written.
HTTP Status Codes.
The following HTTP Status Codes are used by the API
Code | Meaning | Typical reasons |
---|---|---|
200 | OK | Success |
400 | Bad Request | Data validation error, broken rules will have been returned. |
403 | Forbidden | User does not have role |
401 | Unauthorized | API headers or digest incorrect |
429 | Too Many Requests | Used in rate limiting |
404 | Not Found | The resource used in a GET request was not found |
405 | Method Not Allowed | Using an incorrect HTTP Verb when accessing a method. |
Rate Limiting
For the health of the platform rate limiting is enabled on the API, with each method having its own setting. An HTTP 429 status code and a Retry-After header specifying how long the lockout is, is returned if the user exceeds the rate limit. The limits are tenant-wide and cannot be amended or disabled for a specific user.
Swagger
Swagger UI is available for method and payload structure which can be accessed via the endpoint URL, which will be supplied to you by our support team.
Uploading Documents
Uploading documents is split into two separate API calls, metadata and the actual document. This is a similar to You Tube's API and is designed so that the bytes of a document can be directly uploaded without having to base64 encode the contents and passing it a JSON.
The response for adding document metadata includes a document identifier which should be used when making the secondary call to the API to send the actual document bytes.
Common Responses
For most methods that change data in the Urgent platform an HTTP 200 OK status code response with a blank response is returned for successful requests, and this is what is detailed in the Swagger documentation.
For failures, an HTTP 400 Bad Request status code is returned with details on the errors encountered.
{
"Messages": [{
"Key": "BrokenRule_Section_Item_RuleKey",
"Value": "This request broken the rule on item in section"
}]
}
Method Specific Responses
The following methods do not adhere the common responses due to their need to supply identifiers.
Add Task
If an Add Task request is successful then the Task Reference is returned along with any "open" broken rules indicating why the task has been created but potentially not moved into the status you'd normally expect.
Example Success
{
"Messages": null,
"TaskReference": 123456,
"TaskIdentifier": "a83584a6-dc09-4b82-95fe-afeb008edcb0"
}
Example Success - Task is created but with qualifier message
{
"Messages": [
{
"Key": "StateBrokenRule_InvalidUserGroup",
"Value": "Unable to update the incident status, invalid user group"
}
],
"TaskReference": 123456,
"TaskIdentifier": "a83584a6-dc09-4b82-95fe-afeb008edcb0"
}
Example Failure
{
"Messages": [
{
"Key": "StateBrokenRule_InvalidUserGroup",
"Value": "Unable to update the incident status, invalid user group"
}
],
"TaskReference": null,
"TaskIdentifier": null
}
Add Quote
If document metadata is supplied when adding a quote then a document identifier will be returned to allow you to attach the document to the quote.
Example Success
{
"DocumentIdentifier": "ffb7bd81-1d2d-452e-91d4-ae59d60627c4",
"Messages": null
}
Example Failure
{
"DocumentIdentifier": null,
"Messages": [{
"Key": "BrokenRule_Section_Item_RuleKey",
"Value": "The item failed the rule in the section"
}]
}
Add Asset
Success Example
{
"AssetIdentifier": "7e2fb9e5-cf78-4103-88e7-6f7d8272d282",
"Messages":null
}
Failure Example
{
"AssetIdentifier": null,
"Messages": [{
"Key": "BrokenRule_Section_Item_RuleKey",
"Value": "The item broken the rule in section"
}]
}
Add Document Metadata
Success Example
{
"DocumentIdentifier": "4e5c6b54-2c73-45ba-b0cc-4a6ab970723e",
"Messages": null
}
Failure Example
{
"DocumentIdentifier": null,
"Messages": [{
"Key": "BrokenRule_Section_Item_RuleKey",
"Value": "The item broken the rule in section"
}]
}