document added resources

pull/6319/head
Jens Ulferts 7 years ago
parent 57c8aeb5aa
commit 90189e1fb1
No known key found for this signature in database
GPG Key ID: 3CAA4B1182CF5308
  1. 2
      docs/api/apiv3-documentation.apib
  2. 667
      docs/api/apiv3/endpoints/attachments.apib
  3. 86
      docs/api/apiv3/endpoints/posts.apib
  4. 86
      docs/api/apiv3/endpoints/wiki_pages.apib
  5. 18
      docs/api/apiv3/endpoints/work-packages.apib

@ -15,6 +15,7 @@ FORMAT: 1A
<!-- include(apiv3/endpoints/forms.apib) -->
<!-- include(apiv3/endpoints/groups.apib) -->
<!-- include(apiv3/endpoints/help_texts.apib) -->
<!-- include(apiv3/endpoints/posts.apib) -->
<!-- include(apiv3/endpoints/principals.apib) -->
<!-- include(apiv3/endpoints/priorities.apib) -->
<!-- include(apiv3/endpoints/projects.apib) -->
@ -32,4 +33,5 @@ FORMAT: 1A
<!-- include(apiv3/endpoints/user-preferences.apib) -->
<!-- include(apiv3/endpoints/users.apib) -->
<!-- include(apiv3/endpoints/versions.apib) -->
<!-- include(apiv3/endpoints/wiki_pages.apib) -->
<!-- include(apiv3/endpoints/work-packages.apib) -->

