> ## Documentation Index
> Fetch the complete documentation index at: https://velt-codex-ui-customization-guide-refresh.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Headless hooks

> Reference Velt headless hooks for reading data, mutating state, and controlling UI.

<Note>
  **Source of truth: exhaustive for what it covers.** Generated from Velt hook metadata. **If a name isn't on this page, it doesn't exist**: don't use it (a missing identifier resolves to `undefined` / renders nothing). Never invent or guess a name; use only identifiers that appear verbatim here or that you verified against ground truth and added here. *Scope: exhaustive over `@veltdev/react`'s hook exports. Comment + notification + core hooks are documented in full; the remaining other-feature hooks are listed by name + return type + one-line purpose in "Other features (brief)" below: enough to keep the "a hook not listed doesn't exist" invariant true, without full per-hook depth.*
</Note>

The hooks you use to build custom UI ([`Headless`](/ui-customization/headless)) or to add data-driven extras alongside any approach. All from `@veltdev/react`. Types from `@veltdev/types`.

Grouped by purpose: **read** (data/state you render), **mutate** (actions you call), **events** (callbacks), **control** (init/scope/imperative). This lists the commonly-used comment hooks plus a brief map of other features; the SDK exports many more hooks following the same naming, but everything you need for the patterns in this guide is here.

> Exhaustive over `@veltdev/react`'s hook exports: a hook not listed here doesn't exist ([source-of-truth invariant](/ui-customization/reference/source-of-truth-invariant)).

***

## Read: data & state

| Hook                                                                            | Returns / use                                                                                                                              |
| ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `useCommentAnnotations()`                                                       | Reactive `CommentAnnotation[]` (or `null` before load) on the current document. The main data source. Use `useCommentAnnotations() ?? []`. |
| `useGetCommentAnnotations(query?)`                                              | Reactive, filtered query → `GetCommentAnnotationsResponse` (`{ annotations, count, … }`), not a bare array.                                |
| `useCommentAnnotationById({ annotationId })`                                    | One annotation by id.                                                                                                                      |
| `useCommentAnnotationsCount(query?)`                                            | `GetCommentAnnotationsCountResponse` (read its `count` field), not a bare number.                                                          |
| `useCommentModeState()`                                                         | Whether comment mode is active.                                                                                                            |
| `useCommentSidebarData()`                                                       | Data backing the sidebar (filters/sorted list).                                                                                            |
| `useUnreadCommentCountOnCurrentDocument()`                                      | Unread *comment* count on the current document → `UnreadCommentsCount` object `{ count } \| null`. Read `.count`.                          |
| `useCurrentUser()`                                                              | The identified user.                                                                                                                       |
| `useCurrentUserPermissions()`                                                   | Current user's permissions.                                                                                                                |
| `useUnreadCommentAnnotationCountOnCurrentDocument()`                            | Returns `UnreadCommentsCount`: an **object** `{ count } \| null`, not a number. Read `.count` (e.g. `data?.count ?? 0`). Great for badges. |
| `useUnreadCommentCountByAnnotationId()` / `useUnreadCommentCountByLocationId()` | Unread counts scoped to a thread / location.                                                                                               |
| `useUnreadCommentAnnotationCountByLocationId()`                                 | Unread annotation count by location.                                                                                                       |

> **Return shapes matter.** Several read hooks return wrapper objects, not bare values (`…Count*` → `{ count }`; `useGetCommentAnnotations` → a response object). Read the field, don't render the object. When unsure of a return shape, `console.log` the hook's value in your component to see it before rendering.

## Mutate: actions

| Hook                                                                  | Action                                                                                                                                                                                                                     |
| --------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `useAddCommentAnnotation()`                                           | Create a new annotation (a new thread).                                                                                                                                                                                    |
| `useAddComment()`                                                     | Add a comment/reply to an annotation.                                                                                                                                                                                      |
| `useUpdateComment()`                                                  | Edit a comment.                                                                                                                                                                                                            |
| `useDeleteComment()`                                                  | Delete a single comment.                                                                                                                                                                                                   |
| `useDeleteCommentAnnotation()`                                        | Delete a whole thread.                                                                                                                                                                                                     |
| `useResolveCommentAnnotation()`                                       | Resolve a thread.                                                                                                                                                                                                          |
| `useApproveCommentAnnotation()` / `useRejectCommentAnnotation()`      | Approval flows.                                                                                                                                                                                                            |
| `useUpdateStatus()`                                                   | Set a thread's status.                                                                                                                                                                                                     |
| `useUpdatePriority()`                                                 | Set priority.                                                                                                                                                                                                              |
| `useAssignUser()`                                                     | Assign a user to a thread.                                                                                                                                                                                                 |
| `useUpdateAccess()`                                                   | Change a thread's access/visibility. Returns `{ updateAccess }`; `await updateAccess(request: UpdateAccessRequest)` → `Promise<UpdateAccessEvent \| null>`. Writes `CommentAnnotation.iam.accessMode` (public vs private). |
| `useAddReaction()` / `useDeleteReaction()` / `useToggleReaction()`    | Reactions.                                                                                                                                                                                                                 |
| `useAddAttachment()` / `useDeleteAttachment()` / `useGetAttachment()` | Attachments.                                                                                                                                                                                                               |
| `useGetLink()` / `useCopyLink()`                                      | Deep link to a comment.                                                                                                                                                                                                    |
| `useGetComment()`                                                     | Returns `{ getComment }`; `await getComment(request)` → `Comment[]` (imperative fetch, not reactive).                                                                                                                      |
| `useGetRecording()` / `useDeleteRecording()`                          | Returns `{ getRecording }` / `{ deleteRecording }`; fetch or delete a recording attached to a comment.                                                                                                                     |

