GET /frustrations
Frustration detections with evidence, verbatim user quotes, and an embedded context window.Query parameters
integer
default:"7"
1–90.
integer
default:"10"
1–20. This endpoint’s cap is 20, lower than the general 100.
integer
default:"0"
0–10,000.
string
Scope every figure in the response (summary, signal breakdown, list, and total) to one end user. A detection belongs to the first non-empty
user_id seen in its trace. An empty value returns 400.string
Scope every figure in the response to one trace. An empty value returns
400.Response fields
object
total_analyzed (traces analyzed in the window), frustrated_count, at_risk_count (risk score at least 0.5 but not frustrated), frustration_rate_pct.object
Map of frustration signal to count, across frustrated traces only.
array
Frustrated and at-risk traces, ordered by
frustration_score then risk_score. Each row has conversation_id (the trace ID), is_frustrated, frustration_score, risk_score, trajectory, target, primary_cause, evidence, user_quotes[] (turn, quote, signal), expressed_signals[], observed_signals[], key_turns[], message_count, detected_at, and conversation — an embedded context window from the trace (same shape as /conversations/:id/context) centered on the first key turn, or null.object
limit, offset, total, has_more.object
enabled (true, false, or null), setting ("signals.frustration"), and optional reason (for example "dogfood_tenant"). This is the tenant processing switch that gates emotion and frustration analysis. When enabled is false, no new traces are analyzed, so zero counts mean “not analyzed”, not “no frustration”. null means the setting couldn’t be read, so treat zeros as unconfirmed. Missing settings default to enabled.Example
GET /emotions
Multi-family emotion detections. Moda scores six families —frustration, sadness, confusion, anxiety, trust, positive — with one detection row per trace and family. See Signals in the dashboard for the full 16-signal taxonomy.
Query parameters
integer
default:"7"
1–90.
integer
default:"10"
1–20.
integer
default:"0"
0–10,000.
string
Filter the paginated
detections list (and its total) to one family. The summary and signal_breakdown always cover all families. Unknown values return 400.string
Scope every figure in the response (summary, signal breakdown, list, and total) to one end user. A detection belongs to the first non-empty
user_id seen in its trace. An empty value returns 400.string
Scope every figure in the response to one trace. An empty value returns
400.Response fields
object
conversations_analyzed (traces analyzed), by_family (detected count per family), negative_rate_pct (share of analyzed traces with any negative-family detection), positive_rate_pct, and repair_rate_pct (share of negative detections whose trajectory resolved).array
{family, signal, count} rows across detected traces.array
Detected and at-risk rows, ordered by score. Each has
detection_id, conversation_id, user_id, family, is_detected, score, risk_score, trajectory, elicitor, primary_cause, evidence, user_quotes[], expressed_signals[], observed_signals[], key_turns[], downgrade_reason, detection_grade (rlm for deep analyses, light for the positive-family fast path), message_count, detected_at, and conversation_context (embedded context window or null).object
limit, offset, total, has_more.object
enabled (true, false, or null), setting ("signals.frustration"), and optional reason (for example "dogfood_tenant"). This is the tenant processing switch that gates emotion and frustration analysis. When enabled is false, no new traces are analyzed, so zero counts mean “not analyzed”, not “no frustration”. null means the setting couldn’t be read, so treat zeros as unconfirmed. Missing settings default to enabled.Example
GET /tool-failures
Per-tool failure KPIs for the window. Only tools with at least one failure are listed. This endpoint has no pagination; use/tool-failures/:toolName for examples.
Query parameters
integer
default:"7"
1–90.
Response fields
object
total (failed calls), total_calls (all calls), conversations (traces with a failure), tools (with a failure), failure_rate_pct.array
Ordered by
failure_count descending. Each has tool_name, failure_count, total_count, failure_rate_pct, conversation_count (traces affected), top_error (a sample error message, truncated to 80 characters), last_seen.Example
GET /tool-failures/:toolName
Failure detail for one tool: a breakdown by error subtype plus individual examples with embedded trace context. Subtype names come from your tenant’s failure taxonomy — they are labels, not a fixed enum.Query parameters
string
Filter
examples (and the pagination total) to one error subtype. The subtypes breakdown is always unfiltered.integer
default:"7"
1–90.
integer
default:"5"
1–20.
integer
default:"0"
0–10,000.
Response fields
string
array
{subtype, count, conversation_count, sample_error, last_seen} per error subtype.array
Newest first. Each has
failure_id, conversation_id, error_message, error_subtype, tool_input (truncated), msg_index, detected_at, and conversation — an embedded context window from the trace centered on the failing call, or null.object
limit, offset, total, has_more.Example
GET /hallucinations
Grounding results: agent claims checked against the trace’s world state and tool results.The per-message
detections list contains only two kinds of rows: contradicted (a claim contradicted by evidence) and verified (a claim confirmed by evidence). Ungrounded claims — statements with no supporting or contradicting evidence — appear only in the summary aggregates and are never listed per message.Query parameters
integer
default:"7"
1–90.
integer
default:"10"
1–20.
integer
default:"0"
0–10,000.
string
Scope the response — including the
summary aggregates — to one trace.string
contradicted or verified. Filters the detections list and its total.Response fields
object
Counts across all scored claims:
total_scored, contradicted_count, verified_count, ungrounded_count, ungrounded_rate (0–1), conversations_scored (traces scored), conversations_with_contradiction, and rule_breakdown[] ({source, rule_id, count} for contradictions).array
Contradicted rows first, then by confidence. Each has
conversation_id, message_index, unit_id, segment_id, kind (contradicted or verified), label, confidence, source, rule_id, model_id, violated_receipt_id (or null), violated_slot_key, violated_thread_id, offending_substring, evidence_quote, cws_high_water_msg_index, message_count, detected_at.object
limit, offset, total. This endpoint does not return has_more; page until fewer than limit rows come back or offset + limit >= total.Example
Next steps
- Traces — pull a wider context window around any detection’s key turn.
- Problems — signals grouped into ranked root-cause problems.
- Dashboard: Signals — the same detections with the full emotion and failure taxonomies.