Comments
Task discussion.
List Task comments
/api/v1/tasks/{task_id}/commentsReturns one page ordered by creation time, with the comment identifier as tie-breaker. Deleted comments are returned inline as tombstones — identity, author, and timestamps without a body — so client-side ordering and counts stay stable.
Path Parameters
Query Parameters
Responses
integer <int64>·min 0Authorized collection size before cursor bounds; refreshed at read time. Activity counts admitted events before display grouping and Comments include retained ordinals.
integer·min 0Delay in seconds before retrying, when an expected maintenance end is known.
string·const no-storePrevents storage of error responses by clients and intermediaries.
string·min 1·max 200Correlation identifier for the request.
string·const nosniffPrevents user agents from MIME-sniffing the response.
Add a comment to a Task
/api/v1/tasks/{task_id}/commentsCanonical content with an unsupported schema or an attempted schema 2-to-1 downgrade returns 409 document_schema_version_unsupported. Restoring an older Document revision retains an existing schema 2 floor. Appends a comment authored by the calling Actor. The body is validated against the Assign document schema allowlist and may not exceed 256 KiB of JSON.
Path Parameters
Header Parameters
Request Body
application/jsonobjectVersioned, server-validated rich-text document. The server accepts only nodes and marks on the Assign allowlist and rejects anything outside it; the client's installed editor extension set is never authoritative. Complexity is bounded at 32 levels of nesting and 50,000 nodes in addition to the per-field byte limits.
Accepted nodes: doc, paragraph, text, heading, bulletList,
orderedList, listItem, taskList, taskItem, blockquote, callout,
codeBlock, blockMath, horizontalRule, hardBreak, image, file, plus the
reference nodes userMention, projectReference, documentReference,
and taskReference. Accepted marks: bold, italic, underline,
strike, code, link.
A Task-description or Comment mutation accepts at most 100 distinct
canonical user identifiers across its userMention nodes. Repeated
mentions of the same user count once.
image and file name an Assign attachment through
attrs.attachmentId and carry no URL and no bytes: attachments travel
only through the attachment upload and download operations, and a
signed URL is minted per request after a fresh authorization check
rather than stored in content. A request whose image or file node
omits attachmentId, or carries a URL-bearing attribute, is rejected.
callout has block children and exactly attrs.kind and attrs.icon.
Kind is callout, note, tip, important, warning, or caution.
Icon is null for the default Lucide icon, an emoji of at most 64 UTF-8
bytes, an allowlisted lucide:name token to override it, or an empty string
to hide it. Unknown Lucide names are rejected. HTML, URLs and image
data are not accepted as icons. Callouts are additive in schemas 1 and 2.
blockMath stores a required string attrs.latex; rendered math HTML
and renderer settings are not persisted. Schema 1 retains the existing node contract; schema 2 additionally admits tables.
Checklists, attachment blocks, display equations, underline, and
projectReference were added additively, so every
previously stored document is still valid and no migration is
required.
Schema 2 additionally accepts table, tableRow, tableCell and tableHeader. A table has tableRow children; a row has tableCell/tableHeader children. Cells contain Assign blocks, starting with a paragraph; nested tables are rejected. Cells accept colspan/rowspan (integers 1–64, default 1), colwidth (null or one integer 24–2000 per spanned column), and align (null, left, center or right). Tables/rows have no attrs, marks or text; cells have no marks/text or other attributes. The occupancy grid must be rectangular with no overlap, holes or spans beyond its rows. Limits are 1000 rows, 64 logical columns and 10000 physical cells, still subject to each field's byte budget and global node/depth limits. Schema 1 rejects all four table nodes. Rich tables exchange through the named assign-table Markdown JSON fence; simple tables use GFM pipes.
Responses
stringQuoted decimal optimistic-concurrency version.
integer <int64>·min 1Creation-order ordinal within this Task, including deletion tombstones; use for numbered Comment links.
string <uuid>Opaque Assign-owned UUIDv7 identifier. Clients must not derive meaning from it.
string <uuid>Opaque Assign-owned UUIDv7 identifier. Clients must not derive meaning from it.
string <uuid>Opaque Assign-owned UUIDv7 identifier. Clients must not derive meaning from it.
stringImmutable creation-time Actor classification. The base is the
stable author Actor type; a mediated origin is appended with a
colon. For example, a user acting through MCP is user:mcp.
useruser:delegated_connectionuser:mcpuser:automationuser:external_actorstring·min 1·max 100Presentation-safe client, provider, automation, or external-actor
name for a compound actor; null for a direct base Actor.
objectAbsent or null once the comment is deleted.
string <date-time>Set by the first successful edit. Public, so readers can see the text changed.
integer·min 0Delay in seconds before retrying, when an expected maintenance end is known.
string·const no-storePrevents storage of error responses by clients and intermediaries.
string·min 1·max 200Correlation identifier for the request.
string·const nosniffPrevents user agents from MIME-sniffing the response.
Path Parameters
Responses
stringQuoted decimal optimistic-concurrency version.
integer <int64>·min 1Creation-order ordinal within this Task, including deletion tombstones; use for numbered Comment links.
string <uuid>Opaque Assign-owned UUIDv7 identifier. Clients must not derive meaning from it.
string <uuid>Opaque Assign-owned UUIDv7 identifier. Clients must not derive meaning from it.
string <uuid>Opaque Assign-owned UUIDv7 identifier. Clients must not derive meaning from it.
stringImmutable creation-time Actor classification. The base is the
stable author Actor type; a mediated origin is appended with a
colon. For example, a user acting through MCP is user:mcp.
useruser:delegated_connectionuser:mcpuser:automationuser:external_actorstring·min 1·max 100Presentation-safe client, provider, automation, or external-actor
name for a compound actor; null for a direct base Actor.
objectAbsent or null once the comment is deleted.
string <date-time>Set by the first successful edit. Public, so readers can see the text changed.
integer·min 0Delay in seconds before retrying, when an expected maintenance end is known.
string·const no-storePrevents storage of error responses by clients and intermediaries.
string·min 1·max 200Correlation identifier for the request.
string·const nosniffPrevents user agents from MIME-sniffing the response.
Edit a comment
/api/v1/comments/{comment_id}Canonical content with an unsupported schema or an attempted
schema 2-to-1 downgrade returns 409 document_schema_version_unsupported.
Restoring an older Document revision retains an existing schema 2 floor.
Replaces the comment body in place. Only the authoring Actor may
edit a comment; no Workspace role can edit another Actor's comment,
and a deleted comment cannot be edited. The first successful edit
sets the public edited_at marker. There is no user-visible
version history: the previous body is not retrievable.
Path Parameters
Header Parameters
string·min 1·max 200Required when this operation uses browserSession; native bearer callers omit it because no ambient cookie is sent.
string·min 16·max 200Opaque client-generated key for safely retrying this operation.
Request Body
application/jsonobjectVersioned, server-validated rich-text document. The server accepts only nodes and marks on the Assign allowlist and rejects anything outside it; the client's installed editor extension set is never authoritative. Complexity is bounded at 32 levels of nesting and 50,000 nodes in addition to the per-field byte limits.
Accepted nodes: doc, paragraph, text, heading, bulletList,
orderedList, listItem, taskList, taskItem, blockquote, callout,
codeBlock, blockMath, horizontalRule, hardBreak, image, file, plus the
reference nodes userMention, projectReference, documentReference,
and taskReference. Accepted marks: bold, italic, underline,
strike, code, link.
A Task-description or Comment mutation accepts at most 100 distinct
canonical user identifiers across its userMention nodes. Repeated
mentions of the same user count once.
image and file name an Assign attachment through
attrs.attachmentId and carry no URL and no bytes: attachments travel
only through the attachment upload and download operations, and a
signed URL is minted per request after a fresh authorization check
rather than stored in content. A request whose image or file node
omits attachmentId, or carries a URL-bearing attribute, is rejected.
callout has block children and exactly attrs.kind and attrs.icon.
Kind is callout, note, tip, important, warning, or caution.
Icon is null for the default Lucide icon, an emoji of at most 64 UTF-8
bytes, an allowlisted lucide:name token to override it, or an empty string
to hide it. Unknown Lucide names are rejected. HTML, URLs and image
data are not accepted as icons. Callouts are additive in schemas 1 and 2.
blockMath stores a required string attrs.latex; rendered math HTML
and renderer settings are not persisted. Schema 1 retains the existing node contract; schema 2 additionally admits tables.
Checklists, attachment blocks, display equations, underline, and
projectReference were added additively, so every
previously stored document is still valid and no migration is
required.
Schema 2 additionally accepts table, tableRow, tableCell and tableHeader. A table has tableRow children; a row has tableCell/tableHeader children. Cells contain Assign blocks, starting with a paragraph; nested tables are rejected. Cells accept colspan/rowspan (integers 1–64, default 1), colwidth (null or one integer 24–2000 per spanned column), and align (null, left, center or right). Tables/rows have no attrs, marks or text; cells have no marks/text or other attributes. The occupancy grid must be rectangular with no overlap, holes or spans beyond its rows. Limits are 1000 rows, 64 logical columns and 10000 physical cells, still subject to each field's byte budget and global node/depth limits. Schema 1 rejects all four table nodes. Rich tables exchange through the named assign-table Markdown JSON fence; simple tables use GFM pipes.
Responses
stringQuoted decimal optimistic-concurrency version.
integer <int64>·min 1Creation-order ordinal within this Task, including deletion tombstones; use for numbered Comment links.
string <uuid>Opaque Assign-owned UUIDv7 identifier. Clients must not derive meaning from it.
string <uuid>Opaque Assign-owned UUIDv7 identifier. Clients must not derive meaning from it.
string <uuid>Opaque Assign-owned UUIDv7 identifier. Clients must not derive meaning from it.
stringImmutable creation-time Actor classification. The base is the
stable author Actor type; a mediated origin is appended with a
colon. For example, a user acting through MCP is user:mcp.
useruser:delegated_connectionuser:mcpuser:automationuser:external_actorstring·min 1·max 100Presentation-safe client, provider, automation, or external-actor
name for a compound actor; null for a direct base Actor.
objectAbsent or null once the comment is deleted.
string <date-time>Set by the first successful edit. Public, so readers can see the text changed.
integer·min 0Delay in seconds before retrying, when an expected maintenance end is known.
string·const no-storePrevents storage of error responses by clients and intermediaries.
string·min 1·max 200Correlation identifier for the request.
string·const nosniffPrevents user agents from MIME-sniffing the response.
Delete a comment
/api/v1/comments/{comment_id}Soft-deletes the comment, leaving an addressable tombstone in its
thread position. The body and its extracted search text are cleared
immediately rather than merely hidden. The authoring Actor may
delete their own comment; Workspace owner and admin may delete
any comment as a moderation action, attributed to the deleting
Actor. The operation is idempotent and there is no restore.
Path Parameters
Header Parameters
Responses
string·const no-storePrevents storage of error responses by clients and intermediaries.
integer·min 0Delay in seconds before retrying, when an expected maintenance end is known.
string·const no-storePrevents storage of error responses by clients and intermediaries.
string·min 1·max 200Correlation identifier for the request.
string·const nosniffPrevents user agents from MIME-sniffing the response.
Add the caller's reaction to a comment
/api/v1/comments/{comment_id}/reactions/{reaction}Idempotently adds one fixed reaction without changing the Comment body revision. The Comment must be live and its parent Task active.
Path Parameters
Header Parameters
Responses
string·const no-storePrevents storage of error responses by clients and intermediaries.
integer <int64>·min 1Creation-order ordinal within this Task, including deletion tombstones; use for numbered Comment links.
string <uuid>Opaque Assign-owned UUIDv7 identifier. Clients must not derive meaning from it.
string <uuid>Opaque Assign-owned UUIDv7 identifier. Clients must not derive meaning from it.
string <uuid>Opaque Assign-owned UUIDv7 identifier. Clients must not derive meaning from it.
stringImmutable creation-time Actor classification. The base is the
stable author Actor type; a mediated origin is appended with a
colon. For example, a user acting through MCP is user:mcp.
useruser:delegated_connectionuser:mcpuser:automationuser:external_actorstring·min 1·max 100Presentation-safe client, provider, automation, or external-actor
name for a compound actor; null for a direct base Actor.
objectAbsent or null once the comment is deleted.
string <date-time>Set by the first successful edit. Public, so readers can see the text changed.
integer·min 0Delay in seconds before retrying, when an expected maintenance end is known.
string·const no-storePrevents storage of error responses by clients and intermediaries.
string·min 1·max 200Correlation identifier for the request.
string·const nosniffPrevents user agents from MIME-sniffing the response.
Remove the caller's reaction from a comment
/api/v1/comments/{comment_id}/reactions/{reaction}Idempotently removes one fixed reaction without changing the Comment body revision. The Comment must be live and its parent Task active.
Path Parameters
Header Parameters
Responses
string·const no-storePrevents storage of error responses by clients and intermediaries.
integer <int64>·min 1Creation-order ordinal within this Task, including deletion tombstones; use for numbered Comment links.
string <uuid>Opaque Assign-owned UUIDv7 identifier. Clients must not derive meaning from it.
string <uuid>Opaque Assign-owned UUIDv7 identifier. Clients must not derive meaning from it.
string <uuid>Opaque Assign-owned UUIDv7 identifier. Clients must not derive meaning from it.
stringImmutable creation-time Actor classification. The base is the
stable author Actor type; a mediated origin is appended with a
colon. For example, a user acting through MCP is user:mcp.
useruser:delegated_connectionuser:mcpuser:automationuser:external_actorstring·min 1·max 100Presentation-safe client, provider, automation, or external-actor
name for a compound actor; null for a direct base Actor.
objectAbsent or null once the comment is deleted.
string <date-time>Set by the first successful edit. Public, so readers can see the text changed.
integer·min 0Delay in seconds before retrying, when an expected maintenance end is known.
string·const no-storePrevents storage of error responses by clients and intermediaries.
string·min 1·max 200Correlation identifier for the request.
string·const nosniffPrevents user agents from MIME-sniffing the response.