Work packages
The tasks in a project, with relations between them and their history.
#List a project's versions (Roadmap)
/v1/app/project/projects/:id/versionsList a project's versions (Roadmap). Requires at least viewer role on the project. Each version includes open_count/closed_count of its work packages.
- Address
https://<your-org>.brambleit.cloud/api/v1/app/project/projects/:id/versions- Requires
- Signed-in session,
X-API-Key, or a Bramble app access token (Authorization: Bearer).
Licence: Projects.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | integer |
Response 200
| Field | Type | Description |
|---|---|---|
versions | array of object | |
versions[].id | integer | |
versions[].project_id | integer | |
versions[].name | string | |
versions[].description | string, or null | |
versions[].start_date | string (date), or null | |
versions[].due_date | string (date), or null | |
versions[].status | string: "open" | "locked" | "closed" | |
versions[].position | integer | |
versions[].created_at | string (date-time) | |
versions[].open_count | number | |
versions[].closed_count | number |
Example response
{
"versions": [
{
"id": 42,
"project_id": 7,
"name": "Example name",
"description": "string",
"start_date": "2026-11-12",
"due_date": "2026-11-12",
"status": "open",
"position": 1,
"created_at": "2026-11-12T09:30:00.000Z",
"open_count": 12.5,
"closed_count": 12.5
}
]
}Example request
curl -X GET 'https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/versions' \
-H "X-API-Key: $BRAMBLE_KEY"const res = await fetch('https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/versions', {
method: 'GET',
headers: { 'X-API-Key': process.env.BRAMBLE_KEY },
});
const data = await res.json();import os, requests
r = requests.get(
"https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/versions",
headers={"X-API-Key": os.environ["BRAMBLE_KEY"]},
)
r.raise_for_status()
data = r.json()$headers = @{ 'X-API-Key' = $env:BRAMBLE_KEY }
Invoke-RestMethod -Method GET -Uri 'https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/versions' -Headers $headers#Create a version/roadmap milestone
/v1/app/project/projects/:id/versionsCreate a version/roadmap milestone. Requires at least admin role on the project.
- Address
https://<your-org>.brambleit.cloud/api/v1/app/project/projects/:id/versions- Requires
- Signed-in session,
X-API-Key, or a Bramble app access token (Authorization: Bearer).
Licence: Projects.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | integer |
Request body JSON
| Name | Type | Description |
|---|---|---|
namerequired | string | |
description | string | |
start_date | string (date) | |
due_date | string (date) | |
status | string |
Response 201
| Field | Type | Description |
|---|---|---|
version | any |
Example response
{
"version": null
}Errors
| Status | Message |
|---|---|
| 400 | name is required |
| 400 | Invalid status |
Example request
curl -X POST 'https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/versions' \
-H "X-API-Key: $BRAMBLE_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Example name","description":"string","start_date":"2026-11-12","due_date":"2026-11-12","status":"active"}'const res = await fetch('https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/versions', {
method: 'POST',
headers: { 'X-API-Key': process.env.BRAMBLE_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({"name":"Example name","description":"string","start_date":"2026-11-12","due_date":"2026-11-12","status":"active"}),
});
const data = await res.json();import os, requests
r = requests.post(
"https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/versions",
headers={"X-API-Key": os.environ["BRAMBLE_KEY"]},
json={"name":"Example name","description":"string","start_date":"2026-11-12","due_date":"2026-11-12","status":"active"},
)
r.raise_for_status()
data = r.json()$headers = @{ 'X-API-Key' = $env:BRAMBLE_KEY }
$body = '{"name":"Example name","description":"string","start_date":"2026-11-12","due_date":"2026-11-12","status":"active"}'
Invoke-RestMethod -Method POST -Uri 'https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/versions' -Headers $headers -ContentType 'application/json' -Body $body#Update a version/roadmap milestone
/v1/app/project/projects/:id/versions/:versionIdUpdate a version/roadmap milestone. Requires at least admin role on the project.
- Address
https://<your-org>.brambleit.cloud/api/v1/app/project/projects/:id/versions/:versionId- Requires
- Signed-in session,
X-API-Key, or a Bramble app access token (Authorization: Bearer).
Licence: Projects.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | integer | |
versionIdrequired | integer |
Request body JSON
| Name | Type | Description |
|---|---|---|
name | string | |
description | string | |
start_date | string (date) | |
due_date | string (date) | |
status | string | |
position | integer |
Response 200
| Field | Type | Description |
|---|---|---|
version | any |
Example response
{
"version": null
}Errors
| Status | Message |
|---|---|
| 400 | Invalid status |
Example request
curl -X PATCH 'https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/versions/1' \
-H "X-API-Key: $BRAMBLE_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Example name","description":"string","start_date":"2026-11-12","due_date":"2026-11-12","status":"active","position":1}'const res = await fetch('https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/versions/1', {
method: 'PATCH',
headers: { 'X-API-Key': process.env.BRAMBLE_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({"name":"Example name","description":"string","start_date":"2026-11-12","due_date":"2026-11-12","status":"active","position":1}),
});
const data = await res.json();import os, requests
r = requests.patch(
"https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/versions/1",
headers={"X-API-Key": os.environ["BRAMBLE_KEY"]},
json={"name":"Example name","description":"string","start_date":"2026-11-12","due_date":"2026-11-12","status":"active","position":1},
)
r.raise_for_status()
data = r.json()$headers = @{ 'X-API-Key' = $env:BRAMBLE_KEY }
$body = '{"name":"Example name","description":"string","start_date":"2026-11-12","due_date":"2026-11-12","status":"active","position":1}'
Invoke-RestMethod -Method PATCH -Uri 'https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/versions/1' -Headers $headers -ContentType 'application/json' -Body $body#Delete a version/roadmap milestone
/v1/app/project/projects/:id/versions/:versionIdDelete a version/roadmap milestone. Requires at least admin role on the project. Work packages referencing this version are unset (version_id set to null), not deleted.
- Address
https://<your-org>.brambleit.cloud/api/v1/app/project/projects/:id/versions/:versionId- Requires
- Signed-in session,
X-API-Key, or a Bramble app access token (Authorization: Bearer).
Licence: Projects.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | integer | |
versionIdrequired | integer |
Response 200
| Field | Type | Description |
|---|---|---|
ok | boolean |
Example response
{
"ok": true
}Example request
curl -X DELETE 'https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/versions/1' \
-H "X-API-Key: $BRAMBLE_KEY"const res = await fetch('https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/versions/1', {
method: 'DELETE',
headers: { 'X-API-Key': process.env.BRAMBLE_KEY },
});
const data = await res.json();import os, requests
r = requests.delete(
"https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/versions/1",
headers={"X-API-Key": os.environ["BRAMBLE_KEY"]},
)
r.raise_for_status()
data = r.json()$headers = @{ 'X-API-Key' = $env:BRAMBLE_KEY }
Invoke-RestMethod -Method DELETE -Uri 'https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/versions/1' -Headers $headers#List a project's work packages
/v1/app/project/projects/:id/work-packagesList a project's work packages. Requires at least viewer role on the project. Shared by the Board, Work Packages table, and Gantt views. Supports filtering.
- Address
https://<your-org>.brambleit.cloud/api/v1/app/project/projects/:id/work-packages- Requires
- Signed-in session,
X-API-Key, or a Bramble app access token (Authorization: Bearer).
Licence: Projects.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | integer |
Query parameters
| Name | Type | Description |
|---|---|---|
status_id | integer | |
category_id | integer | |
type_id | integer | |
version_id | integer | |
priority | any | |
assignee | any | |
q | string |
Response 200
| Field | Type | Description |
|---|---|---|
work_packages | array of object | |
work_packages[].id | integer | |
work_packages[].project_id | integer | |
work_packages[].type_id | integer | |
work_packages[].status_id | integer | |
work_packages[].parent_id | integer, or null | |
work_packages[].version_id | integer, or null | |
work_packages[].category_id | integer, or null | |
work_packages[].subject | string | |
work_packages[].description | string, or null | |
work_packages[].priority | string: "low" | "medium" | "high" | "urgent" | |
work_packages[].start_date | string (date), or null | |
work_packages[].due_date | string (date), or null | |
work_packages[].percent_done | integer | |
work_packages[].position | integer | |
work_packages[].created_by | integer | |
work_packages[].created_at | string (date-time) | |
work_packages[].updated_at | string (date-time) | |
work_packages[].completed_at | string (date-time), or null | |
work_packages[].deleted_at | string (date-time), or null |
Example response
{
"work_packages": [
{
"id": 42,
"project_id": 7,
"type_id": 7,
"status_id": 7,
"parent_id": 7,
"version_id": 7,
"category_id": 7,
"subject": "Example subject",
"description": "string",
"priority": "low",
"start_date": "2026-11-12",
"due_date": "2026-11-12",
"percent_done": 1,
"position": 1,
"created_by": 1,
"created_at": "2026-11-12T09:30:00.000Z",
"updated_at": "2026-11-12T09:30:00.000Z",
"completed_at": "2026-11-12T09:30:00.000Z",
"deleted_at": "2026-11-12T09:30:00.000Z"
}
]
}Example request
curl -X GET 'https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages' \
-H "X-API-Key: $BRAMBLE_KEY"const res = await fetch('https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages', {
method: 'GET',
headers: { 'X-API-Key': process.env.BRAMBLE_KEY },
});
const data = await res.json();import os, requests
r = requests.get(
"https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages",
headers={"X-API-Key": os.environ["BRAMBLE_KEY"]},
)
r.raise_for_status()
data = r.json()$headers = @{ 'X-API-Key' = $env:BRAMBLE_KEY }
Invoke-RestMethod -Method GET -Uri 'https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages' -Headers $headers#Create a work package
/v1/app/project/projects/:id/work-packagesCreate a work package. Requires at least member role on the project. Falls back to the project's first non-milestone type and default status if not specified.
- Address
https://<your-org>.brambleit.cloud/api/v1/app/project/projects/:id/work-packages- Requires
- Signed-in session,
X-API-Key, or a Bramble app access token (Authorization: Bearer).
Licence: Projects.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | integer |
Request body JSON
| Name | Type | Description |
|---|---|---|
subjectrequired | string | |
description | string | |
type_id | integer | |
status_id | integer | |
parent_id | integer | |
version_id | integer | |
category_id | integer | |
priority | any | |
start_date | string (date) | |
due_date | string (date) | |
percent_done | number | |
assignee_ids | array of any | |
tag_ids | array of any |
Response 201
| Field | Type | Description |
|---|---|---|
work_package | object | |
work_package.tag_ids | array of integer | |
work_package.assignee_ids | array of integer |
Example response
{
"work_package": {
"…rows[0]": "…",
"tag_ids": [
7
],
"assignee_ids": [
7
]
}
}Errors
| Status | Message |
|---|---|
| 400 | subject is required |
| 400 | Invalid priority |
| 400 | percent_done must be between 0 and 100 |
| 400 | Project has no types or statuses configured |
| 400 | Invalid parent work package |
Example request
curl -X POST 'https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages' \
-H "X-API-Key: $BRAMBLE_KEY" \
-H "Content-Type: application/json" \
-d '{"subject":"Example subject","description":"string","type_id":7,"status_id":7,"parent_id":7,"version_id":7,"category_id":7,"priority":"…","start_date":"2026-11-12","due_date":"2026-11-12","percent_done":12.5,"assignee_ids":[],"tag_ids":[]}'const res = await fetch('https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages', {
method: 'POST',
headers: { 'X-API-Key': process.env.BRAMBLE_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({"subject":"Example subject","description":"string","type_id":7,"status_id":7,"parent_id":7,"version_id":7,"category_id":7,"priority":"…","start_date":"2026-11-12","due_date":"2026-11-12","percent_done":12.5,"assignee_ids":[],"tag_ids":[]}),
});
const data = await res.json();import os, requests
r = requests.post(
"https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages",
headers={"X-API-Key": os.environ["BRAMBLE_KEY"]},
json={"subject":"Example subject","description":"string","type_id":7,"status_id":7,"parent_id":7,"version_id":7,"category_id":7,"priority":"…","start_date":"2026-11-12","due_date":"2026-11-12","percent_done":12.5,"assignee_ids":[],"tag_ids":[]},
)
r.raise_for_status()
data = r.json()$headers = @{ 'X-API-Key' = $env:BRAMBLE_KEY }
$body = '{"subject":"Example subject","description":"string","type_id":7,"status_id":7,"parent_id":7,"version_id":7,"category_id":7,"priority":"…","start_date":"2026-11-12","due_date":"2026-11-12","percent_done":12.5,"assignee_ids":[],"tag_ids":[]}'
Invoke-RestMethod -Method POST -Uri 'https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages' -Headers $headers -ContentType 'application/json' -Body $body#Get a single work package
/v1/app/project/projects/:id/work-packages/:wpIdGet a single work package. Requires at least viewer role on the project.
- Address
https://<your-org>.brambleit.cloud/api/v1/app/project/projects/:id/work-packages/:wpId- Requires
- Signed-in session,
X-API-Key, or a Bramble app access token (Authorization: Bearer).
Licence: Projects.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | integer | |
wpIdrequired | integer |
Response 200
| Field | Type | Description |
|---|---|---|
work_package | object | |
work_package.assignee_ids | array of integer | |
work_package.tag_ids | array of integer |
Example response
{
"work_package": {
"…rows[0]": "…",
"assignee_ids": [
7
],
"tag_ids": [
7
]
}
}Errors
| Status | Message |
|---|---|
| 404 | Work package not found |
Example request
curl -X GET 'https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages/1' \
-H "X-API-Key: $BRAMBLE_KEY"const res = await fetch('https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages/1', {
method: 'GET',
headers: { 'X-API-Key': process.env.BRAMBLE_KEY },
});
const data = await res.json();import os, requests
r = requests.get(
"https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages/1",
headers={"X-API-Key": os.environ["BRAMBLE_KEY"]},
)
r.raise_for_status()
data = r.json()$headers = @{ 'X-API-Key' = $env:BRAMBLE_KEY }
Invoke-RestMethod -Method GET -Uri 'https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages/1' -Headers $headers#Update a work package
/v1/app/project/projects/:id/work-packages/:wpIdUpdate a work package. Requires at least member role on the project. Reassigning triggers "assigned" notifications for newly-added assignees; changing status_id notifies current assignees of the status change. Rejects a parent_id change that would create a circular hierarchy.
- Address
https://<your-org>.brambleit.cloud/api/v1/app/project/projects/:id/work-packages/:wpId- Requires
- Signed-in session,
X-API-Key, or a Bramble app access token (Authorization: Bearer).
Licence: Projects.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | integer | |
wpIdrequired | integer |
Request body JSON
| Name | Type | Description |
|---|---|---|
subject | any | |
description | string | |
type_id | integer | |
status_id | integer | |
category_id | integer | |
version_id | integer | |
priority | any | |
start_date | string (date) | |
due_date | string (date) | |
percent_done | number | |
assignee_ids | array of any | |
tag_ids | array of any | |
completed | any | |
parent_id | integer |
Response 200
| Field | Type | Description |
|---|---|---|
work_package | any |
Example response
{
"work_package": null
}Errors
| Status | Message |
|---|---|
| 400 | Invalid priority |
| 400 | percent_done must be between 0 and 100 |
| 400 | Invalid parent work package |
| 400 | That would create a circular hierarchy |
Example request
curl -X PATCH 'https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages/1' \
-H "X-API-Key: $BRAMBLE_KEY" \
-H "Content-Type: application/json" \
-d '{"subject":"…","description":"string","type_id":7,"status_id":7,"category_id":7,"version_id":7,"priority":"…","start_date":"2026-11-12","due_date":"2026-11-12","percent_done":12.5,"assignee_ids":[],"tag_ids":[],"completed":"…","parent_id":7}'const res = await fetch('https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages/1', {
method: 'PATCH',
headers: { 'X-API-Key': process.env.BRAMBLE_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({"subject":"…","description":"string","type_id":7,"status_id":7,"category_id":7,"version_id":7,"priority":"…","start_date":"2026-11-12","due_date":"2026-11-12","percent_done":12.5,"assignee_ids":[],"tag_ids":[],"completed":"…","parent_id":7}),
});
const data = await res.json();import os, requests
r = requests.patch(
"https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages/1",
headers={"X-API-Key": os.environ["BRAMBLE_KEY"]},
json={"subject":"…","description":"string","type_id":7,"status_id":7,"category_id":7,"version_id":7,"priority":"…","start_date":"2026-11-12","due_date":"2026-11-12","percent_done":12.5,"assignee_ids":[],"tag_ids":[],"completed":"…","parent_id":7},
)
r.raise_for_status()
data = r.json()$headers = @{ 'X-API-Key' = $env:BRAMBLE_KEY }
$body = '{"subject":"…","description":"string","type_id":7,"status_id":7,"category_id":7,"version_id":7,"priority":"…","start_date":"2026-11-12","due_date":"2026-11-12","percent_done":12.5,"assignee_ids":[],"tag_ids":[],"completed":"…","parent_id":7}'
Invoke-RestMethod -Method PATCH -Uri 'https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages/1' -Headers $headers -ContentType 'application/json' -Body $body#Move a work package between statuses/positions (Board drag-drop / reorder)
/v1/app/project/projects/:id/work-packages/:wpId/moveMove a work package between statuses/positions (Board drag-drop / reorder). Requires at least member role on the project. Notifies current assignees of the status change.
- Address
https://<your-org>.brambleit.cloud/api/v1/app/project/projects/:id/work-packages/:wpId/move- Requires
- Signed-in session,
X-API-Key, or a Bramble app access token (Authorization: Bearer).
Licence: Projects.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | integer | |
wpIdrequired | integer |
Request body JSON
| Name | Type | Description |
|---|---|---|
status_idrequired | integer | |
positionrequired | integer | |
order | array of any |
Response 200
| Field | Type | Description |
|---|---|---|
ok | boolean |
Example response
{
"ok": true
}Errors
| Status | Message |
|---|---|
| 400 | status_id and position are required |
Example request
curl -X PATCH 'https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages/1/move' \
-H "X-API-Key: $BRAMBLE_KEY" \
-H "Content-Type: application/json" \
-d '{"status_id":7,"position":1,"order":[]}'const res = await fetch('https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages/1/move', {
method: 'PATCH',
headers: { 'X-API-Key': process.env.BRAMBLE_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({"status_id":7,"position":1,"order":[]}),
});
const data = await res.json();import os, requests
r = requests.patch(
"https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages/1/move",
headers={"X-API-Key": os.environ["BRAMBLE_KEY"]},
json={"status_id":7,"position":1,"order":[]},
)
r.raise_for_status()
data = r.json()$headers = @{ 'X-API-Key' = $env:BRAMBLE_KEY }
$body = '{"status_id":7,"position":1,"order":[]}'
Invoke-RestMethod -Method PATCH -Uri 'https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages/1/move' -Headers $headers -ContentType 'application/json' -Body $body#Delete a work package (soft delete)
/v1/app/project/projects/:id/work-packages/:wpIdDelete a work package (soft delete). Requires at least member role on the project. Children are reparented to top-level first.
- Address
https://<your-org>.brambleit.cloud/api/v1/app/project/projects/:id/work-packages/:wpId- Requires
- Signed-in session,
X-API-Key, or a Bramble app access token (Authorization: Bearer).
Licence: Projects.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | integer | |
wpIdrequired | integer |
Response 200
| Field | Type | Description |
|---|---|---|
ok | boolean |
Example response
{
"ok": true
}Example request
curl -X DELETE 'https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages/1' \
-H "X-API-Key: $BRAMBLE_KEY"const res = await fetch('https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages/1', {
method: 'DELETE',
headers: { 'X-API-Key': process.env.BRAMBLE_KEY },
});
const data = await res.json();import os, requests
r = requests.delete(
"https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages/1",
headers={"X-API-Key": os.environ["BRAMBLE_KEY"]},
)
r.raise_for_status()
data = r.json()$headers = @{ 'X-API-Key' = $env:BRAMBLE_KEY }
Invoke-RestMethod -Method DELETE -Uri 'https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages/1' -Headers $headers#List every work-package relation edge in the project
/v1/app/project/projects/:id/relationsList every work-package relation edge in the project. Requires at least viewer role on the project. Used by the Gantt view to draw dependency arrows without an N+1 fetch per work package.
- Address
https://<your-org>.brambleit.cloud/api/v1/app/project/projects/:id/relations- Requires
- Signed-in session,
X-API-Key, or a Bramble app access token (Authorization: Bearer).
Licence: Projects.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | integer |
Response 200
| Field | Type | Description |
|---|---|---|
relations | array of object | |
relations[].work_package_id | integer | |
relations[].related_work_package_id | integer | |
relations[].relation_type | string: "relates" | "blocks" | "blocked_by" | "precedes" | "follows" | "duplicates" | "duplicated_by" |
Example response
{
"relations": [
{
"work_package_id": 7,
"related_work_package_id": 7,
"relation_type": "relates"
}
]
}Example request
curl -X GET 'https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/relations' \
-H "X-API-Key: $BRAMBLE_KEY"const res = await fetch('https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/relations', {
method: 'GET',
headers: { 'X-API-Key': process.env.BRAMBLE_KEY },
});
const data = await res.json();import os, requests
r = requests.get(
"https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/relations",
headers={"X-API-Key": os.environ["BRAMBLE_KEY"]},
)
r.raise_for_status()
data = r.json()$headers = @{ 'X-API-Key' = $env:BRAMBLE_KEY }
Invoke-RestMethod -Method GET -Uri 'https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/relations' -Headers $headers#List a single work package's relations
/v1/app/project/projects/:id/work-packages/:wpId/relationsList a single work package's relations. Requires at least viewer role on the project.
- Address
https://<your-org>.brambleit.cloud/api/v1/app/project/projects/:id/work-packages/:wpId/relations- Requires
- Signed-in session,
X-API-Key, or a Bramble app access token (Authorization: Bearer).
Licence: Projects.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | integer | |
wpIdrequired | integer |
Response 200
| Field | Type | Description |
|---|---|---|
relations | array of object | |
relations[].id | integer | |
relations[].project_id | integer | |
relations[].work_package_id | integer | |
relations[].related_work_package_id | integer | |
relations[].relation_type | string: "relates" | "blocks" | "blocked_by" | "precedes" | "follows" | "duplicates" | "duplicated_by" | |
relations[].created_by | integer | |
relations[].created_at | string (date-time) | |
relations[].related_subject | string | |
relations[].related_status_id | integer | |
relations[].related_type_id | integer |
Example response
{
"relations": [
{
"id": 42,
"project_id": 7,
"work_package_id": 7,
"related_work_package_id": 7,
"relation_type": "relates",
"created_by": 1,
"created_at": "2026-11-12T09:30:00.000Z",
"related_subject": "Example related subject",
"related_status_id": 7,
"related_type_id": 7
}
]
}Example request
curl -X GET 'https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages/1/relations' \
-H "X-API-Key: $BRAMBLE_KEY"const res = await fetch('https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages/1/relations', {
method: 'GET',
headers: { 'X-API-Key': process.env.BRAMBLE_KEY },
});
const data = await res.json();import os, requests
r = requests.get(
"https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages/1/relations",
headers={"X-API-Key": os.environ["BRAMBLE_KEY"]},
)
r.raise_for_status()
data = r.json()$headers = @{ 'X-API-Key' = $env:BRAMBLE_KEY }
Invoke-RestMethod -Method GET -Uri 'https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages/1/relations' -Headers $headers#Create a relation between two work packages
/v1/app/project/projects/:id/work-packages/:wpId/relationsCreate a relation between two work packages. Requires at least member role on the project. Also creates the inverse relation on the related work package (e.g. blocks/blocked_by).
- Address
https://<your-org>.brambleit.cloud/api/v1/app/project/projects/:id/work-packages/:wpId/relations- Requires
- Signed-in session,
X-API-Key, or a Bramble app access token (Authorization: Bearer).
Licence: Projects.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | integer | |
wpIdrequired | string |
Request body JSON
| Name | Type | Description |
|---|---|---|
related_idrequired | string | |
relation_type | string |
Response 201
| Field | Type | Description |
|---|---|---|
ok | boolean |
Example response
{
"ok": true
}Errors
| Status | Message |
|---|---|
| 400 | related_id is required and must differ from the work package |
| 400 | Invalid relation_type |
| 404 | Related work package not found |
| 409 | That relation already exists |
Example request
curl -X POST 'https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages/string/relations' \
-H "X-API-Key: $BRAMBLE_KEY" \
-H "Content-Type: application/json" \
-d '{"related_id":"string","relation_type":"string"}'const res = await fetch('https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages/string/relations', {
method: 'POST',
headers: { 'X-API-Key': process.env.BRAMBLE_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({"related_id":"string","relation_type":"string"}),
});
const data = await res.json();import os, requests
r = requests.post(
"https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages/string/relations",
headers={"X-API-Key": os.environ["BRAMBLE_KEY"]},
json={"related_id":"string","relation_type":"string"},
)
r.raise_for_status()
data = r.json()$headers = @{ 'X-API-Key' = $env:BRAMBLE_KEY }
$body = '{"related_id":"string","relation_type":"string"}'
Invoke-RestMethod -Method POST -Uri 'https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages/string/relations' -Headers $headers -ContentType 'application/json' -Body $body#Delete a work-package relation
/v1/app/project/projects/:id/work-packages/:wpId/relations/:relIdDelete a work-package relation. Requires at least member role on the project. Also deletes the corresponding inverse relation.
- Address
https://<your-org>.brambleit.cloud/api/v1/app/project/projects/:id/work-packages/:wpId/relations/:relId- Requires
- Signed-in session,
X-API-Key, or a Bramble app access token (Authorization: Bearer).
Licence: Projects.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | integer | |
wpIdrequired | integer | |
relIdrequired | integer |
Response 200
| Field | Type | Description |
|---|---|---|
ok | boolean |
Example response
{
"ok": true
}Errors
| Status | Message |
|---|---|
| 404 | Relation not found |
Example request
curl -X DELETE 'https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages/1/relations/1' \
-H "X-API-Key: $BRAMBLE_KEY"const res = await fetch('https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages/1/relations/1', {
method: 'DELETE',
headers: { 'X-API-Key': process.env.BRAMBLE_KEY },
});
const data = await res.json();import os, requests
r = requests.delete(
"https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages/1/relations/1",
headers={"X-API-Key": os.environ["BRAMBLE_KEY"]},
)
r.raise_for_status()
data = r.json()$headers = @{ 'X-API-Key' = $env:BRAMBLE_KEY }
Invoke-RestMethod -Method DELETE -Uri 'https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages/1/relations/1' -Headers $headers#List a work package's comments
/v1/app/project/projects/:id/work-packages/:wpId/commentsList a work package's comments. Requires at least viewer role on the project.
- Address
https://<your-org>.brambleit.cloud/api/v1/app/project/projects/:id/work-packages/:wpId/comments- Requires
- Signed-in session,
X-API-Key, or a Bramble app access token (Authorization: Bearer).
Licence: Projects.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | integer | |
wpIdrequired | integer |
Response 200
| Field | Type | Description |
|---|---|---|
comments | array of any |
Example response
{
"comments": []
}Example request
curl -X GET 'https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages/1/comments' \
-H "X-API-Key: $BRAMBLE_KEY"const res = await fetch('https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages/1/comments', {
method: 'GET',
headers: { 'X-API-Key': process.env.BRAMBLE_KEY },
});
const data = await res.json();import os, requests
r = requests.get(
"https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages/1/comments",
headers={"X-API-Key": os.environ["BRAMBLE_KEY"]},
)
r.raise_for_status()
data = r.json()$headers = @{ 'X-API-Key' = $env:BRAMBLE_KEY }
Invoke-RestMethod -Method GET -Uri 'https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages/1/comments' -Headers $headers#Add a comment to a work package
/v1/app/project/projects/:id/work-packages/:wpId/commentsAdd a comment to a work package. Requires at least member role on the project. Notifies assignees/creator ("comment") and any valid @mentioned project members ("mention", which takes priority).
- Address
https://<your-org>.brambleit.cloud/api/v1/app/project/projects/:id/work-packages/:wpId/comments- Requires
- Signed-in session,
X-API-Key, or a Bramble app access token (Authorization: Bearer).
Licence: Projects.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | integer | |
wpIdrequired | integer |
Request body JSON
| Name | Type | Description |
|---|---|---|
bodyrequired | string | |
mentioned_user_ids | array of any |
Response 201
| Field | Type | Description |
|---|---|---|
comment | object | |
comment.user | any |
Example response
{
"comment": {
"…rows[0]": "…",
"user": null
}
}Errors
| Status | Message |
|---|---|
| 400 | body is required |
| 404 | Work package not found |
Example request
curl -X POST 'https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages/1/comments' \
-H "X-API-Key: $BRAMBLE_KEY" \
-H "Content-Type: application/json" \
-d '{"body":"<p>…</p>","mentioned_user_ids":[]}'const res = await fetch('https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages/1/comments', {
method: 'POST',
headers: { 'X-API-Key': process.env.BRAMBLE_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({"body":"<p>…</p>","mentioned_user_ids":[]}),
});
const data = await res.json();import os, requests
r = requests.post(
"https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages/1/comments",
headers={"X-API-Key": os.environ["BRAMBLE_KEY"]},
json={"body":"<p>…</p>","mentioned_user_ids":[]},
)
r.raise_for_status()
data = r.json()$headers = @{ 'X-API-Key' = $env:BRAMBLE_KEY }
$body = '{"body":"<p>…</p>","mentioned_user_ids":[]}'
Invoke-RestMethod -Method POST -Uri 'https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages/1/comments' -Headers $headers -ContentType 'application/json' -Body $body#Edit a work-package comment
/v1/app/project/projects/:id/work-packages/:wpId/comments/:commentIdEdit a work-package comment. Requires at least viewer role on the project to reach the check, but only the comment's author may actually edit it.
- Address
https://<your-org>.brambleit.cloud/api/v1/app/project/projects/:id/work-packages/:wpId/comments/:commentId- Requires
- Signed-in session,
X-API-Key, or a Bramble app access token (Authorization: Bearer).
Licence: Projects.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | integer | |
wpIdrequired | integer | |
commentIdrequired | integer |
Request body JSON
| Name | Type | Description |
|---|---|---|
bodyrequired | string |
Response 200
| Field | Type | Description |
|---|---|---|
comment | any |
Example response
{
"comment": null
}Errors
| Status | Message |
|---|---|
| 400 | body is required |
| 404 | Comment not found |
| 403 | You can only edit your own comments |
Example request
curl -X PATCH 'https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages/1/comments/1' \
-H "X-API-Key: $BRAMBLE_KEY" \
-H "Content-Type: application/json" \
-d '{"body":"<p>…</p>"}'const res = await fetch('https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages/1/comments/1', {
method: 'PATCH',
headers: { 'X-API-Key': process.env.BRAMBLE_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({"body":"<p>…</p>"}),
});
const data = await res.json();import os, requests
r = requests.patch(
"https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages/1/comments/1",
headers={"X-API-Key": os.environ["BRAMBLE_KEY"]},
json={"body":"<p>…</p>"},
)
r.raise_for_status()
data = r.json()$headers = @{ 'X-API-Key' = $env:BRAMBLE_KEY }
$body = '{"body":"<p>…</p>"}'
Invoke-RestMethod -Method PATCH -Uri 'https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages/1/comments/1' -Headers $headers -ContentType 'application/json' -Body $body#Delete a work-package comment (soft delete)
/v1/app/project/projects/:id/work-packages/:wpId/comments/:commentIdDelete a work-package comment (soft delete). Requires at least viewer role on the project to reach the check; the comment's author or an admin+ may delete it.
- Address
https://<your-org>.brambleit.cloud/api/v1/app/project/projects/:id/work-packages/:wpId/comments/:commentId- Requires
- Signed-in session,
X-API-Key, or a Bramble app access token (Authorization: Bearer).
Licence: Projects.
Path parameters
| Name | Type | Description |
|---|---|---|
idrequired | integer | |
wpIdrequired | integer | |
commentIdrequired | integer |
Response 200
| Field | Type | Description |
|---|---|---|
ok | boolean |
Example response
{
"ok": true
}Errors
| Status | Message |
|---|---|
| 404 | Comment not found |
| 403 | Insufficient permissions |
Example request
curl -X DELETE 'https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages/1/comments/1' \
-H "X-API-Key: $BRAMBLE_KEY"const res = await fetch('https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages/1/comments/1', {
method: 'DELETE',
headers: { 'X-API-Key': process.env.BRAMBLE_KEY },
});
const data = await res.json();import os, requests
r = requests.delete(
"https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages/1/comments/1",
headers={"X-API-Key": os.environ["BRAMBLE_KEY"]},
)
r.raise_for_status()
data = r.json()$headers = @{ 'X-API-Key' = $env:BRAMBLE_KEY }
Invoke-RestMethod -Method DELETE -Uri 'https://<your-org>.brambleit.cloud/api/v1/app/project/projects/42/work-packages/1/comments/1' -Headers $headersWas this page helpful?
Thanks for your feedback.