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.
Authorizations
Section titled “Authorizations ”Parameters
Section titled “ Parameters ”Path Parameters
Section titled “Path Parameters ”Request Body required
Section titled “Request Body required ”object
User commentary (Markdown later; plain text now).
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
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.
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.
Review-flow flag — the panel can filter resolved annotations out of the active list. Resolution does not delete; the anchor stays anchored for audit.
Responses
Section titled “ Responses ”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
Local author user.ref. NULL for remote-authored comments (see peer_id / actor_uri).
Server-rendered safe HTML; clients should render this rather than reformatting body.
object
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.
The remote actor’s URI on their home instance (e.g. https://studio-b.example/users/bob). NULL for local-authored rows.
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.
Malformed request
object
Human-readable error summary
Example
the request could not be completedAuthentication required, missing, or invalid
object
Human-readable error summary
Example
the request could not be completedExample
{ "error": "authentication required: sign in and retry with a valid session or API token"}Authenticated but missing required capabilities
object
Human-readable error summary
Example
the request could not be completedResource not found
object
Human-readable error summary
Example
the request could not be completed