Links a stand-alone work order to a project, or moves it to another position within the project it already sits in, and declares the dependencies it takes on among the project's jobs. One work order is processed per call.
Rules
- The project must be filed at or above the office of the work order, and must not be completed.
- The work order can be linked at any status.
- A work order already in this project can be sent again to change its position. A work order held by another project leaves it to join this one, unless that other project is completed.
- A work order or a project outside the hierarchy of the OAuth2 application is reported as unknown.
- When a code is carried by a validated work order and a live one, the live one is linked. When several non-validated work orders carry the code, the call is refused as ambiguous.
Unlinking is not covered by this endpoint.
Rate limit range : High
Body
Required
-
Type of job linked. Only
workOrderis supported (case insensitive).Value is
workOrder. -
Business code of the work order to link.
-
Position of the work order among the project's jobs, and its dependencies. When absent, the work order is linked last, without dependency.
Additional properties are NOT allowed.
POST
/eTech/rest/ws/projectManagement/v1/projects/code:{projectCode}/link
curl \
--request POST 'https://ws-eu1.praxedo.com/eTech/rest/ws/projectManagement/v1/projects/code:PRJ-2026-0007/link' \
--header "Authorization: Bearer $ACCESS_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"type": "workOrder",
"code": "WO-2026-00123",
"insertion": {
"insertionMode": "last"
}
}'
Request examples
Link the work order after every job of the project
{
"type": "workOrder",
"code": "WO-2026-00123",
"insertion": {
"insertionMode": "last"
}
}
{
"type": "workOrder",
"code": "WO-2026-00123",
"insertion": {
"insertionMode": "index",
"position": 3
}
}
{
"type": "workOrder",
"code": "WO-2026-00123",
"insertion": {
"insertionMode": "after",
"relativePosition": "12333",
"jobType": "task"
}
}
{
"type": "workOrder",
"code": "WO-2026-00123",
"insertion": {
"insertionMode": "before",
"relativePosition": "PHASE-1"
}
}
{
"type": "workOrder",
"code": "WO-2026-00123",
"insertion": {
"insertionMode": "first",
"block": [
{
"jobType": "task",
"code": "0003"
}
],
"isBlockedBy": [
{
"jobType": "workOrder",
"code": "WO-2026-00124"
}
]
}
}
{
"type": "workOrder",
"code": "WO-2026-00123"
}
Response examples (204)
Response examples (400)
Unknown project
{
"errors": [
{
"code": "projectmanagement.project.code.unknown",
"message": "The project PRJ-2026-0007 is unknown. It doesn't exist or it is outside oauth2 hierarchy."
}
],
"errorReference": "823e4567-e89b-12d3-a456-426614174000"
}
{
"errors": [
{
"code": "projectmanagement.project.job.code.unknown",
"message": "The work order WO-2026-00123 is unknown. It doesn't exist or it is outside oauth2 hierarchy."
}
],
"errorReference": "823e4567-e89b-12d3-a456-426614174000"
}
{
"errors": [
{
"code": "projectmanagement.workorder.code.ambiguous",
"message": "Several work orders carry the code WO-2026-00123."
}
],
"errorReference": "823e4567-e89b-12d3-a456-426614174000"
}
{
"errors": [
{
"code": "projectmanagement.insertion.relativePosition.unknown",
"message": "The job 12333 is not one of the jobs the project holds."
}
],
"errorReference": "823e4567-e89b-12d3-a456-426614174000"
}
{
"errors": [
{
"code": "projectmanagement.insertion.relativePosition.unknown",
"message": "The work order WO-2026-00123 cannot be positioned relative to itself."
}
],
"errorReference": "823e4567-e89b-12d3-a456-426614174000"
}
{
"errors": [
{
"code": "projectmanagement.project.block.code.unknown",
"message": "A job named in insertion.block is not one of the jobs the project holds."
}
],
"errorReference": "823e4567-e89b-12d3-a456-426614174000"
}
{
"errors": [
{
"code": "projectmanagement.project.isBlockedBy.code.unknown",
"message": "A job named in insertion.isBlockedBy is not one of the jobs the project holds."
}
],
"errorReference": "823e4567-e89b-12d3-a456-426614174000"
}
{
"errors": [
{
"code": "projectmanagement.project.code.mandatory",
"message": "Missing project code in path."
}
],
"errorReference": "823e4567-e89b-12d3-a456-426614174000"
}
{
"errors": [
{
"code": "projectmanagement.project.job.type.mandatory",
"message": "Property type is required."
}
],
"errorReference": "823e4567-e89b-12d3-a456-426614174000"
}
{
"errors": [
{
"code": "projectmanagement.project.job.type.unknown",
"message": "The type 'task' is unknown. Only 'workorder' is supported."
}
],
"errorReference": "823e4567-e89b-12d3-a456-426614174000"
}
{
"errors": [
{
"code": "projectmanagement.project.job.code.mandatory",
"message": "Property code is required."
}
],
"errorReference": "823e4567-e89b-12d3-a456-426614174000"
}
{
"errors": [
{
"code": "projectmanagement.insertion.insertionMode.unknown",
"message": "The insertion mode 'middle' is unknown."
}
],
"errorReference": "823e4567-e89b-12d3-a456-426614174000"
}
{
"errors": [
{
"code": "projectmanagement.insertion.position.mandatory",
"message": "Property insertion.position is required when insertion.insertionMode is 'index'."
}
],
"errorReference": "823e4567-e89b-12d3-a456-426614174000"
}
{
"errors": [
{
"code": "projectmanagement.insertion.position.invalid",
"message": "Property insertion.position cannot be negative."
}
],
"errorReference": "823e4567-e89b-12d3-a456-426614174000"
}
{
"errors": [
{
"code": "projectmanagement.insertion.relativePosition.mandatory",
"message": "Property insertion.relativePosition is required when insertion.insertionMode is 'after'."
}
],
"errorReference": "823e4567-e89b-12d3-a456-426614174000"
}
{
"errors": [
{
"code": "projectmanagement.insertion.jobType.unknown",
"message": "The job type 'milestone' is unknown."
}
],
"errorReference": "823e4567-e89b-12d3-a456-426614174000"
}
{
"errors": [
{
"code": "projectmanagement.project.block.code.mandatory",
"message": "Property code is required on every insertion.block entry."
}
],
"errorReference": "823e4567-e89b-12d3-a456-426614174000"
}
{
"errors": [
{
"code": "projectmanagement.project.block.jobType.mandatory",
"message": "Property jobType is required on every insertion.block entry."
}
],
"errorReference": "823e4567-e89b-12d3-a456-426614174000"
}
{
"errors": [
{
"code": "projectmanagement.project.block.jobType.unknown",
"message": "The job type 'phase' is unknown. Use 'task' or 'workOrder'."
}
],
"errorReference": "823e4567-e89b-12d3-a456-426614174000"
}
{
"errors": [
{
"code": "projectmanagement.project.isBlockedBy.code.mandatory",
"message": "Property code is required on every insertion.isBlockedBy entry."
}
],
"errorReference": "823e4567-e89b-12d3-a456-426614174000"
}
{
"errors": [
{
"code": "projectmanagement.project.isBlockedBy.jobType.mandatory",
"message": "Property jobType is required on every insertion.isBlockedBy entry."
}
],
"errorReference": "823e4567-e89b-12d3-a456-426614174000"
}
{
"errors": [
{
"code": "projectmanagement.project.isBlockedBy.jobType.unknown",
"message": "The job type 'phase' is unknown. Use 'task' or 'workOrder'."
}
],
"errorReference": "823e4567-e89b-12d3-a456-426614174000"
}
{
"errors": [
{
"code": "projectmanagement.invalid.json",
"message": "Invalid Json format."
}
],
"errorReference": "823e4567-e89b-12d3-a456-426614174000"
}
{
"errors": [
{
"code": "projectmanagement.field.unknown",
"message": "The field 'priority' is unknown. Please correct your JSON request."
}
],
"errorReference": "823e4567-e89b-12d3-a456-426614174000"
}
{
"errors": [
{
"code": "projectmanagement.project.office.conflict",
"message": "The project must be in equal or higher hierarchy of work order."
}
],
"errorReference": "823e4567-e89b-12d3-a456-426614174000"
}
{
"errors": [
{
"code": "projectmanagement.project.status.conflict",
"message": "The project is completed, and takes no more work on."
}
],
"errorReference": "823e4567-e89b-12d3-a456-426614174000"
}
{
"errors": [
{
"code": "projectmanagement.workorder.currentproject.status.conflict",
"message": "The project the work order currently sits in is completed, and will not let it go."
}
],
"errorReference": "823e4567-e89b-12d3-a456-426614174000"
}
{
"errors": [
{
"code": "projectmanagement.project.block.office.conflict",
"message": "Dependencies can only be declared on a project filed on the office of the calling application or one of its descendants."
}
],
"errorReference": "823e4567-e89b-12d3-a456-426614174000"
}
{
"errors": [
{
"code": "projectmanagement.project.block.dependency.cycle",
"message": "The requested dependency would create a cycle between the project's jobs."
}
],
"errorReference": "823e4567-e89b-12d3-a456-426614174000"
}
{
"errors": [
{
"code": "projectmanagement.project.block.dependency.overlap",
"message": "The requested dependency is not allowed: the blocked job would have to start before the blocking one can."
}
],
"errorReference": "823e4567-e89b-12d3-a456-426614174000"
}
{
"errors": [
{
"code": "projectmanagement.rule.violated",
"message": "The operation was refused by a business rule."
}
],
"errorReference": "823e4567-e89b-12d3-a456-426614174000"
}
Response examples (401)
401 unauthorized
{
"errors": [
{
"code": "unauthorized.nocredentials",
"message": "No credentials."
}
],
"errorReference": "f939c6b8c15045c9a70f500fdb570555"
}
{
"errors": [
{
"code": "unauthorized.badcredentials",
"message": "Bad Credentials."
}
],
"errorReference": "f1028f99811b422eb21f5ff176664069"
}
Response examples (403)
{
"errors": [
{
"code": "access.forbiden",
"message": "You don't have the rights to access this resource."
}
],
"errorReference": "a745dc4c5a2b473aaf8ce94c9260aa8f"
}
Response examples (429)
{
"errors": [
{
"code": "ratelimiter.toomanyrequest",
"message": "Rejected because of the rate limit definition."
}
],
"errorReference": "973326230a3f44daba6cc34a5939b4fb"
}
Response examples (500)
{
"errors": [
{
"code": "internal.server.error",
"message": "Something went wrong."
}
],
"errorReference": "6377010431314bf6b0b95ec4d32ddae0"
}