# Taxonomy ## List Fields `client.taxonomy.listFields(TaxonomyListFieldsParamsquery, RequestOptionsoptions?): TaxonomyListFieldsResponse` **get** `/v1/taxonomy/fields` Returns the feedback fields that can be used to generate a taxonomy for a tenant, along with the number of text records and embedded records available per field scope (source_type, source_id, field_id). A field with no attributed source is exposed under the canonical "no source" bucket (empty source_id). Requires Hub embeddings to be configured; otherwise the endpoint returns 503. ### Parameters - `query: TaxonomyListFieldsParams` - `tenant_id: string` Tenant whose taxonomy-capable fields should be listed. ### Returns - `TaxonomyListFieldsResponse` - `data: Array` - `embedding_count: number` Number of those records that have an embedding. - `field_id: string` - `record_count: number` Number of text feedback records in the scope. - `source_id: string` Empty string is the canonical "no source" bucket. - `source_type: string` - `tenant_id: string` - `field_label?: string` - `source_name?: string` ### Example ```typescript import FormbricksHub from '@formbricks/hub'; const client = new FormbricksHub({ apiKey: process.env['HUB_API_KEY'], // This is the default and can be omitted }); const response = await client.taxonomy.listFields({ tenant_id: 'org-123' }); console.log(response.data); ``` ## Domain Types ### Run - `Run` A persisted taxonomy generation run. - `id: string` - `cluster_count: number` - `created_at: string` - `embedding_count: number` - `field_id: string` - `node_count: number` - `record_count: number` - `scope_type: "field" | "directory"` Taxonomy input scope. `field` covers one (source_type, source_id, field_id) field scope. `directory` covers all text feedback records for the tenant/directory and must not include source_type, source_id, or field_id. - `"field"` - `"directory"` - `source_id: string` Empty string is the canonical "no source" bucket. - `source_type: string` - `status: "pending" | "running" | "succeeded" | 2 more` Lifecycle state of a taxonomy run. Allowed transitions are pending -> running|failed|canceled and running -> succeeded|failed|canceled. - `"pending"` - `"running"` - `"succeeded"` - `"failed"` - `"canceled"` - `tenant_id: string` - `updated_at: string` - `error?: string` Sanitized failure message; present on failed runs. - `error_code?: "insufficient_data" | "service_unavailable" | "generation_failed" | 2 more` Machine-readable reason a taxonomy run failed or a prerequisite was not met. - `"insufficient_data"` - `"service_unavailable"` - `"generation_failed"` - `"invalid_output"` - `"internal_error"` - `field_label?: string` Human-readable field label; absent when unknown. - `finished_at?: string` - `metrics?: Record` Opaque run metrics recorded by the taxonomy service. - `params?: Record` Opaque run parameters recorded by Hub. - `started_at?: string` ### Node - `Node` 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" | "branch" | "leaf"` Position of a node within the taxonomy tree. - `"root"` - `"branch"` - `"leaf"` - `run_id: string` - `sort_order: number` - `updated_at: string` - `children?: Array` Child nodes, present when the tree is returned hierarchically. - `Node` 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" | "branch" | "leaf"` Position of a node within the taxonomy tree. - `"root"` - `"branch"` - `"leaf"` - `run_id: string` - `sort_order: number` - `updated_at: string` - `children?: Array` Child nodes, present when the tree is returned hierarchically. - `cluster_id?: string` Cluster this node summarizes; typically present on leaf nodes. - `description?: string` - `metadata?: Record` - `original_label?: string` Label as originally generated, before any rename. - `parent_id?: string` Parent node ID; absent for the root node. - `removed_at?: string` Set when the node has been soft-removed. - `removed_by?: string` Actor that soft-removed the node. - `cluster_id?: string` Cluster this node summarizes; typically present on leaf nodes. - `description?: string` - `metadata?: Record` - `original_label?: string` Label as originally generated, before any rename. - `parent_id?: string` Parent node ID; absent for the root node. - `removed_at?: string` Set when the node has been soft-removed. - `removed_by?: string` Actor that soft-removed the node. # Runs ## List `client.taxonomy.runs.list(RunListParamsquery, RequestOptionsoptions?): RunListResponse` **get** `/v1/taxonomy/runs` Returns taxonomy run history for a tenant, most recent first. Optionally filter by scope_type, source_type, field_id, and source_id. source_id is a tri-state filter: omit it for no source filter, pass an empty string to scope to the canonical "no source" bucket, or pass a concrete value to match that source. ### Parameters - `query: RunListParams` - `tenant_id: string` Tenant whose runs should be listed. - `field_id?: string` Optional field_id filter. - `limit?: number` Maximum number of runs to return. - `scope_type?: "field" | "directory"` Optional scope type filter. Omitted means no scope type filter. - `"field"` - `"directory"` - `source_id?: string` Optional source_id filter. Omit for no filter; empty string scopes to the "no source" bucket; a concrete value matches that source. - `source_type?: string` Optional source_type filter. ### Returns - `RunListResponse` - `data: Array` - `id: string` - `cluster_count: number` - `created_at: string` - `embedding_count: number` - `field_id: string` - `node_count: number` - `record_count: number` - `scope_type: "field" | "directory"` Taxonomy input scope. `field` covers one (source_type, source_id, field_id) field scope. `directory` covers all text feedback records for the tenant/directory and must not include source_type, source_id, or field_id. - `"field"` - `"directory"` - `source_id: string` Empty string is the canonical "no source" bucket. - `source_type: string` - `status: "pending" | "running" | "succeeded" | 2 more` Lifecycle state of a taxonomy run. Allowed transitions are pending -> running|failed|canceled and running -> succeeded|failed|canceled. - `"pending"` - `"running"` - `"succeeded"` - `"failed"` - `"canceled"` - `tenant_id: string` - `updated_at: string` - `error?: string` Sanitized failure message; present on failed runs. - `error_code?: "insufficient_data" | "service_unavailable" | "generation_failed" | 2 more` Machine-readable reason a taxonomy run failed or a prerequisite was not met. - `"insufficient_data"` - `"service_unavailable"` - `"generation_failed"` - `"invalid_output"` - `"internal_error"` - `field_label?: string` Human-readable field label; absent when unknown. - `finished_at?: string` - `metrics?: Record` Opaque run metrics recorded by the taxonomy service. - `params?: Record` Opaque run parameters recorded by Hub. - `started_at?: string` ### Example ```typescript import FormbricksHub from '@formbricks/hub'; const client = new FormbricksHub({ apiKey: process.env['HUB_API_KEY'], // This is the default and can be omitted }); const runs = await client.taxonomy.runs.list({ tenant_id: 'org-123' }); console.log(runs.data); ``` ## Start `client.taxonomy.runs.start(RunStartParamsbody, RequestOptionsoptions?): RunStartResponse` **post** `/v1/taxonomy/runs` Starts a manual taxonomy generation run for a field or directory scope. Hub validates that the scope has enough embedded text feedback (below the configured minimum returns 400 with an "insufficient data" validation error), creates the run, and hands it to the taxonomy compute service. Omit scope_type for the existing field scope behavior; use scope_type=directory with tenant_id only to generate one taxonomy over all text feedback in the directory. Idempotent per scope: if a run is already pending or running for the same scope, the existing run is returned with `in_progress: true` (HTTP 200) instead of starting a new one; a newly created run returns HTTP 202 with `in_progress: false`. 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. Requires Hub embeddings and the taxonomy service to be configured; otherwise returns 503. ### Parameters - `body: RunStartParams` - `tenant_id: string` - `actor_id?: string` Optional identifier of the actor starting the run. - `field_id?: string` Required for field scope; omit for directory scope. - `field_label?: string` Optional human-readable field label. - `scope_type?: "field" | "directory"` Taxonomy input scope. `field` covers one (source_type, source_id, field_id) field scope. `directory` covers all text feedback records for the tenant/directory and must not include source_type, source_id, or field_id. - `"field"` - `"directory"` - `source_id?: string` Optional for field scope; empty or omitted is the canonical "no source" bucket. Omit for directory scope. - `source_type?: string` Required for field scope; omit for directory scope. ### Returns - `RunStartResponse` - `in_progress: boolean` True when an existing pending/running run for the scope was returned instead of starting a new one. - `run: Run` A persisted taxonomy generation run. - `id: string` - `cluster_count: number` - `created_at: string` - `embedding_count: number` - `field_id: string` - `node_count: number` - `record_count: number` - `scope_type: "field" | "directory"` Taxonomy input scope. `field` covers one (source_type, source_id, field_id) field scope. `directory` covers all text feedback records for the tenant/directory and must not include source_type, source_id, or field_id. - `"field"` - `"directory"` - `source_id: string` Empty string is the canonical "no source" bucket. - `source_type: string` - `status: "pending" | "running" | "succeeded" | 2 more` Lifecycle state of a taxonomy run. Allowed transitions are pending -> running|failed|canceled and running -> succeeded|failed|canceled. - `"pending"` - `"running"` - `"succeeded"` - `"failed"` - `"canceled"` - `tenant_id: string` - `updated_at: string` - `error?: string` Sanitized failure message; present on failed runs. - `error_code?: "insufficient_data" | "service_unavailable" | "generation_failed" | 2 more` Machine-readable reason a taxonomy run failed or a prerequisite was not met. - `"insufficient_data"` - `"service_unavailable"` - `"generation_failed"` - `"invalid_output"` - `"internal_error"` - `field_label?: string` Human-readable field label; absent when unknown. - `finished_at?: string` - `metrics?: Record` Opaque run metrics recorded by the taxonomy service. - `params?: Record` Opaque run parameters recorded by Hub. - `started_at?: string` ### Example ```typescript import FormbricksHub from '@formbricks/hub'; const client = new FormbricksHub({ apiKey: process.env['HUB_API_KEY'], // This is the default and can be omitted }); const response = await client.taxonomy.runs.start({ tenant_id: 'org-123', actor_id: 'user-42', field_id: 'feedback', scope_type: 'field', source_id: 'survey-abc', source_type: 'formbricks', }); console.log(response.in_progress); ``` ## Retrieve `client.taxonomy.runs.retrieve(stringrunID, RunRetrieveParamsquery, RequestOptionsoptions?): Run` **get** `/v1/taxonomy/runs/{run_id}` Returns a single taxonomy run by ID, scoped to the tenant. Returns 404 if the run does not belong to the tenant. ### Parameters - `runID: string` - `query: RunRetrieveParams` - `tenant_id: string` Tenant that owns the run. ### Returns - `Run` A persisted taxonomy generation run. - `id: string` - `cluster_count: number` - `created_at: string` - `embedding_count: number` - `field_id: string` - `node_count: number` - `record_count: number` - `scope_type: "field" | "directory"` Taxonomy input scope. `field` covers one (source_type, source_id, field_id) field scope. `directory` covers all text feedback records for the tenant/directory and must not include source_type, source_id, or field_id. - `"field"` - `"directory"` - `source_id: string` Empty string is the canonical "no source" bucket. - `source_type: string` - `status: "pending" | "running" | "succeeded" | 2 more` Lifecycle state of a taxonomy run. Allowed transitions are pending -> running|failed|canceled and running -> succeeded|failed|canceled. - `"pending"` - `"running"` - `"succeeded"` - `"failed"` - `"canceled"` - `tenant_id: string` - `updated_at: string` - `error?: string` Sanitized failure message; present on failed runs. - `error_code?: "insufficient_data" | "service_unavailable" | "generation_failed" | 2 more` Machine-readable reason a taxonomy run failed or a prerequisite was not met. - `"insufficient_data"` - `"service_unavailable"` - `"generation_failed"` - `"invalid_output"` - `"internal_error"` - `field_label?: string` Human-readable field label; absent when unknown. - `finished_at?: string` - `metrics?: Record` Opaque run metrics recorded by the taxonomy service. - `params?: Record` Opaque run parameters recorded by Hub. - `started_at?: string` ### Example ```typescript import FormbricksHub from '@formbricks/hub'; const client = new FormbricksHub({ apiKey: process.env['HUB_API_KEY'], // This is the default and can be omitted }); const run = await client.taxonomy.runs.retrieve('019f177f-9aa3-705e-8195-cea2aa187268', { tenant_id: 'org-123', }); console.log(run.id); ``` ## Get Tree `client.taxonomy.runs.getTree(stringrunID, RunGetTreeParamsquery, RequestOptionsoptions?): RunGetTreeResponse` **get** `/v1/taxonomy/runs/{run_id}/tree` Returns the run and its taxonomy tree (visible nodes only; soft-removed nodes are excluded). Tenant-scoped; returns 404 if the run does not belong to the tenant. ### Parameters - `runID: string` - `query: RunGetTreeParams` - `tenant_id: string` Tenant that owns the run. ### Returns - `RunGetTreeResponse` - `root: Node | null` 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" | "branch" | "leaf"` Position of a node within the taxonomy tree. - `"root"` - `"branch"` - `"leaf"` - `run_id: string` - `sort_order: number` - `updated_at: string` - `children?: Array` Child nodes, present when the tree is returned hierarchically. - `Node` 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" | "branch" | "leaf"` Position of a node within the taxonomy tree. - `"root"` - `"branch"` - `"leaf"` - `run_id: string` - `sort_order: number` - `updated_at: string` - `children?: Array` Child nodes, present when the tree is returned hierarchically. - `cluster_id?: string` Cluster this node summarizes; typically present on leaf nodes. - `description?: string` - `metadata?: Record` - `original_label?: string` Label as originally generated, before any rename. - `parent_id?: string` Parent node ID; absent for the root node. - `removed_at?: string` Set when the node has been soft-removed. - `removed_by?: string` Actor that soft-removed the node. - `cluster_id?: string` Cluster this node summarizes; typically present on leaf nodes. - `description?: string` - `metadata?: Record` - `original_label?: string` Label as originally generated, before any rename. - `parent_id?: string` Parent node ID; absent for the root node. - `removed_at?: string` Set when the node has been soft-removed. - `removed_by?: string` Actor that soft-removed the node. - `run: Run` A persisted taxonomy generation run. - `id: string` - `cluster_count: number` - `created_at: string` - `embedding_count: number` - `field_id: string` - `node_count: number` - `record_count: number` - `scope_type: "field" | "directory"` Taxonomy input scope. `field` covers one (source_type, source_id, field_id) field scope. `directory` covers all text feedback records for the tenant/directory and must not include source_type, source_id, or field_id. - `"field"` - `"directory"` - `source_id: string` Empty string is the canonical "no source" bucket. - `source_type: string` - `status: "pending" | "running" | "succeeded" | 2 more` Lifecycle state of a taxonomy run. Allowed transitions are pending -> running|failed|canceled and running -> succeeded|failed|canceled. - `"pending"` - `"running"` - `"succeeded"` - `"failed"` - `"canceled"` - `tenant_id: string` - `updated_at: string` - `error?: string` Sanitized failure message; present on failed runs. - `error_code?: "insufficient_data" | "service_unavailable" | "generation_failed" | 2 more` Machine-readable reason a taxonomy run failed or a prerequisite was not met. - `"insufficient_data"` - `"service_unavailable"` - `"generation_failed"` - `"invalid_output"` - `"internal_error"` - `field_label?: string` Human-readable field label; absent when unknown. - `finished_at?: string` - `metrics?: Record` Opaque run metrics recorded by the taxonomy service. - `params?: Record` Opaque run parameters recorded by Hub. - `started_at?: string` ### Example ```typescript import FormbricksHub from '@formbricks/hub'; const client = new FormbricksHub({ apiKey: process.env['HUB_API_KEY'], // This is the default and can be omitted }); const response = await client.taxonomy.runs.getTree('019f177f-9aa3-705e-8195-cea2aa187268', { tenant_id: 'org-123', }); console.log(response.root); ``` ## Retrieve Record Counts `client.taxonomy.runs.retrieveRecordCounts(stringrunID, RunRetrieveRecordCountsParamsquery, RequestOptionsoptions?): RunRetrieveRecordCountsResponse` **get** `/v1/taxonomy/runs/{run_id}/record-counts` Returns the feedback-record count for every visible node in a taxonomy run. Each count is a subtree total, so a topic (branch) reports the sum of its subtopics and the root reports the run total. Tenant-scoped; returns 404 if the run does not belong to the tenant. ### Parameters - `runID: string` - `query: RunRetrieveRecordCountsParams` - `tenant_id: string` Tenant that owns the run. ### Returns - `RunRetrieveRecordCountsResponse` - `counts: Array` Per-node feedback-record counts, one entry per visible node. - `node_id: string` Taxonomy node ID. - `record_count: number` Number of feedback records in the node's subtree. ### Example ```typescript import FormbricksHub from '@formbricks/hub'; const client = new FormbricksHub({ apiKey: process.env['HUB_API_KEY'], // This is the default and can be omitted }); const response = await client.taxonomy.runs.retrieveRecordCounts( '019f177f-9aa3-705e-8195-cea2aa187268', { tenant_id: 'org-123' }, ); console.log(response.counts); ``` # Active ## Get Tree `client.taxonomy.runs.active.getTree(ActiveGetTreeParamsquery, RequestOptionsoptions?): ActiveGetTreeResponse` **get** `/v1/taxonomy/runs/active/tree` Returns the currently active taxonomy run and its tree for a field or directory scope. Exactly one run is active per scope at a time. Returns 404 when no run has been activated for the scope. ### Parameters - `query: ActiveGetTreeParams` - `tenant_id: string` Tenant that owns the scope. - `field_id?: string` Field ID of a field scope. Must be omitted for directory scope. - `scope_type?: "field" | "directory"` Scope type. Omit for field scope; use directory with tenant_id only for directory taxonomy. - `"field"` - `"directory"` - `source_id?: string` Source ID of the scope; empty string is the canonical "no source" bucket. - `source_type?: string` Source type of a field scope. Must be omitted for directory scope. ### Returns - `ActiveGetTreeResponse` - `root: Node | null` 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" | "branch" | "leaf"` Position of a node within the taxonomy tree. - `"root"` - `"branch"` - `"leaf"` - `run_id: string` - `sort_order: number` - `updated_at: string` - `children?: Array` Child nodes, present when the tree is returned hierarchically. - `Node` 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" | "branch" | "leaf"` Position of a node within the taxonomy tree. - `"root"` - `"branch"` - `"leaf"` - `run_id: string` - `sort_order: number` - `updated_at: string` - `children?: Array` Child nodes, present when the tree is returned hierarchically. - `cluster_id?: string` Cluster this node summarizes; typically present on leaf nodes. - `description?: string` - `metadata?: Record` - `original_label?: string` Label as originally generated, before any rename. - `parent_id?: string` Parent node ID; absent for the root node. - `removed_at?: string` Set when the node has been soft-removed. - `removed_by?: string` Actor that soft-removed the node. - `cluster_id?: string` Cluster this node summarizes; typically present on leaf nodes. - `description?: string` - `metadata?: Record` - `original_label?: string` Label as originally generated, before any rename. - `parent_id?: string` Parent node ID; absent for the root node. - `removed_at?: string` Set when the node has been soft-removed. - `removed_by?: string` Actor that soft-removed the node. - `run: Run` A persisted taxonomy generation run. - `id: string` - `cluster_count: number` - `created_at: string` - `embedding_count: number` - `field_id: string` - `node_count: number` - `record_count: number` - `scope_type: "field" | "directory"` Taxonomy input scope. `field` covers one (source_type, source_id, field_id) field scope. `directory` covers all text feedback records for the tenant/directory and must not include source_type, source_id, or field_id. - `"field"` - `"directory"` - `source_id: string` Empty string is the canonical "no source" bucket. - `source_type: string` - `status: "pending" | "running" | "succeeded" | 2 more` Lifecycle state of a taxonomy run. Allowed transitions are pending -> running|failed|canceled and running -> succeeded|failed|canceled. - `"pending"` - `"running"` - `"succeeded"` - `"failed"` - `"canceled"` - `tenant_id: string` - `updated_at: string` - `error?: string` Sanitized failure message; present on failed runs. - `error_code?: "insufficient_data" | "service_unavailable" | "generation_failed" | 2 more` Machine-readable reason a taxonomy run failed or a prerequisite was not met. - `"insufficient_data"` - `"service_unavailable"` - `"generation_failed"` - `"invalid_output"` - `"internal_error"` - `field_label?: string` Human-readable field label; absent when unknown. - `finished_at?: string` - `metrics?: Record` Opaque run metrics recorded by the taxonomy service. - `params?: Record` Opaque run parameters recorded by Hub. - `started_at?: string` ### Example ```typescript import FormbricksHub from '@formbricks/hub'; const client = new FormbricksHub({ apiKey: process.env['HUB_API_KEY'], // This is the default and can be omitted }); const response = await client.taxonomy.runs.active.getTree({ tenant_id: 'org-123' }); console.log(response.root); ``` # Nodes ## Rename `client.taxonomy.nodes.rename(stringnodeID, NodeRenameParamsbody, RequestOptionsoptions?): Node` **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. ### Parameters - `nodeID: string` - `body: NodeRenameParams` - `actor_id: string` - `label: string` New node label. - `tenant_id: string` ### Returns - `Node` 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" | "branch" | "leaf"` Position of a node within the taxonomy tree. - `"root"` - `"branch"` - `"leaf"` - `run_id: string` - `sort_order: number` - `updated_at: string` - `children?: Array` Child nodes, present when the tree is returned hierarchically. - `Node` 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" | "branch" | "leaf"` Position of a node within the taxonomy tree. - `"root"` - `"branch"` - `"leaf"` - `run_id: string` - `sort_order: number` - `updated_at: string` - `children?: Array` Child nodes, present when the tree is returned hierarchically. - `cluster_id?: string` Cluster this node summarizes; typically present on leaf nodes. - `description?: string` - `metadata?: Record` - `original_label?: string` Label as originally generated, before any rename. - `parent_id?: string` Parent node ID; absent for the root node. - `removed_at?: string` Set when the node has been soft-removed. - `removed_by?: string` Actor that soft-removed the node. - `cluster_id?: string` Cluster this node summarizes; typically present on leaf nodes. - `description?: string` - `metadata?: Record` - `original_label?: string` Label as originally generated, before any rename. - `parent_id?: string` Parent node ID; absent for the root node. - `removed_at?: string` Set when the node has been soft-removed. - `removed_by?: string` Actor that soft-removed the node. ### Example ```typescript import FormbricksHub from '@formbricks/hub'; const client = new FormbricksHub({ apiKey: process.env['HUB_API_KEY'], // This is the default and can be omitted }); const node = await client.taxonomy.nodes.rename('019f177f-9abe-78cd-8008-f40b58e3147d', { actor_id: 'user-42', label: 'Authentication Problems', tenant_id: 'org-123', }); console.log(node.id); ``` ## Soft Remove `client.taxonomy.nodes.softRemove(stringnodeID, NodeSoftRemoveParamsparams, RequestOptionsoptions?): Node` **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`). ### Parameters - `nodeID: string` - `params: NodeSoftRemoveParams` - `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` 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" | "branch" | "leaf"` Position of a node within the taxonomy tree. - `"root"` - `"branch"` - `"leaf"` - `run_id: string` - `sort_order: number` - `updated_at: string` - `children?: Array` Child nodes, present when the tree is returned hierarchically. - `Node` 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" | "branch" | "leaf"` Position of a node within the taxonomy tree. - `"root"` - `"branch"` - `"leaf"` - `run_id: string` - `sort_order: number` - `updated_at: string` - `children?: Array` Child nodes, present when the tree is returned hierarchically. - `cluster_id?: string` Cluster this node summarizes; typically present on leaf nodes. - `description?: string` - `metadata?: Record` - `original_label?: string` Label as originally generated, before any rename. - `parent_id?: string` Parent node ID; absent for the root node. - `removed_at?: string` Set when the node has been soft-removed. - `removed_by?: string` Actor that soft-removed the node. - `cluster_id?: string` Cluster this node summarizes; typically present on leaf nodes. - `description?: string` - `metadata?: Record` - `original_label?: string` Label as originally generated, before any rename. - `parent_id?: string` Parent node ID; absent for the root node. - `removed_at?: string` Set when the node has been soft-removed. - `removed_by?: string` Actor that soft-removed the node. ### Example ```typescript import FormbricksHub from '@formbricks/hub'; const client = new FormbricksHub({ apiKey: process.env['HUB_API_KEY'], // This is the default and can be omitted }); const node = await client.taxonomy.nodes.softRemove('019f177f-9abe-78cd-8008-f40b58e3147d', { actor_id: 'actor_id', tenant_id: 'org-123', }); console.log(node.id); ``` ## List Records `client.taxonomy.nodes.listRecords(stringnodeID, NodeListRecordsParamsquery, RequestOptionsoptions?): NodeListRecordsResponse` **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; returns 404 if the node does not belong to the tenant or has been removed. An empty `data` therefore means the node genuinely holds no records. The `limit` in the response reflects the applied cap. ### Parameters - `nodeID: string` - `query: NodeListRecordsParams` - `tenant_id: string` Tenant that owns the node. - `limit?: number` Maximum number of feedback records to return. ### Returns - `NodeListRecordsResponse` - `data: Array` - `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" | "categorical" | "nps" | 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 - `emotions?: Array<"joy" | "anger" | "sadness" | 3 more>` Emotions inferred from value_text (emotion enrichment); multi-label from a fixed set. Read-only; absent until the record is enriched, and never an empty array. - `"joy"` - `"anger"` - `"sadness"` - `"fear"` - `"surprise"` - `"disgust"` - `field_group_id?: string` Stable identifier grouping related fields (for ranking, matrix, grid questions) - `field_group_label?: string` Human-readable question text for the group - `field_label?: string` The actual question text - `language?: string` ISO language code. NULL bytes not allowed. - `metadata?: Record` Additional context - `sentiment?: "very_negative" | "negative" | "neutral" | 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?: 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?: string` Reference to survey/form/ticket ID - `source_name?: string` Human-readable name - `translation_lang_key?: string` BCP-47 target locale that value_text_translated was produced in (language enrichment). Read-only; absent until the record is enriched. - `user_id?: string` User ID (e.g., anonymous ID or email hash) - `value_boolean?: boolean` Boolean response - `value_date?: string` Date response - `value_id?: string` Stable id of the selected option in the source system (e.g. a survey choice id), stored alongside value_text for durable option identity. Opaque to Hub. Absent for free-text/non-choice answers. NULL bytes not allowed. - `value_number?: number` Numeric response - `value_text?: string` Text response. NULL bytes not allowed. - `value_text_translated?: 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 ```typescript import FormbricksHub from '@formbricks/hub'; const client = new FormbricksHub({ apiKey: process.env['HUB_API_KEY'], // This is the default and can be omitted }); const response = await client.taxonomy.nodes.listRecords('019f177f-9abe-78cd-8008-f40b58e3147d', { tenant_id: 'org-123', }); console.log(response.data); ```