# PATCH /api/v2/comments/{comment}

Edit a comment

- MCP id: comments.update
- Scope: api:write:project_management
- Scope: api:write:project_drive
- Scope: api:write:customer_drive
- Scope: api:write:organization_drive
- Scope: api:write:user_drive
- Permission: project_management::manage_work_items
- Rate cost: 1 unit, write bucket. A write costs the same whatever `view` you ask for.
- Cache-Control: private, no-store

Partially updates one comment: `body` is the only writable key and absent keys are untouched.

This mirrors the edit action on a comment thread in plnnrly and follows the same rules: Editing is author-only. No permission lets a manager edit somebody else's comment, so a PATCH by a non-author is `403` `forbidden-by-policy` and there is no override to ask for. On top of authorship the caller must still be able to comment on the parent, which is `project_management::manage_work_items` for a work item and read access to the drive document for a drive item; the token must cover that parent's prefix. Re-parenting is not a field write and is not available: sending `commentable_type` or `commentable_id` is a `422`. Mention spans present in the body you read may be sent back verbatim and are preserved; note that the response body is sanitised, so it can differ from the exact bytes you sent. Send `If-Match` with the `ETag` from your last read to detect a concurrent edit, which answers `412`; a comment has no `version` field, so its `ETag` is derived from `updated_at`, and the `ETag` in the response is the one to send next.

## Parameters
- comment (integer, path): The Comment's numeric id.
- view (string, optional): Which field set to render.
- X-Request-Id (header, optional): A correlation id of your own. It is recorded in our logs next to the server's request id but never returned: the response header always carries the server's id. A value that does not match the pattern is discarded silently, never rejected.
- If-Match (header, optional): The ETag a write is conditional on. A stale validator is 412 precondition-failed.

## Request body
- body (string ≤ 65535, optional): Comment body as rich text. HTML from the plnnrly editor, sanitised on the way out, so what you read back can differ from the bytes you sent. Mention spans (`<span data-type="mention" data-id="3">`) survive untouched and may be posted back verbatim; constructing a new mention is not supported in v2.0.

Unknown keys are refused with `422` validation-failed, naming the key.

## Response 200
- id (integer, required): Unique identifier.
- body (html, required): Comment body as rich text. HTML from the plnnrly editor, sanitised on the way out, so what you read back can differ from the bytes you sent. Mention spans (`<span data-type="mention" data-id="3">`) survive untouched and may be posted back verbatim; constructing a new mention is not supported in v2.0.
- author_type (string, required): The kind of record `author` points at; it says which branch of `author` applies.
- author_id (integer, required): The id of the record `author` points at.
- author (Ref or UserSummary, required): Who wrote the comment. Renders as `{"id": N}` unless `?include=author` expands it, which additionally requires the users prefix's read grant and a token covering it.
- commentable_type (string, required): The kind of record `commentable` points at; it says which branch of `commentable` applies.
- commentable_id (integer, required): The id of the record `commentable` points at.
- commentable (Ref, required): The record the comment hangs off, as a reference. Look it up from `commentable_type` and `commentable_id` with `GET /api/v2/work-items/{id}` or GET `/api/v2/drive-items/{id}`. It is not expandable: `?include=commentable` is a `400`.
- created_at (timestamp (YYYY-MM-DDThh:mm:ssZ), required): When the comment was posted.
- updated_at (timestamp (YYYY-MM-DDThh:mm:ssZ), required): Last-write timestamp; use for incremental sync, and as the revision the strong `ETag` is derived from.
- links (CommentLinks, required)
  - self (url, required): The canonical URI of this record.

## Errors
- 403 forbidden-by-policy | insufficient-permission | insufficient-token-scope: Forbidden.
  - `forbidden-by-policy`: You did not write this comment. Only its author can edit a comment, and no permission lets anyone else do it. You also get this answer when you can see the work item or drive item the comment belongs to but may not comment on it.
- 412 precondition-failed: Precondition failed.
- 415 unsupported-media-type: Unsupported media type.
- 422 unprocessable-relationship | validation-failed: Unprocessable content.
- 400 idempotency-key-required | invalid-cursor | invalid-query-parameter | malformed-request | unsupported-parameter: Bad request.
- 401 token-expired | unauthenticated: Unauthenticated.
- 404 endpoint-not-found | resource-not-found: Not found.
- 406 not-acceptable: Not acceptable.
- 429 rate-limit-exceeded: Too many requests.
- 500 internal-error: Server error.
- 503 tenant-unavailable: Service unavailable.

## Example
```bash
curl -X PATCH \
  'https://<your-url>/api/v2/comments/1' \
  -H 'Authorization: Bearer <token>' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -H 'If-Match: *' \
  -d '{
    "body": "<p>Deployed to staging, ready for review.</p>"
  }'
```