@ -5,9 +5,9 @@ container (e.g. a work package or a board message).
## Actions
| Link | Description | Condition |
|:-------------------:|----------------------------------------------------------------------| -------------------------------------------- |
| delete | Deletes this attachment | **Permission**: edit on attachment container |
| Link | Description | Condition |
|:-------------------:|----------------------------------------------------------------------| -------------------------------------------- |
| delete | Deletes this attachment | **Permission**: edit on attachment container or being the author for attachments without container |
## Linked Properties
| Link | Description | Type | Constraints | Supported operations |
@ -21,6 +21,7 @@ container (e.g. a work package or a board message).
| Property | Description | Type | Constraints | Supported operations |
|:------------:| ----------------------------------------------- | ----------- | ----------- | -------------------- |
| id | Attachment's id | Integer | x > 0 | READ |
| title | The name of the file | String | not null | READ |
| fileName | The name of the uploaded file | String | not null | READ |
| fileSize | The size of the uploaded file in Bytes | Integer | x >= 0 | READ |
| description | A user provided description of the file | Formattable | not null | READ |
@ -28,6 +29,97 @@ container (e.g. a work package or a board message).
| digest | A checksum for the files content | Digest | not null | READ |
| createdAt | Time of creation | DateTime | not null | READ |
## Attachments [/api/v3/attachments]
## Create Attachment [POST]
Clients can create attachments without a container first and attach them later on.
This is useful if the container does not exist at the time the attachment is uploaded.
After the upload, the client can then claim such containerless attachments for any resource eligible (e.g. WorkPackage) on subsequent requests.
The upload and the claiming *must* be done for the same user account. Attachments uploaded by another user cannot be claimed and
once claimed for a resource, they cannot be claimed by another.
The upload request must be of type `multipart/form-data` with exactly two parts.
The first part *must* be called `metadata`. Its content type is expected to be `application/json`,
the body *must* be a single JSON object, containing at least the `fileName` and optionally the attachments `description`.
The second part *must* be called `file`, its content type *should* match the mime type of the file.
The body *must* be the raw content of the file.
Note that a `filename` *must* be indicated in the `Content-Disposition` of this part, although it will be ignored.
Instead the `fileName` inside the JSON of the metadata part will be used.
+ Request (multipart/form-data)
--boundary-delimiter
Content-Disposition: form-data; name="metadata"
Content-Type: application/json; charset=UTF-8
{
"fileName": "cute-cat.png",
"description": {
"raw": "A cute kitty, cuddling with its friends!"
}
}
--boundary-delimiter
Content-Disposition: form-data; name="file"; filename="attachment"
Content-Type: image/png
PNG file data
--boundary-delimiter--
+ Response 200 (application/hal+json)
[Attachment][]
+ Response 400 (application/hal+json)
Returned if the client sends a not understandable request. Reasons include:
* Omitting one of the required parts (metadata and file)
* sending unparsable JSON in the metadata part
+ Body
{
"_type": "Error",
"errorIdentifier": "urn:openproject-org:api:v3:errors:InvalidRequestBody",
"message": "The request could not be parsed as JSON."
}
+ Response 403 (application/hal+json)
Returned if the client does not have sufficient permissions.
**Required permission:** At least one permission in any project: edit work package, add work package, edit messages, edit wiki pages (plugins might extend this list)
+ Body
{
"_type": "Error",
"errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
"message": "You are not allowed to delete this attachment."
}
+ Response 422 (application/hal+json)
Returned if the client tries to send an invalid attachment.
Reasons are:
* Omitting the file name (`fileName` property of metadata part)
* Sending a file that is too large
+ Body
{
"_type": "Error",
"errorIdentifier": "urn:openproject-org:api:v3:errors:PropertyConstraintViolation",
"message": "File is too large (maximum size is 5242880 Bytes)."
}
## Attachment [/api/v3/attachments/{id}]
+ Model
@ -79,7 +171,7 @@ container (e.g. a work package or a board message).
Returned if the attachment does not exist or the client does not have sufficient permissions
to see it.
**Required permission:** view permission for the container of the attachment
**Required permission:** view permission for the container of the attachment or being the author for attachments without container
*Note: A client without sufficient permissions shall not be able to test for the existence of an attachment.
That's why a 404 is returned here, even if a 403 might be more appropriate.*
@ -112,7 +204,7 @@ Permanently deletes the specified attachment.
Returned if the client does not have sufficient permissions.
**Required permission:** edit permission for the container of the attachment
**Required permission:** edit permission for the container of the attachment or being the author for attachments without container
*Note that you will only receive this error, if you are at least allowed to see the attachment.*
@ -129,7 +221,7 @@ Permanently deletes the specified attachment.
Returned if the attachment does not exist or the client does not have sufficient permissions
to see it.
**Required permission:** view permission for the container of the attachment
**Required permission:** view permission for the container of the attachment or being the author for attachments without container
*Note: A client without sufficient permissions shall not be able to test for the existence of an attachment.
That's why a 404 is returned here, even if a 403 might be more appropriate.*
@ -142,6 +234,569 @@ Permanently deletes the specified attachment.
"message": "The specified attachment does not exist."
}
# Attachments by post [/api/v3/posts/{id}/attachments]
+ Model
+ Body
{
"_type": "Collection",
"total": 1,
"count": 1,
"_embedded": {
"elements": [
{
"_type": "Attachment",
"id": 376,
"fileName": "some.gif",
"fileSize": 3521772,
"description": {
"format": "plain",
"raw": "",
"html": ""
},
"contentType": "image/gif",
"digest": {
"algorithm": "md5",
"hash": "7ac9c97ef73d47127f590788b84c0c1c"
},
"createdAt": "2018-06-01T07:24:19Z",
"_links": {
"self": {
"href": "/api/v3/attachments/376",
"title": "200.gif"
},
"author": {
"href": "/api/v3/users/1",
"title": "OpenProject Admin"
},
"container": {
"href": "/api/v3/posts/72",
"title": "wiki"
},
"downloadLocation": {
"href": "/api/v3/attachments/376/content"
},
"delete": {
"href": "/api/v3/attachments/376",
"method": "delete"
}
}
}
]
},
"_links": {
"self": {
"href": "/api/v3/posts/72/attachments"
}
}
}
## List attachments [GET]
+ Parameters
+ id (required, integer, `1`) ... ID of the post whose attachments will be listed
+ Response 200 (application/hal+json)
[Attachments by post][]
+ Response 404 (application/hal+json)
Returned if the post does not exist or the client does not have sufficient permissions
to see it.
**Required permission:** view messages
*Note: A client without sufficient permissions shall not be able to test for the existence of a post.
That's why a 404 is returned here, even if a 403 might be more appropriate.*
+ Body
{
"_type": "Error",
"errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
"message": "The requested resource could not be found."
}
## Add attachment [POST]
Adds an attachment with the post as it's container.
See [the general specification for uploading attachments](#attachments-attachments) for details.
+ Parameters
+ id (required, integer, `1`) ... ID of the post to receive the attachment
+ Request (multipart/form-data)
--boundary-delimiter
Content-Disposition: form-data; name="metadata"
Content-Type: application/json; charset=UTF-8
{
"fileName": "cute-cat.png",
"description": {
"raw": "A cute kitty, cuddling with its friends!"
}
}
--boundary-delimiter
Content-Disposition: form-data; name="file"; filename="attachment"
Content-Type: image/png
PNG file data
--boundary-delimiter--
+ Response 200 (application/hal+json)
+ Body
{
"_embedded": {
"author": {
"_type": "User",
"id": 1,
"name": "OpenProject Admin",
"createdAt": "2015-03-20T12:56:52Z",
"updatedAt": "2018-05-29T13:57:44Z",
"login": "admin",
"admin": true,
"firstName": "OpenProject",
"lastName": "Admin",
"email": null,
"avatar": "",
"status": "active",
"identityUrl": null,
"_links": {
"self": {
"href": "/api/v3/users/1",
"title": "OpenProject Admin"
},
"showUser": {
"href": "/users/1",
"type": "text/html"
},
"updateImmediately": {
"href": "/api/v3/users/1",
"title": "Update admin",
"method": "patch"
},
"lock": {
"href": "/api/v3/users/1/lock",
"title": "Set lock on admin",
"method": "post"
}
}
},
"container": {
"_type": "Post",
"id": 150,
"subject": "sfsdfsdfsdfsdf",
"_links": {
"self": {
"href": "/api/v3/posts/150"
},
"attachments": {
"href": "/api/v3/posts/150/attachments"
},
"addAttachment": {
"href": "/api/v3/posts/150/attachments",
"method": "post"
},
"project": {
"href": "/api/v3/projects/12",
"title": "Demo project"
}
}
}
},
"_type": "Attachment",
"id": 377,
"fileName": "some.gif",
"fileSize": 3521772,
"description": {
"format": "plain",
"raw": "",
"html": ""
},
"contentType": "image/gif",
"digest": {
"algorithm": "md5",
"hash": "7ac9c97ef73d47127f590788b84c0c1c"
},
"createdAt": "2018-06-01T07:53:36Z",
"_links": {
"self": {
"href": "/api/v3/attachments/377",
"title": "200.gif"
},
"author": {
"href": "/api/v3/users/1",
"title": "OpenProject Admin"
},
"container": {
"href": "/api/v3/posts/150",
"title": "sfsdfsdfsdfsdf"
},
"downloadLocation": {
"href": "/api/v3/attachments/377/content"
},
"delete": {
"href": "/api/v3/attachments/377",
"method": "delete"
}
}
}
+ Response 400 (application/hal+json)
Returned if the client sends a not understandable request. Reasons include:
* Omitting one of the required parts (metadata and file)
* sending unparsable JSON in the metadata part
+ Body
{
"_type": "Error",
"errorIdentifier": "urn:openproject-org:api:v3:errors:InvalidRequestBody",
"message": "The request could not be parsed as JSON."
}
+ Response 403 (application/hal+json)
Returned if the client does not have sufficient permissions.
**Required permission:** edit messages
*Note that you will only receive this error, if you are at least allowed to see the wiki page*
+ Body
{
"_type": "Error",
"errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
"message": "You are not allowed to delete this attachment."
}
+ Response 404 (application/hal+json)
Returned if the post does not exist or the client does not have sufficient permissions
to see it.
**Required permission:** view messages
*Note: A client without sufficient permissions shall not be able to test for the existence of a post.
That's why a 404 is returned here, even if a 403 might be more appropriate.*
+ Body
{
"_type": "Error",
"errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
"message": "The requested resource could not be found."
}
+ Response 422 (application/hal+json)
Returned if the client tries to send an invalid attachment.
Reasons are:
* Omitting the file name (`fileName` property of metadata part)
* Sending a file that is too large
+ Body
{
"_type": "Error",
"errorIdentifier": "urn:openproject-org:api:v3:errors:PropertyConstraintViolation",
"message": "File is too large (maximum size is 5242880 Bytes)."
}
# Attachments by wiki page [/api/v3/wiki_pages/{id}/attachments]
+ Model
+ Body
{
"_type": "Collection",
"total": 1,
"count": 1,
"_embedded": {
"elements": [
{
"_type": "Attachment",
"id": 376,
"fileName": "some.gif",
"fileSize": 3521772,
"description": {
"format": "plain",
"raw": "",
"html": ""
},
"contentType": "image/gif",
"digest": {
"algorithm": "md5",
"hash": "7ac9c97ef73d47127f590788b84c0c1c"
},
"createdAt": "2018-06-01T07:24:19Z",
"_links": {
"self": {
"href": "/api/v3/attachments/376",
"title": "200.gif"
},
"author": {
"href": "/api/v3/users/1",
"title": "OpenProject Admin"
},
"container": {
"href": "/api/v3/wiki_pages/72",
"title": "wiki"
},
"downloadLocation": {
"href": "/api/v3/attachments/376/content"
},
"delete": {
"href": "/api/v3/attachments/376",
"method": "delete"
}
}
}
]
},
"_links": {
"self": {
"href": "/api/v3/wiki_pages/72/attachments"
}
}
}
## List attachments [GET]
+ Parameters
+ id (required, integer, `1`) ... ID of the wiki page whose attachments will be listed
+ Response 200 (application/hal+json)
[Attachments by wiki page][]
+ Response 404 (application/hal+json)
Returned if the wiki page does not exist or the client does not have sufficient permissions
to see it.
**Required permission:** view wiki pages
*Note: A client without sufficient permissions shall not be able to test for the existence of a work package.
That's why a 404 is returned here, even if a 403 might be more appropriate.*
+ Body
{
"_type": "Error",
"errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
"message": "The requested resource could not be found."
}
## Add attachment [POST]
Adds an attachment with the wiki page as it's container.
See [the general specification for uploading attachments](#attachments-attachments) for details.
+ Parameters
+ id (required, integer, `1`) ... ID of the wiki page to receive the attachment
+ Request (multipart/form-data)
--boundary-delimiter
Content-Disposition: form-data; name="metadata"
Content-Type: application/json; charset=UTF-8
{
"fileName": "cute-cat.png",
"description": {
"raw": "A cute kitty, cuddling with its friends!"
}
}
--boundary-delimiter
Content-Disposition: form-data; name="file"; filename="attachment"
Content-Type: image/png
PNG file data
--boundary-delimiter--
+ Response 200 (application/hal+json)
+ Body
{
"_embedded": {
"author": {
"_type": "User",
"id": 1,
"name": "OpenProject Admin",
"createdAt": "2015-03-20T12:56:52Z",
"updatedAt": "2018-05-29T13:57:44Z",
"login": "admin",
"admin": true,
"firstName": "OpenProject",
"lastName": "Admin",
"email": null,
"avatar": "",
"status": "active",
"identityUrl": null,
"_links": {
"self": {
"href": "/api/v3/users/1",
"title": "OpenProject Admin"
},
"showUser": {
"href": "/users/1",
"type": "text/html"
},
"updateImmediately": {
"href": "/api/v3/users/1",
"title": "Update admin",
"method": "patch"
},
"lock": {
"href": "/api/v3/users/1/lock",
"title": "Set lock on admin",
"method": "post"
}
}
},
"container": {
"_type": "WikiPage",
"id": 72,
"title": "wiki",
"_links": {
"self": {
"href": "/api/v3/wiki_pages/72"
},
"attachments": {
"href": "/api/v3/wiki_pages/72/attachments"
},
"addAttachment": {
"href": "/api/v3/wiki_pages/72/attachments",
"method": "post"
},
"project": {
"href": "/api/v3/projects/12",
"title": "Demo project"
}
}
}
},
"_type": "Attachment",
"id": 376,
"fileName": "some.gif",
"fileSize": 3521772,
"description": {
"format": "plain",
"raw": "",
"html": ""
},
"contentType": "image/gif",
"digest": {
"algorithm": "md5",
"hash": "7ac9c97ef73d47127f590788b84c0c1c"
},
"createdAt": "2018-06-01T07:24:19Z",
"_links": {
"self": {
"href": "/api/v3/attachments/376",
"title": "200.gif"
},
"author": {
"href": "/api/v3/users/1",
"title": "OpenProject Admin"
},
"container": {
"href": "/api/v3/wiki_pages/72",
"title": "wiki"
},
"downloadLocation": {
"href": "/api/v3/attachments/376/content"
},
"delete": {
"href": "/api/v3/attachments/376",
"method": "delete"
}
}
}
+ Response 400 (application/hal+json)
Returned if the client sends a not understandable request. Reasons include:
* Omitting one of the required parts (metadata and file)
* sending unparsable JSON in the metadata part
+ Body
{
"_type": "Error",
"errorIdentifier": "urn:openproject-org:api:v3:errors:InvalidRequestBody",
"message": "The request could not be parsed as JSON."
}
+ Response 403 (application/hal+json)
Returned if the client does not have sufficient permissions.
**Required permission:** edit wiki pages
*Note that you will only receive this error, if you are at least allowed to see the wiki page*
+ Body
{
"_type": "Error",
"errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
"message": "You are not allowed to delete this attachment."
}
+ Response 404 (application/hal+json)
Returned if the wiki page does not exist or the client does not have sufficient permissions
to see it.
**Required permission:** view wiki pages
*Note: A client without sufficient permissions shall not be able to test for the existence of a wiki page
That's why a 404 is returned here, even if a 403 might be more appropriate.*
+ Body
{
"_type": "Error",
"errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
"message": "The requested resource could not be found."
}
+ Response 422 (application/hal+json)
Returned if the client tries to send an invalid attachment.
Reasons are:
* Omitting the file name (`fileName` property of metadata part)
* Sending a file that is too large
+ Body
{
"_type": "Error",
"errorIdentifier": "urn:openproject-org:api:v3:errors:PropertyConstraintViolation",
"message": "File is too large (maximum size is 5242880 Bytes)."
}
# Attachments by work package [/api/v3/work_packages/{id}/attachments]
+ Model

@ -0,0 +1,86 @@
# Group Posts
Represents a post in a board. Posts are also referred to as messages in the application.
*This resource is currently a stub*
## Actions
| Link | Description | Condition |
|:-------------------:|--------------------------------| --------------------------------------- |
| addAttachment | Attach a file to the post | **Permission**: edit messages |
## Linked Properties
| Property | Description | Type | Constraints | Supported operations |
| :--------------: | ------------------------------------------------------ | ----------- | -------------- | -------------------- |
| self | This post | Post | not null | READ |
| attachments | The files attached to this post | Collection | | READ |
| project | The project the post belongs to | Project | not null | READ |
## Local Properties
| Property | Description | Type | Constraints | Supported operations |
| :--------------: | ------------------------------------------- | ----------- | ------------------------------------ | -------------------- |
| id | Identifier of this post | Integer | x > 0 | READ |
| subject | The posts's subject | String | not null | READ |
## Post [/api/v3/posts/{id}]
+ Model
+ Body
{
"_type": "Post",
"id": 1,
"subject": "A post with a subject",
"_embedded": {
"project": {
"_type": "Project",
"id": 1,
<-- abbreviated -->
}
}
},
"_links": {
"self": {
"href": "/api/v3/posts/1"
},
"attachments": {
"href": "/api/v3/posts/1/attachments"
},
"addAttachment": {
"href": "/api/v3/posts/1/attachments",
"method": "post"
},
"project": {
"href": "/api/v3/projects/1",
"title": "A project with a title"
}
}
}
## View Post [GET]
Retrieve an individual post as identified by the id parameter
+ Parameters
+ id (required, integer, `1`) ... Post's identifier
+ Response 200 (application/hal+json)
[Post][]
+ Response 404 (application/hal+json)
Returned if the post does not exist or the client does not have sufficient permissions to see it.
**Required permission:** view messages in the post's project
+ Body
{
"_type": "Error",
"errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
"message": "The requested resource could not be found."
}

@ -0,0 +1,86 @@
# Group Wiki Pages
Represents an individual page in a project's wiki.
*This resource is currently a stub*
## Actions
| Link | Description | Condition |
|:-------------------:|----------------------------------------------------------------------| --------------------------------------- |
| addAttachment | Attach a file to the wiki page | **Permission**: edit wiki page |
## Linked Properties
| Property | Description | Type | Constraints | Supported operations |
| :--------------: | ------------------------------------------------------ | ----------- | -------------- | -------------------- |
| self | This wiki page | WikiPage | not null | READ |
| attachments | The files attached to this wiki page | Collection | | READ |
| project | The project the wiki page belongs to | Project | not null | READ |
## Local Properties
| Property | Description | Type | Constraints | Supported operations |
| :--------------: | ------------------------------------------- | ----------- | ------------------------------------ | -------------------- |
| id | Identifier of this wiki page | Integer | x > 0 | READ |
| title | The wiki page's title | String | not null | READ |
## Wiki Page [/api/v3/wiki_pages/{id}]
+ Model
+ Body
{
"_type": "WikiPage",
"id": 72,
"title": "A wiki page with a name",
"_embedded": {
"project": {
"_type": "Project",
"id": 12,
<-- abbreviated -->
}
}
},
"_links": {
"self": {
"href": "/api/v3/wiki_pages/72"
},
"attachments": {
"href": "/api/v3/wiki_pages/72/attachments"
},
"addAttachment": {
"href": "/api/v3/wiki_pages/72/attachments",
"method": "post"
},
"project": {
"href": "/api/v3/projects/12",
"title": "some project"
}
}
}
## View Wiki Page [GET]
Retrieve an individual wiki page as identified by the id parameter
+ Parameters
+ id (required, integer, `1`) ... Wiki page identifier
+ Response 200 (application/hal+json)
[Wiki Page][]
+ Response 404 (application/hal+json)
Returned if the wiki page does not exist or the client does not have sufficient permissions to see it.
**Required permission:** view wiki page in the page's project
+ Body
{
"_type": "Error",
"errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
"message": "The requested resource could not be found."
}