Most return an object with a function, e.g. `const { addComment } = useAddComment();` then `await addComment({ annotationId, comment })`.

## Events: callbacks

| Hook                                                   | Fires on                                                                              |
| ------------------------------------------------------ | ------------------------------------------------------------------------------------- |
| `useCommentEventCallback()`                            | Generic comment events.                                                               |
| `useCommentAddHandler()` / `useCommentUpdateHandler()` | A comment added / updated.                                                            |
| `useCommentSelectionChangeHandler()`                   | Selected thread changes.                                                              |
| `useCommentCopyLinkHandler()`                          | A copy-link action.                                                                   |
| `useCommentActionCallback(action)`                     | Typed callback for a specific comment action (`CommentEventTypesMap[action]`).        |
| `useCommentSidebarActionButtonClick()`                 | A custom sidebar action-button click → `CommentSidebarCustomActionEventData \| null`. |
| `useCommentSidebarInit()`                              | Fires when the comment sidebar initializes.                                           |
| `useCommentDialogSidebarClickHandler()`                | A click on the sidebar from a comment dialog.                                         |
| `useNotificationEventCallback(action)`                 | Typed notification event callback (`NotificationEventTypesMap[action]`).              |
| `usePresenceEventCallback(action)`                     | Typed presence event callback (`PresenceEventTypesMap[action]`).                      |
| `useRecorderAddHandler()`                              | Fires when a recording is added → `RecordedData \| null`.                             |
| `useServerConnectionStateChangeHandler()`              | Live-state server connection state changes → `ServerConnectionState`.                 |
| `useVeltEventCallback(eventName)`                      | Custom events (e.g. `'veltButtonClick'` from a wireframe button).                     |

## Control: init, scope, imperative

