Download OpenAPI specification:Download
The Timewriting API is an open API covering the HR area. It's an example API used to demonstrate the api-first-workbench and has not been implemented.
This document describes release v1.0.1. We recommend using documentation published at https://equinor.github.io/api-first-workbench as it provides the best developer experience. Information on the next release v1.1.0 is available at this page
The API is designed and built according to Equinor's API strategy.
The API is documented in OpenAPI 3.0 format and follows REST principles.
api-version
must be present in all request as part of the query string. Requests without API version will be rejected with a HTTP 404 response code. The latest api-version is v1.
The api-version
will stay stable over time as the API follows the principles of API evolution
Subscription key must be created from Equinor's API Portal for the consumer application and each request must have the HTTP header Ocp-Apim-Subscription-Key
present with this value.
The resource will be named according to common terminology used across the Oil&Gas industry (for example Norsok standard NS-EN 13306 and ISO 14224).
Example of resources are /time-entries
and /cost-objects
.
Resources keys will indicate the resource type as part of the name.
Example: timeEntryId
and costObjectId
.
All date and time information are based on UTC (Universal Time Coordinated) and formatted according to RFC3339
This also applies to durations, such as 1 day or 2 hours, which are encoded as P0Y0M1DT0H0M0S
and P0Y0M0DT2H0M0S
.
These values are easily compatible with time libraries such as moment.js library.
Lookup operations return a single instance for the resource based on the key.
The resource may have related data which may or may not be relevant for a client. In order to indicate which related data to include, the lookup operation may provide include-...
query string boolean options.
Example: include-time-entries
Clients need to retrieve a subset of all resources for an endpoint. Usually, the criteria are non-trivial and in many case are not direct properties of the resource. REST does not provide a well-defined pattern for these types of requests.
Our approach, is to provide predefined filters with parameters. Each filter is documented in the OpenAPI specification.
Update operations for resources will utilize a sub-set of the JSON Patch proposed standard. JSON Patch is described in RFC 6902 with a user-friendly version at http://jsonpatch.com/.
Our goals with using JSON Patch is to focus on the intent of the update and avoid common pitfalls for the client. The common pitfalls we avoid with JSON Patch are:
Using JSON Patch is straightforward.
application/json-patch+json
. As part of the OpenAPI documentation, we will provide concrete examples for all update operation. In addition, the schema definiton for the request body defines which resource properties can be updated.
Example of JSON Patch request body which replaces the value of the properties title and text:
[
{
"op": "replace",
"path": "/comment ",
"value": "New comment"
},
{
"op": "replace",
"path": "/hours",
"value": 4
}
]
HTTP response codes will follow established best practice for REST services and will be documented in the OpenAPI specification.
Below is a list of status codes used in the API which the client should handle. Common:
Read - HTTP GET:
Create - HTTP POST:
Create - HTTP PUT:
Update - HTTP PATCH:
Delete - HTTP DELETE:
The API will use the principles of API evolution instead of introducing a new api-version on every breaking change.
In order to achieve this, endpoints, query parameters and resource properties can become deprecated and will be marked so in the OpenAPI specification.
In general, depcrated properties will be removed after 3 months.
If a client uses a deprecated endpoint or query parameter, the API will in the response provide a Sunset HTTP header
Sunset: Sat, 15 May 2021 12:59:59 GMT
representing the removal date for the deprecated feature as specified in RFC8594. In addition, a HTTP header Link: <https://equinor.github.io/maintenance-api-docs/#section/Deprecation>; rel="sunset"
will be provided to pointing to relevant documentation.
Clients must monitor these messages and take corrective actions.
Subscription key created from https://api.equinor.com
Security Scheme Type | API Key |
---|---|
Header parameter name: | ocp-apim-subscription-key |
Perform time writing by supplying all time entries for a given calendar period.
It's also possible to change individual time entries via endpoints POST /time-entries
,PATCH /time-entries/{time-entry-id}
and DELETE /time-entries/{time-entry-id}
.
This operation overwrites all existing time writing in the given calendar period. If there are errors for one or more of the time entries, none of them will be updated.
start-date required | string <date> Example: 2021-11-01 |
end-date required | string <date> Example: 2021-11-01 |
Time entries
date required | string <date> Time entry date |
hours required | number <double> [ 0 .. 24 ] Number of hours worked |
costObjectTypeId required | string (CostObjectTypes) Enum: "wbs" "network" Type of cost object |
costObjectId required | string Cost object identifier |
costSubObjectId | string Secondary cost object identifier. Not use for all cost object types. |
comment | string <= 40 characters Comment for time entry |
[- {
- "date": "2021-11-04",
- "hours": 8,
- "costObjectTypeId": "wbs",
- "costObjectId": "C.BAX.30.xxx",
- "comment": "Analysis of task xyz"
}, - {
- "date": "2021-11-05",
- "hours": 4.5,
- "costObjectTypeId": "network",
- "costObjectId": "9000000",
- "costSubObjectId": "10",
- "comment": "Analysis of task xyz"
}
]
{- "title": "One or more validation errors occurred.",
- "status": 400,
- "traceId": "00-d9dc368e6caec4449a64e798dad1b5b2-7d82bdde82c9474a-00",
- "errors": {
- "property1": { },
- "property2": { }
}
}
Create single time entry for logged on user.
Clients should expect end users to have prexisting knowledge of the cost object to use for a time entry, but can assist them by providing suggestions based on earlier time entries from endpoint /calendar/{start-date}/{end-date}
. A general search for cost objects used in the company will not be provided as it increases the risk for wrong time writing.
The time entry will need approval by the task owner of the cost object after registration. It's recommended to provide a comment where possible in order ease the approval process. If the approver does not have enough information, the time entry will be sent back to the end user through the workflow inbox of the ERP system.
The client is recommended to verify that the cost object exist and is open for time writing through the endpoint /cost-objects/{cost-object-id}
.
The endpoint does not currently support clock times. If logged on user is configured for clock times, the request will fail with a 409 - Conflict
error.
The request will fail with a 409 - Conflict
error if the date is more than 3 months in the past.
Time entry update
date required | string <date> Time entry date |
hours required | number <double> [ 0 .. 24 ] Number of hours worked |
costObjectTypeId required | string (CostObjectTypes) Enum: "wbs" "network" Type of cost object |
costObjectId required | string Cost object identifier |
costSubObjectId | string Secondary cost object identifier. Not use for all cost object types. |
comment | string <= 40 characters Comment for time entry |
{- "date": "2021-11-04",
- "hours": 8,
- "costObjectTypeId": "wbs",
- "costObjectId": "C.BAX.30.xxx",
- "comment": "Analysis of task xyz"
}
{- "timeEntryId": "154632395",
- "date": "2021-11-04",
- "hours": 7.5,
- "costObjectTypeId": "wbs",
- "costObjectId": "C.BAX.30.xxx",
- "costSubObjectId": "",
- "costObjectDescription": "Project XYZ",
- "comment": "string"
}
Calendar represent a date range to perform time writing for based on expecations in the work scehdule
TBD
start-date required | string <date> Example: 2021-11-01 |
end-date required | string <date> Example: 2021-11-01 |
include-time-entries | boolean Default: true Include all time entries in the calendar |
curl --request GET \ --url 'https://api-dev.gateway.equinor.com/api-first-workbench/calendar/%7Bstart-date%7D/%7Bend-date%7D?include-time-entries=SOME_BOOLEAN_VALUE' \ --header 'ocp-apim-subscription-key: REPLACE_KEY_VALUE'
{- "startDate": "2021-11-04",
- "endDate": "2021-11-10",
- "days": [
- {
- "date": "2019-05-22",
- "workSchedule": 8,
- "sumHours": 8,
- "timeEntries": [
- {
- "timeEntryId": "154632395",
- "date": "2021-11-04",
- "hours": 7.5,
- "costObjectTypeId": "wbs",
- "costObjectId": "C.BAX.30.xxx",
- "costSubObjectId": "",
- "costObjectDescription": "Project XYZ",
- "comment": "string"
}
]
}
]
}
Perform time writing by supplying all time entries for a given calendar period.
It's also possible to change individual time entries via endpoints POST /time-entries
,PATCH /time-entries/{time-entry-id}
and DELETE /time-entries/{time-entry-id}
.
This operation overwrites all existing time writing in the given calendar period. If there are errors for one or more of the time entries, none of them will be updated.
start-date required | string <date> Example: 2021-11-01 |
end-date required | string <date> Example: 2021-11-01 |
Time entries
date required | string <date> Time entry date |
hours required | number <double> [ 0 .. 24 ] Number of hours worked |
costObjectTypeId required | string (CostObjectTypes) Enum: "wbs" "network" Type of cost object |
costObjectId required | string Cost object identifier |
costSubObjectId | string Secondary cost object identifier. Not use for all cost object types. |
comment | string <= 40 characters Comment for time entry |
[- {
- "date": "2021-11-04",
- "hours": 8,
- "costObjectTypeId": "wbs",
- "costObjectId": "C.BAX.30.xxx",
- "comment": "Analysis of task xyz"
}, - {
- "date": "2021-11-05",
- "hours": 4.5,
- "costObjectTypeId": "network",
- "costObjectId": "9000000",
- "costSubObjectId": "10",
- "comment": "Analysis of task xyz"
}
]
{- "title": "One or more validation errors occurred.",
- "status": 400,
- "traceId": "00-d9dc368e6caec4449a64e798dad1b5b2-7d82bdde82c9474a-00",
- "errors": {
- "property1": { },
- "property2": { }
}
}
Lookup a single time entry. Time entry represent hours registered on a specific day towards a cost object.
Consider using the endpoint /calendar/{start-date}/{end-date}
for retrieving all time entries in the date range.
time-entry-id required | string Example: 154632395 |
curl --request GET \ --url https://api-dev.gateway.equinor.com/api-first-workbench/time-entries/%7Btime-entry-id%7D \ --header 'ocp-apim-subscription-key: REPLACE_KEY_VALUE'
{- "timeEntryId": "154632395",
- "date": "2021-11-04",
- "hours": 7.5,
- "costObjectTypeId": "wbs",
- "costObjectId": "C.BAX.30.xxx",
- "costSubObjectId": "",
- "costObjectDescription": "Project XYZ",
- "comment": "string"
}
Update single time entry.
Supports:
time-entry-id required | string Example: 154632395 |
Time entry update
op | string Value: "replace" JSON Patch operation according to RFC6902. |
path | string Enum: "/date" "/hours" "/comment" Path indicating the property to be impacted by the operation |
string or number Value to be assigned to a resource property based on the operation and path. |
[- {
- "op": "replace",
- "path": "/hours",
- "value": 7.5
}
]
{- "timeEntryId": "154632395",
- "date": "2021-11-04",
- "hours": 7.5,
- "costObjectTypeId": "wbs",
- "costObjectId": "C.BAX.30.xxx",
- "costSubObjectId": "",
- "costObjectDescription": "Project XYZ",
- "comment": "string"
}
Delete single time entry.
time-entry-id required | string Example: 154632395 |
curl --request DELETE \ --url https://api-dev.gateway.equinor.com/api-first-workbench/time-entries/%7Btime-entry-id%7D \ --header 'ocp-apim-subscription-key: REPLACE_KEY_VALUE'
{- "title": "One or more validation errors occurred.",
- "status": 400,
- "traceId": "00-d9dc368e6caec4449a64e798dad1b5b2-7d82bdde82c9474a-00",
- "errors": {
- "property1": { },
- "property2": { }
}
}
Create single time entry for logged on user.
Clients should expect end users to have prexisting knowledge of the cost object to use for a time entry, but can assist them by providing suggestions based on earlier time entries from endpoint /calendar/{start-date}/{end-date}
. A general search for cost objects used in the company will not be provided as it increases the risk for wrong time writing.
The time entry will need approval by the task owner of the cost object after registration. It's recommended to provide a comment where possible in order ease the approval process. If the approver does not have enough information, the time entry will be sent back to the end user through the workflow inbox of the ERP system.
The client is recommended to verify that the cost object exist and is open for time writing through the endpoint /cost-objects/{cost-object-id}
.
The endpoint does not currently support clock times. If logged on user is configured for clock times, the request will fail with a 409 - Conflict
error.
The request will fail with a 409 - Conflict
error if the date is more than 3 months in the past.
Time entry update
date required | string <date> Time entry date |
hours required | number <double> [ 0 .. 24 ] Number of hours worked |
costObjectTypeId required | string (CostObjectTypes) Enum: "wbs" "network" Type of cost object |
costObjectId required | string Cost object identifier |
costSubObjectId | string Secondary cost object identifier. Not use for all cost object types. |
comment | string <= 40 characters Comment for time entry |
{- "date": "2021-11-04",
- "hours": 8,
- "costObjectTypeId": "wbs",
- "costObjectId": "C.BAX.30.xxx",
- "comment": "Analysis of task xyz"
}
{- "timeEntryId": "154632395",
- "date": "2021-11-04",
- "hours": 7.5,
- "costObjectTypeId": "wbs",
- "costObjectId": "C.BAX.30.xxx",
- "costSubObjectId": "",
- "costObjectDescription": "Project XYZ",
- "comment": "string"
}
Lookup a single cost object.
The cost object is used when creating a new time entry.
cost-object-id required | string Example: C.BAX.30.xxx |
curl --request GET \ --url https://api-dev.gateway.equinor.com/api-first-workbench/cost-objects/%7Bcost-object-id%7D \ --header 'ocp-apim-subscription-key: REPLACE_KEY_VALUE'
{- "costObjectId": "9000000",
- "type": "wbs",
- "costObject": "Project XYZ",
- "isOpenForTimeWriting": true,
- "subObjects": [
- {
- "subCostObjectId": "0100",
- "subCostObject": "Implement API",
- "isOpenForTimeWriting": true
}
]
}