# Nodes ## Rename **patch** `/v1/taxonomy/nodes/{node_id}` Renames a taxonomy node's label and records a rename event attributed to actor_id. Tenant-scoped; returns 404 if the node does not belong to the tenant. While a tenant data purge runs for the same tenant_id, the request is rejected with HTTP 409 (code `tenant_write_conflict`) and may be retried. ### Path Parameters - `node_id: string` ### Body Parameters - `actor_id: string` - `label: string` New node label. - `tenant_id: string` ### Returns - `Node = object { id, created_at, label, 13 more }` A node in a taxonomy tree. Non-root nodes have a parent; leaf nodes reference the cluster they summarize. - `id: string` - `created_at: string` - `label: string` - `level: number` Depth in the tree; the root is level 0. - `node_type: "root" or "branch" or "leaf"` Position of a node within the taxonomy tree. - `"root"` - `"branch"` - `"leaf"` - `run_id: string` - `sort_order: number` - `updated_at: string` - `children: optional array of Node` Child nodes, present when the tree is returned hierarchically. - `cluster_id: optional string` Cluster this node summarizes; typically present on leaf nodes. - `description: optional string` - `metadata: optional map[unknown]` - `original_label: optional string` Label as originally generated, before any rename. - `parent_id: optional string` Parent node ID; absent for the root node. - `removed_at: optional string` Set when the node has been soft-removed. - `removed_by: optional string` Actor that soft-removed the node. ### Example ```http curl http://localhost:8080/v1/taxonomy/nodes/$NODE_ID \ -X PATCH \ -H 'Content-Type: application/json' \ -H "Authorization: Bearer $HUB_API_KEY" \ -d '{ "actor_id": "user-42", "label": "Authentication Problems", "tenant_id": "org-123" }' ``` ## Soft Remove **delete** `/v1/taxonomy/nodes/{node_id}` Soft-removes a taxonomy node (sets removed_at/removed_by) and records a soft_remove event attributed to actor_id. The node is retained for audit but excluded from tree responses. Tenant-scoped; returns 404 if the node does not belong to the tenant. While a tenant data purge runs for the same tenant_id, the request is rejected with HTTP 409 (code `tenant_write_conflict`). ### Path Parameters - `node_id: string` ### Query Parameters - `actor_id: string` Identifier of the actor performing the removal (recorded in the audit event). - `tenant_id: string` Tenant that owns the node. ### Returns - `Node = object { id, created_at, label, 13 more }` A node in a taxonomy tree. Non-root nodes have a parent; leaf nodes reference the cluster they summarize. - `id: string` - `created_at: string` - `label: string` - `level: number` Depth in the tree; the root is level 0. - `node_type: "root" or "branch" or "leaf"` Position of a node within the taxonomy tree. - `"root"` - `"branch"` - `"leaf"` - `run_id: string` - `sort_order: number` - `updated_at: string` - `children: optional array of Node` Child nodes, present when the tree is returned hierarchically. - `cluster_id: optional string` Cluster this node summarizes; typically present on leaf nodes. - `description: optional string` - `metadata: optional map[unknown]` - `original_label: optional string` Label as originally generated, before any rename. - `parent_id: optional string` Parent node ID; absent for the root node. - `removed_at: optional string` Set when the node has been soft-removed. - `removed_by: optional string` Actor that soft-removed the node. ### Example ```http curl http://localhost:8080/v1/taxonomy/nodes/$NODE_ID \ -X DELETE \ -H "Authorization: Bearer $HUB_API_KEY" ``` ## List Records **get** `/v1/taxonomy/nodes/{node_id}/records` Returns the feedback records assigned to a node and all of its (visible) descendant nodes, via the clusters those nodes reference. Tenant-scoped. The `limit` in the response reflects the applied cap. ### Path Parameters - `node_id: string` ### Query Parameters - `tenant_id: string` Tenant that owns the node. - `limit: optional number` Maximum number of feedback records to return. ### Returns - `data: array of FeedbackRecordData` - `id: string` UUIDv7 primary key - `collected_at: string` When the feedback was collected - `created_at: string` When this record was created - `field_id: string` Identifier for the question/field - `field_type: "text" or "categorical" or "nps" or 6 more` Type of field - `"text"` - `"categorical"` - `"nps"` - `"csat"` - `"ces"` - `"rating"` - `"number"` - `"boolean"` - `"date"` - `source_type: string` Type of feedback source - `submission_id: string` Identifier for the logical submission this record belongs to (required). - `tenant_id: string` Tenant/organization identifier. NULL bytes not allowed. - `updated_at: string` When this record was last updated - `field_group_id: optional string` Stable identifier grouping related fields (for ranking, matrix, grid questions) - `field_group_label: optional string` Human-readable question text for the group - `field_label: optional string` The actual question text - `language: optional string` ISO language code. NULL bytes not allowed. - `metadata: optional map[unknown]` Additional context - `sentiment: optional "very_negative" or "negative" or "neutral" or 3 more` Sentiment polarity inferred from value_text (sentiment enrichment). Read-only; absent until the record is enriched. - `"very_negative"` - `"negative"` - `"neutral"` - `"positive"` - `"very_positive"` - `"mixed"` - `sentiment_score: optional number` Signed sentiment polarity from -1.0 (very negative) to 1.0 (very positive) (sentiment enrichment). Read-only; absent until the record is enriched. - `source_id: optional string` Reference to survey/form/ticket ID - `source_name: optional string` Human-readable name - `translation_lang_key: optional string` BCP-47 target locale that value_text_translated was produced in (language enrichment). Read-only; absent until the record is enriched. - `user_id: optional string` User ID (e.g., anonymous ID or email hash) - `value_boolean: optional boolean` Boolean response - `value_date: optional string` Date response - `value_number: optional number` Numeric response - `value_text: optional string` Text response. NULL bytes not allowed. - `value_text_translated: optional string` value_text translated into the tenant's configured target language (language enrichment). Read-only; absent until the record is enriched. - `limit: number` The applied maximum number of records. ### Example ```http curl http://localhost:8080/v1/taxonomy/nodes/$NODE_ID/records \ -H "Authorization: Bearer $HUB_API_KEY" ```