Skip to main content

Sentiment portfolio dashboard

Contact reasons tells you why customers contact you. Sentiment tells you how they feel while it happens — across every conversation, not one thread at a time. The dashboard at Insights → Sentiment in the Orbit console rolls per-message sentiment scores up into a net sentiment trend with by-channel, by-agent, by-language, and by-resolution breakdowns, so a CX lead can answer “is the customer experience getting better or worse, and where?” without reading transcripts. The same aggregates are available over the API at GET /api/v1/analytics/sentiment — see the Insights API reference for the full response shape.

What Contact reasons deliberately does not cover

The two surfaces split the work on purpose:
  • Contact reasons classifies reason-level intent. Each inbound conversation gets one reason (billing_query, where_is_my_order), one category, and one urgency tag. That answers “what is driving volume” — it does not score tone.
  • Sentiment scores every message on a polarity scale. Each message’s body is scored from -1 (very negative) to +1 (very positive) and labelled positive, neutral, or negative. That answers “how the conversation feels” — independent of its topic.
The split matters operationally. An angry where_is_my_order conversation and a cheerful one share a reason row in Contact reasons but sit on opposite ends of the sentiment dashboard. If you only watch reasons, both look identical until the escalation queue tells you otherwise — usually two windows late. Sentiment is the earlier signal: polarity shifts before the reason mix does. Sentiment scoring is a tenant-owned control, same as auto-categorize: it runs over inbound message bodies and voice transcripts, and you can turn it off under Settings → Compliance → Inbox AI privacy if your regulated content must stay off the LLM hop. With scoring off, no new scores are written and the dashboard keeps showing what was scored while it was enabled.

What the dashboard shows

Open Insights → Sentiment. Four headline tiles sit on top:
  • Net sentiment — the headline index in [-100, 100]: (positive − negative) / analyzed messages, as a percentage. +42 means positives outnumber negatives by 42 points across the window. This is the number CX teams track week-on-week.
  • Analyzed messages — how many messages in the window carry a score. Check this before trusting anything else; a net of -30 on 40 messages is noise, on 40,000 it is a trend.
  • Positive share — the positive slice of the label distribution, so a neutral-heavy portfolio does not masquerade as healthy.
  • Resolution lift — net sentiment of resolved conversations minus that of unresolved ones. Positive lift means resolving correlates with happier customers; negative lift means the backlog is not the problem.
Below the tiles, one trend chart and four breakdown panels:
  • Net sentiment over time — the trend line, bucketed hourly on the 24h window and daily otherwise. A dip with a start day is a diagnosis anchor; a slow grind means compounding friction.
  • By channel — net sentiment per surface (WhatsApp, SMS, email, chat, voice, and so on). The most negative channel that is actually negative carries a “Most negative” badge, so triage starts at the right row.
  • By resolution — resolved vs unresolved sentiment side by side, feeding the Resolution lift tile.
  • By assigned agent — a table per agent: analyzed volume, net sentiment, and the positive / neutral / negative mix. Conversations with no owner appear under unassigned. Treat this panel as a coaching shortlist, not a scorecard — a low net on low volume is one bad thread, not a pattern.
  • By language (API) — the response also breaks sentiment down per detected conversation language, catching the “great in English, failing in Spanish” blind spot. The console renders the channel, resolution, and agent panels; query the API with a language filter when you need the per-locale drill-down.

Reading the dashboard

  1. Pick the window. 24h, 7d (default), 30d, or 90d from the selector in the header. Use 24h for incident triage (“is the dip still moving?”) and 30d or 90d for coaching and staffing decisions, where one bad afternoon should not move the numbers.
  2. Read the headline net first, then the analyzed count. A negative net on thin volume is a sampling artifact; on solid volume it is a real downturn.
  3. Then the trend chart. A single deep bucket points at an event (an outage, a broken template, an angry campaign response). A stair-step decline points at process friction — read the slope, not just the level.
  4. Break down by channel. Narrow the dip to a surface. A portfolio-wide dip that lives entirely on WhatsApp is a channel problem; a dip uniform across channels is a product or policy problem.
  5. Break down by agent, then by resolution. If the dip concentrates on one or two assignees, that is a coaching candidate. The by-resolution panel tells you whether unhappy conversations still closed (process holds up under stress) or are piling open (process is the problem).
  6. Cross-check with Contact reasons. Sentiment says where it hurts; the reason table says what they were writing about. A dip isolated to where_is_my_order on one channel is a very different fix from a dip spread across every reason.

Sentiment × resolution — the correlation to track

The Resolution lift tile is the panel most teams under-read. Two shapes and what each means:
  • Resolved sentiment ≫ unresolved sentiment (large positive lift). Resolution works. The negative tail lives in the open backlog — chase queue hygiene (SLA, ownership, follow-ups), not agent behavior.
  • Resolved sentiment ≈ unresolved sentiment (lift near zero or negative). Closing a conversation is not making customers happier. That points at the quality of resolution — technically-closed-but-satisfied-in-name-only threads — and belongs in coaching or your resolution definition, not the queue.
Read lift on the 30d window. On 24h it is dominated by whatever incident is live; on 30d it reflects how your operation converts contact into satisfaction.

Worked example

A support director at an e-commerce tenant opens Insights → Sentiment on a Monday with the 7d window:
  1. The Net sentiment headline reads −18 against an analyzed-message count well into the thousands — volume is sufficient to trust the number.
  2. The trend chart shows the downturn starting Thursday, not a gradual slide — an event, not erosion.
  3. The By channel panel badges WhatsApp as “Most negative” at −41 while email and chat hold slightly positive. The dip is one surface, not the portfolio.
  4. The By assigned agent table shows one agent at −38 on solid volume while teammates sit between −5 and +12. Two agents does not make a roster problem, but one agent plus one channel makes a coaching candidate.
  5. She opens Contact reasons with the same window: return_status jumped on WhatsApp over the same days — topic-specific, not a general tone problem.
  6. In Agent comparison, the same agent’s resolution rate on return_status chats trails the team by 20 points — the coaching target is now concrete: one agent, one topic, one channel.
  7. The Resolution lift tile is still positive, so the org’s resolution process itself is intact — the drag has not reached the escalation panel yet, and she has the window to act before it does.
One coaching conversation about the returns flow on WhatsApp closes the loop; the next two windows confirm the agent’s net and the channel’s badge clearing.

API access

Every panel is one call:
Response shape (trimmed):
  • window: 24h, 7d (default), 30d, or 90d.
  • channel: narrows the trend, agent, resolution, and language breakdowns to one surface — GET /analytics/sentiment?window=7d&channel=whatsapp.
  • language: narrows every breakdown to one detected conversation language (for example es), or unknown for messages with no detected language.
  • net_sentiment is the headline index in [-100, 100]; avg_score is the raw mean in [-1, 1]; granularity tells you whether trend buckets are hourly (24h) or daily.
The endpoint is tenant-scoped and read-only. Access matches the dashboard: owner, admin, developer, and viewer roles. Responses are cached for 60 seconds, so a poller on a one-minute cadence is the right shape. The per-dimension breakdowns return the top 25 rows by analyzed volume.

See also