| Hook                                                                    | Use                                                                                                                                       |                                                                  |
| ----------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- |
| `useVeltClient()`                                                       | The Velt client (`const { client } = useVeltClient()`); imperative API + `client.getCommentElement()`. (`useClient()` is a newer alias.)  |                                                                  |
| `useIdentify()`                                                         | Returns `{ identify }`; call `identify(user)`.                                                                                            |                                                                  |
| `useSetDocuments()` / `useSetDocument()`                                | Return a setter: `const { setDocuments } = useSetDocuments();` then `setDocuments(documents, options)`. **Not** `useSetDocuments([...])`. |                                                                  |
| `useSetDocumentId(documentId)`                                          | Argument-form setter for a single document id (no returned setter; pass the id directly).                                                 |                                                                  |
| `useUnsetDocuments()` / `useUnsetDocumentId()`                          | Clear the current document(s) scope.                                                                                                      |                                                                  |
| `useSetRootDocument()`                                                  | Returns `{ setRootDocument }`; `setRootDocument(document)` sets the root document.                                                        |                                                                  |
| `useSetLocation(location, appendLocation?)`                             | Argument-form location setter.                                                                                                            |                                                                  |
| `useSetLocations()`                                                     | Returns `{ setLocations }`; `setLocations(locations, options)`.                                                                           |                                                                  |
| `useSetRootLocation()`                                                  | Returns `{ setRootLocation }`; `setRootLocation(location)`.                                                                               |                                                                  |
| `useSetPageInfo()` / `useClearPageInfo()`                               | Return `{ setPageInfo }` / `{ clearPageInfo }`; set or clear page metadata.                                                               |                                                                  |
| `useHeartbeat(config?)`                                                 | Reactive `GetHeartbeatResponse` (presence heartbeat).                                                                                     |                                                                  |
| `useSetContextProvider()`                                               | Provide custom context to comments.                                                                                                       |                                                                  |
| `useVeltInitState()`                                                    | Whether Velt finished initializing (gate rendering on this).                                                                              |                                                                  |
| `useUiState()` / `useSetLiveStateData()`                                | Shared UI state between users.                                                                                                            |                                                                  |
| `useSubscribeCommentAnnotation()` / `useUnsubscribeCommentAnnotation()` | Subscribe to a specific annotation.                                                                                                       |                                                                  |
| `useCommentUtils()`                                                     | The underlying comment element (\`CommentElement                                                                                          | undefined\`); the imperative element backing most comment hooks. |

***

## Imperative API via the client

Some controls aren't hooks: call them on the comment element:

```tsx theme={null}
const { client } = useVeltClient();
const commentElement = client.getCommentElement();
commentElement.openCommentSidebar();
commentElement.enableCommentMode();
commentElement.setCommentSidebarFilters({ status: ["open"], priority: ["high"] });
commentElement.setCustomStatus([{ id: "new", title: "New", color: "#FF5733" }]);
```

(These element APIs come from the typed comment element returned by `client.getCommentElement()`.)

***

## Other features (brief)

| Feature         | Representative hooks                                                                                                                                                                                                        |
| --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Presence        | `usePresenceUsers`, `usePresenceData`, `usePresenceUtils`, `usePresenceEventCallback`, `useHeartbeat`                                                                                                                       |
| Cursors         | `useCursorUsers`, `useCursorUtils`                                                                                                                                                                                          |
| Notifications   | `useNotificationsData`, `useUnreadNotificationsCount`, `useNotificationSettings`, `useNotificationUtils`, `useNotificationEventCallback`                                                                                    |
| Reactions       | `useAddReaction`, `useToggleReaction`, `useDeleteReaction`                                                                                                                                                                  |
| Recorder        | `useRecordings`, `useRecordingDataByRecorderId`, `useRecorderUtils`, `useRecorderEventCallback`, `useRecorderAddHandler`                                                                                                    |
| Suggestions     | `useSuggestions`, `useSuggestionUtils`, `usePendingSuggestion`, `useStartSuggestion`, `useCommitSuggestion`, `useEnableSuggestionMode` / `useDisableSuggestionMode`, `useSuggestionModeState`, `useSuggestionEventCallback` |
| Activity log    | `useAllActivities`, `useActivityUtils`                                                                                                                                                                                      |
| Autocomplete    | `useAutocompleteUtils`, `useAutocompleteChipClick`, `useContactList`, `useContactSelected`, `useContactUtils`                                                                                                               |
| Tags            | `useTagAnnotations`, `useTagUtils`                                                                                                                                                                                          |
| Views/Analytics | `useUniqueViewsByUser`, `useUniqueViewsByDate`, `useViewsUtils`                                                                                                                                                             |
| Live state sync | `useLiveState`, `useLiveStateData`, `useSetLiveStateData`                                                                                                                                                                   |

See [`Other features`](/ui-customization/features/other-features) for how customization applies to these.

### Other-feature hook exports (verified return types)

These are exported from `@veltdev/react` but belong to out-of-scope features. They are listed here only to keep the "a hook not listed doesn't exist" invariant true: name, category, return type, and one-line purpose. Return types verified against ground truth.

| Hook                                    | Category           | Returns                                                     | Purpose                                                                                                 |
| --------------------------------------- | ------------------ | ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| `useLiveStateSyncUtils()`               | Live state sync    | `LiveStateSyncElement \| undefined`                         | The imperative live-state-sync element backing the live-state hooks.                                    |
| `useUserEditorState()`                  | Live state sync    | `UserEditorAccess \| null \| undefined`                     | Whether the current user is the editor in single-editor mode.                                           |
| `useEditor()`                           | Live state sync    | `User \| null`                                              | The current editor user in single-editor mode.                                                          |
| `useEditorAccessTimer()`                | Live state sync    | `EditorAccessTimer` (defaults to `{ state: 'idle' }`)       | Editor-access countdown/timer state.                                                                    |
| `useEditorAccessRequestHandler()`       | Live state sync    | `{ requestStatus: string; requestedBy: User } \| null`      | The pending editor-access request, if any.                                                              |
| `useLiveStateSyncEventCallback(action)` | Live state sync    | `LiveStateEventTypesMap[action]`                            | Latest live-state-sync event payload (access/editor events).                                            |
| `useRegisterTarget()`                   | Suggestion targets | `{ registerTarget(config: RegisterTargetConfig<T>): void }` | Register a complex-object getter for a suggestion target.                                               |
| `useUnregisterTarget()`                 | Suggestion targets | `{ unregisterTarget(targetId: string): void }`              | Drop a registered suggestion-target getter.                                                             |
| `useLiveSelectionUtils()`               | Live selection     | `SelectionElement \| undefined`                             | The imperative live-selection element.                                                                  |
| `useLiveSelectionDataHandler()`         | Live selection     | `LiveSelectionData \| null`                                 | Reactive live-selection data.                                                                           |
| `useCrdtUtils()`                        | CRDT               | `CrdtElement \| undefined`                                  | The imperative CRDT element.                                                                            |
| `useCrdtEventCallback(action)`          | CRDT               | `CrdtEventTypesMap[action]`                                 | Latest CRDT event payload (e.g. `updateData`).                                                          |
| `useHuddleUtils()`                      | Huddle             | `HuddleElement \| undefined` (typed `any` in source)        | The imperative huddle element.                                                                          |
| `useAIRewriterUtils()`                  | AI rewriter        | `RewriterElement \| undefined`                              | The imperative rewriter element (subscribe to `textSelected`; call `askAi`/`replaceText`/`addComment`). |
