Skip to content

Create a text-range annotation on a doc asset

POST
/assets/{id}/text-annotations

Persists a highlight / strikethrough / underline / comment / note as a top-level comments row with annotation_type='text-range'. body carries the user’s commentary (empty string is fine for a pure highlight).

Requires posts.comment capability — annotations are comments at the storage layer, so the same gate applies.

id
required
string format: uuid
object
body

User commentary (Markdown later; plain text now).

string
<= 8000 characters
anchor
required

Range anchor for a doc-viewer annotation. Lines are 1-based; columns are 0-based (CodeMirror convention). The range may be empty (start == end) for a sticky note at a position.

object
style
required

Visual treatment the editor’s decoration extension applies. comment + note carry user text in the parent comment’s body; highlight / strikethrough / underline typically have empty bodies but the field is free to set.

string
Allowed values: highlight strikethrough underline comment note
color
required

Hex color (#fef08a etc.). The default swatch palette is five highlighter colors, but any hex string is accepted so the future “custom color” picker works without a schema change.

string
<= 16 characters
start_line
required
integer
>= 1
start_col
required
integer
end_line
required
integer
>= 1
end_col
required
integer
resolved

Review-flow flag — the panel can filter resolved annotations out of the active list. Resolution does not delete; the anchor stays anchored for audit.

boolean

Annotation created

A single comment in a thread. Threading is via parent_id + root_id + depth (caller renders nested replies indented by depth). annotation_* fields are NULL for plain comments; the review-mode feature reuses the same row shape.

Federation: exactly one of {author_user_ref} XOR {peer_id + actor_uri} is set per row. Local-authored comments have author_user_ref set + peer_id NULL. Remote-authored comments (from a paired peer per ADR 0043 / phase 1.22.D) have author_user_ref NULL + peer_id + actor_uri + display_name populated. Clients render “<display_name> @ <peer’s host>” for remote rows.

object
id
required
string format: uuid
target_kind
required
string
Allowed values: post asset collection
target_id
required
string format: uuid
parent_id
string format: uuid
nullable
root_id
required
string format: uuid
depth
required
integer
author_user_ref

Local author user.ref. NULL for remote-authored comments (see peer_id / actor_uri).

integer format: int64
nullable
body
required
string
body_html
required

Server-rendered safe HTML; clients should render this rather than reformatting body.

string
annotation_type
string
nullable
Allowed values: point rect timestamp frame whiteboard text-range
annotation_data
object
key
additional properties
any
like_count
required
integer format: int64
edited_at
string format: date-time
nullable
created_at
required
string format: date-time
updated_at
required
string format: date-time
peer_id

The federation peer that originated this comment. NULL for local-authored rows. Set in tandem with actor_uri

  • display_name when the comment came in via the federation inbox.
string format: uuid
nullable
actor_uri

The remote actor’s URI on their home instance (e.g. https://studio-b.example/users/bob). NULL for local-authored rows.

string
nullable
display_name

Display name resolved from federation_remote_actors cache for remote-authored comments. May be empty if the remote instance hasn’t shipped display hints yet; clients should fall back to the actor_uri’s host + local-part when this is empty.

string
nullable

Malformed request

object
error
required

Human-readable error summary

string
Example
the request could not be completed

Authentication required, missing, or invalid

object
error
required

Human-readable error summary

string
Example
the request could not be completed
Example
{
"error": "authentication required: sign in and retry with a valid session or API token"
}

Authenticated but missing required capabilities

object
error
required

Human-readable error summary

string
Example
the request could not be completed

Resource not found

object
error
required

Human-readable error summary

string
Example
the request could not be completed