@ -23,7 +23,7 @@
| self | This work package | WorkPackage | not null | READ | |
| schema | The schema of this work package | Schema | not null | READ | |
| ancestors | Array of all visible ancestors of the work package, with the root node being the first element | Collection | not null | READ | **Permission** view work packages |
| attachments | The files attached to this work package | Collection | not null | READ | |
| attachments | The files attached to this work package | Collection | not null | READ / WRITE | |
| author | The person that created the work package | User | not null | READ | |
| assignee | The person that is intended to work on the work package | User | | READ / WRITE | |
| availableWatchers | All users that can be added to the work package as watchers. | User | | READ | **Permission** add work package watchers |
@ -59,23 +59,27 @@
| createdAt | Time of creation | DateTime | | READ | |
| updatedAt | Time of the most recent change to the work package | DateTime | | READ | |
*Note that the properties listed here only cover the built-in properties of the OpenProject Core.
Note that the properties listed here only cover the built-in properties of the OpenProject Core.
Using plug-ins and custom fields a work package might contain various additional properties.
A client can consult the schema information to which the work package links. The schema will contain information about
all properties of the linking work package, including properties added by plug-ins and custom fields.*
all properties of the linking work package, including properties added by plug-ins and custom fields.
*Custom fields are identified by a key in the form of `customFieldN`, where `N` is an integer. Depending on their type,
Custom fields are identified by a key in the form of `customFieldN`, where `N` is an integer. Depending on their type,
they can occur as properties or as linked properties. A client has to consult the schema to resolve
the human readable name of custom fields.*
the human readable name of custom fields.
*Properties that cannot be set directly on parent work packages are inferred from their children instead:*
Properties that cannot be set directly on parent work packages are inferred from their children instead:
* `startDate` is the earliest start date from its children
* `dueDate` is the latest due date from its children
* `estimatedTime` is the sum of estimated times from its children
* `percentageDone` is the weighted average of the sum of its children percentages done. The weight is given by the average of its children estimatedHours. However, if the percentage done is given by a work package's status, then only the status matters and no value is inferred.
*Start date can also not be earlier than a due date of any predecessor.*
Start date can also not be earlier than a due date of any predecessor.
While attachments are returned as a link which's content is to be fetched separately, clients can choose to
replace the work package's attachments by providing an array of already uploaded [Attachment resources](#attachments) on [create](#work-packages-work-packages-post)
and [update](#work-packages-work-package-patch). The attachments the work package has had prior to the request will be removed.
## Work Package [/api/v3/work_packages/{id}{?notify}]

Loading…
Cancel
Save