DocumentMessage record
anchored to a subdocument path, with a type that says what kind of mark it is
and a markType label that further classifies it. The API is one and the same
for two distinct use cases:
- Annotations, free-text notes and flags a reviewer leaves on a document
(
type: "annotation"), with threaded replies for back-and-forth discussion. - Sign-offs, the reviewer sign-off marks the review flow records against a
sheet or row (
type: "activity",markType: "signoff"). See Review a return and sign off for the end-to-end recipe.
workspaceToken (see
Authentication) and go to the single GraphQL endpoint:
How notes and comments fit together
Use this page as the source of truth for creating, editing, hiding, and replying to notes and comments. Use Binder to discover documents and search across existing content.In product language, a note or flag is a top-level
DocumentMessage. A comment or reply in a conversation is a
DocumentMessageThread under that top-level message. Search may return
BinderMessage objects from the binder search index, but create, update, hide,
and reply operations use the DocumentMessage API on this page.MCP usage pattern for notes and comments
- Query the client binder first and read
binder.subdocuments.id. - Use the selected subdocument
idasdocumentPathfor message reads and writes. - For an overview badge, read
binder.messageCounts.notesinstead of fetching every message. - To find text across notes, flags, and document contents, call
binder.search. - To edit, hide, unhide, or reply, refetch
Client.documentMessages(filter)and use the returnedDocumentMessage.id. - Prefer
filter.includeHidden: falsefor normal product views. UseincludeHidden: trueonly for audit, recovery, or admin workflows.
The DocumentMessage type
ID!
The workspace that owns the message.
String!
The subdocument path the message is anchored to. For a sign-off this is the
subdocument being signed off; for an annotation it is the document location the
note is attached to.
DocumentMessageType!
annotation for free-text annotations, activity for activity events such as
sign-offs, missing_document for missing-document flags.String!
A free-form label for the kind of mark. Sign-offs use
"signoff". Annotations
are surface-defined (for example "note", "flag").JSON!
A JSON object describing where the mark is anchored. For a sign-off the shape
is
{ page, coordinates: { x, y }, level, user_role }. The exact fields depend
on the surface that created the message.String
Optional path into the document content that the mark references.
String
The message body text. Annotations carry their note text here.
null for
activity messages such as sign-offs that have no prose.ISO 8601 timestamp when the message was soft-hidden via
hideDocumentMessage. null while the
message is visible.The user who hid the message.
null while the message is visible.ID!
The user who created the message.
String!
ISO 8601 timestamp of creation.
String!
ISO 8601 timestamp of the last mutation (edit, hide, unhide).
[DocumentMessageThread!]!
Replies on this message (see Threads (replies)).
[DocumentMessageTaggedUser!]!
Users tagged on this message. See the
DocumentMessageTaggedUser type below.The DocumentMessageThread type
ID!
The thread reply’s unique identifier.
ID!
The parent
DocumentMessage.id.String!
Path into the document content the reply is anchored to.
String
The reply body.
null when empty.ID!
The user who posted the reply.
String!
ISO 8601 timestamp of creation.
String!
ISO 8601 timestamp of the last edit.
[DocumentMessageTaggedUser!]!
Users tagged on this reply.
The DocumentMessageTaggedUser type
ID!
The tag record’s unique identifier.
ID!
The workspace user who was tagged.
ID
Set when the tag is on a top-level
DocumentMessage. null when the tag is on
a thread reply.ID
Set when the tag is on a
DocumentMessageThread reply. null when the tag is
on a top-level message.String!
ISO 8601 timestamp of the tag.
String!
ISO 8601 timestamp of the last update to the tag.
Read document messages
There is no top-leveldocumentMessages query. Read them through the
Client.documentMessages(filter) field, reached via
me { ... on WorkspaceUser { workspace { clients(...) { documentMessages(...) } } } }.
Arguments
String
Return only messages anchored to this subdocument path.
[String!]
Return only messages whose
markType is in this list (for example
["signoff"] for sign-offs, ["note"] for notes).[DocumentMessageType!]
Return only messages whose
type is in this list.When
true, include soft-hidden messages in the results. Defaults to false,
which excludes hidden messages.Annotations
An annotation is aDocumentMessage with type: "annotation" that a reviewer
leaves on a document. Use a markType label your surface understands (the web
app uses "note" for free-text notes and "flag" for review flags). Annotations
carry their text in body, and can collect threaded replies for discussion.
Create an annotation
createDocumentMessage creates a single document message anchored to a
subdocument path. For an annotation, pass type: "annotation", your surface’s
markType, and the note text in body.
Input: CreateDocumentMessageInput
ID!
required
The client whose binder this message belongs to.
String!
required
The subdocument path the message is anchored to.
DocumentMessageType!
required
annotation, activity, or missing_document. Use annotation for notes and
flags, activity for sign-offs.String!
required
A label for the kind of mark. Use
"note" or "flag" for annotations, and
"signoff" for a sign-off.JSON!
required
A JSON object describing where the mark is anchored. The shape is
surface-defined (for example
{ page, coordinates: { x, y } } for an
annotation, or { page, coordinates: { x, y }, level, user_role } for a
sign-off).String
The message body text. Required for prose annotations;
null for activity
messages such as sign-offs that have no prose.ID
Optional task ID to associate the message with (for example, the
review task it was created during).
[ID!]
Optional list of workspace user IDs to tag on the message.
Returns: DocumentMessage!
The created DocumentMessage. Save its id to
later update or hide it.
Update a document message
updateDocumentMessage edits the body, anchor point, or tagged users on an
existing document message. markType and type are not mutable.
Input: UpdateDocumentMessageInput
ID!
required
The document message to update.
String
The new body text.
JSON
The new anchor point object.
[ID!]
The complete list of tagged user IDs (replaces the previous list).
Returns: DocumentMessage!
The updated DocumentMessage.
Hide and unhide a document message
Hiding a document message is the soft-delete the binder uses to dismiss an annotation or to undo a sign-off (see Sign-offs). The message is retained withhiddenAt and hiddenBy set, and excluded from default reads
unless filter.includeHidden: true is passed.
ID!
required
The document message to hide or unhide.
Returns: DocumentMessage!
The updated DocumentMessage. After
hideDocumentMessage, hiddenAt and hiddenBy are populated. After
unhideDocumentMessage, both are null again.
Threads (replies)
Threads are replies on aDocumentMessage. A thread reply is its own
DocumentMessageThread object, created under a parent message ID. Use threads
for the back-and-forth discussion that grows under an annotation.
Create a thread reply
Input: CreateDocumentMessageThreadInput
ID!
required
The parent
DocumentMessage.id to reply under.String!
required
The reply body text.
[ID!]
Optional list of workspace user IDs to tag on the reply.
Returns: DocumentMessageThread!
The created DocumentMessageThread.
Update a thread reply
Input: UpdateDocumentMessageThreadInput
ID!
required
The thread reply to update.
String!
required
The new reply body text.
Returns: DocumentMessageThread!
The updated DocumentMessageThread.
Delete a thread reply
deleteDocumentMessageThread permanently removes a thread reply. It returns the
deleted reply’s ID.
ID!
required
The thread reply to delete.
Returns: ID!
The ID of the deleted thread reply.
Sign-offs
A sign-off is aDocumentMessage with type: "activity" and
markType: "signoff", anchored to the subdocument path being signed off. The
review flow records one sign-off per subdocument. Undoing a sign-off is a
soft-hide of the sign-off DocumentMessage via hideDocumentMessage.
For the end-to-end review recipe that ties leadsheets, sign-offs, and refetch
together, see Review a return and sign off.
For the sign-off read surface on leadsheets (the signOffs field on
Leadsheet and LeadsheetFieldRow), see
Leadsheets and review.
Sign off on a sheet or row
createDocumentMessage records a sign-off. Pass type: "activity",
markType: "signoff", the subdocument path being signed off as documentPath,
and an anchorPoint that carries the reviewer’s level and user_role so the
UI renders the sign-off with the right label. The web app signs off one
subdocument at a time, one createDocumentMessage call per subdocument.
CreateDocumentMessageInput documented under
Create an annotation; only the type, markType,
and anchorPoint values differ for a sign-off.
id. You pass it to hideDocumentMessage in the next step if
you ever need to undo the sign-off.
Undo a sign-off
Undoing a sign-off is a soft-hide of the sign-offDocumentMessage via
hideDocumentMessage (see Hide and unhide a document
message). The sign-off row stays in
history with hiddenAt set, and the leadsheets query’s resolved and
issueCount recomputation backs it out.
See also
- Leadsheets and review for the
Leadsheets,Leadsheet,LeadsheetSheetIssue,LeadsheetFieldRow, andLeadsheetTracetype definitions, and the leadsheets sign-off read surface (Leadsheet.signOffs,LeadsheetFieldRow.signOffs). - Review a return and sign off for the end-to-end recipe that ties reading leadsheets, recording sign-offs, and refetching together.
- Tasks for the polling mechanics behind the review task whose
taskIdyou can associate a document message with.