GET /overview
Headline KPIs for a window, plus top clusters and recent activity.Query parameters
integer
default:"7"
1–90. Applies to the conversation, frustration, and tool-failure KPIs.
Response fields
object
{days} — the effective window.object
total in the window and trend_pct — percentage change versus the previous window of equal length (one decimal; 0 when the previous window was empty).object
total_analyzed, frustrated, at_risk (risk score at least 0.5 but not frustrated), rate_pct.object
total (failed calls), conversations, tools.array
Up to 10 clusters from the latest clustering run, largest first:
node_id, label, summary, keywords[], segment_count.array
The 10 most recent conversation summaries:
conversation_id, summary, timestamp. Always covers the last 7 days, regardless of days_back.Example
GET /clusters
Browses the hierarchical use-case clusters from the latest completed clustering run. Call it without parameters for the root level; pass a node’snode_id as parent_id to descend.
Query parameters
string
Return the children of this node. Omit for root-level nodes. The response’s
breadcrumb traces the path from the root to this node.string
default:"all"
Accepted and validated, but the hierarchy currently reflects the latest clustering run regardless of this value.
Response fields
object | null
The latest completed run:
id, num_categories, num_clusters, num_segments, completed_at. null when no taxonomy exists yet — the first one is built once at least 50 analyzed segments exist.array
{node_id, label} path from the root to parent_id. Empty when parent_id is omitted.array
Child nodes ordered by size:
node_id, label, summary, keywords[], node_type, segment_count, has_children, depth.object
total_clusters and total_segments for the whole run.Example
GET /clusters/:nodeId/conversations
Lists conversations whose segments belong to one cluster node.An unknown
nodeId returns 200 with cluster: null and an empty conversations array — not 404. Check cluster before reading the list.Query parameters
integer
default:"10"
1–100.
integer
default:"0"
0–10,000.
Response fields
object | null
node_id, label, summary, segment_count — or null when the node does not exist in the latest run.array
conversation_id, summary, message_count.object
limit, offset, total, has_more.Example
GET /task-clusters/search
Searches cluster nodes in the latest hierarchy by name or meaning. Use it to resolve a phrase like “refund requests” to anode_id you can pass to /clusters/:nodeId/conversations or the cluster_id filter on /conversations.
Query parameters
string
Search text, 2–200 characters. Required unless
node_id is given.string
Deterministic lookup of one node (returns that node with its ancestor path). Makes
q optional.string
default:"hybrid"
fuzzy, semantic, or hybrid.integer
default:"30"
1–50.
Response fields
string | null
The run the matches came from.
null (with empty matches) when no clustering run exists yet.string
The mode that actually served the request. Falls back to
fuzzy when semantic search is unavailable.array
Each match has
node_id, parent_id, depth, node_type, label, description, keywords[], segment_count, ancestor_path[] ({nodeId, label, depth} from the root), path_truncated, and similarity (semantic/hybrid matches only).Example
Next steps
- Conversations — filter the conversation list by
cluster_id. - Dashboard: Use Cases — the same hierarchy in the dashboard, including how the taxonomy is built.
- Problems — ranked root-cause problems across signals.