How to

How to build a support performance dashboard

The queue is clear and customers are still unhappy, and the ticket tool cannot tell you why. Here is the model behind a dashboard that can, the prompts to build it, and what it takes to run it.

The short answer

A support performance dashboard is four parts: volume broken down by contact reason rather than by channel, resolution measured as first response and full resolution separately, satisfaction joined back to the specific ticket that produced it, and a repeat-contact view. The measure most teams are missing is contact reason. Ticket counts by channel tell you how busy support is; ticket counts by reason tell you what the rest of the company should fix, and that is the only version of this dashboard that changes anything.

support-performance.helix-app.ai

Support performance

1,842

Tickets this month

2.1h / 19h

Median response / resolve

41

CSAT responses, 8% rate

14%

Contacted twice

412 · 22% repeat
388 · 4% repeat
244 · 9% repeat
198 · 31% repeat
122 · 6% repeat
BrokenHow do IBillingAccessData question

Ranked by volume, flagged by repeat rate. Access problems are a third of the volume of how-do-I questions and generate eight times the repeat contacts.

A sketch of volume by contact reason rather than channel. Channel tells you how busy support is; this tells the rest of the company what to fix.

What matters here

  • A support dashboard is four parts: volume by reason, resolution split into response and resolve, satisfaction joined to the ticket, and repeat contacts.
  • Break volume down by contact reason, not channel. Channel tells you how people reached you; reason tells the rest of the company what to fix.
  • Measure first response and full resolution separately. They fail for different reasons and a single time-to-close hides which you have.
  • Join satisfaction scores back to the ticket. An aggregate NPS with no ticket behind it is a mood, not a finding.
  • Repeat contacts about the same issue are the strongest quality signal in support, and almost nobody measures them.
  • Averages hide the problem. Report the worst decile alongside the median, because that is who is actually angry.

Who this is for

You run support, or you own the customer experience it produces. Your ticket tool reports volume and time to close. What you want is to know what customers keep contacting you about, and whether the people you failed are the ones showing up in the score.

How it works in practice

What happens between a month of tickets and a list product will actually act on.

  1. 1

    Every ticket gets a contact reason

    From a taxonomy you own. Missing reasons are reported as missing rather than bucketed into other.

  2. 2

    Response and resolution are timed separately

    With waiting-on-the-customer excluded from resolution but tracked and shown, since it is a large share of apparent slowness.

  3. 3

    The ninetieth percentile sits next to the median

    Because the median is what gets reported and the ninetieth percentile is who is angry.

  4. 4

    Satisfaction is joined to the ticket that caused it

    With the customer's own words, the reason, the handling time and who handled it.

  5. 5

    Repeat contacts are counted per reason

    A category resolved fast that keeps coming back was not resolved, and no other number on the page shows that.

  6. 6

    One ranked list leaves the team

    Top reasons by volume, repeat rate and dissatisfaction. That is the report for product and engineering.

What a support dashboard is made of

A support dashboard is not the ticket tool with nicer charts. It is four parts, and the first one is the difference between reporting activity and changing anything.

Volume by reason

A taxonomy of what customers actually contacted you about, applied to every ticket. Channel and product area are useful; reason is the one that produces an action outside support.

Resolution, split

Time to first response and time to full resolution, reported separately, with the worst decile shown next to the median. Slow response and slow resolution need different fixes.

Satisfaction, joined up

CSAT or NPS attached to the ticket that produced it, so a low score has a cause you can read rather than a number you can only worry about.

Repeat contacts

Customers coming back about the same issue within a window. The strongest quality signal support produces and the one most dashboards omit.

These prompts start from a Helix project, which is what handles sign-in, credentials and hosting. Start with Helix

The prompts

Paste these into Claude Code, Codex or Cursor in order. Each one leaves you with something that runs, so you can stop after any step.

  1. Volume, by what people actually wanted

    Reason, not channel. This is the whole difference.

    In this Helix project, build me a support performance dashboard.
    
    Pull tickets with their customer, channel, product area, priority, dates
    opened, first responded and resolved, the assignee, and the outcome.
    
    Then the part that matters: a contact reason on every ticket, from a
    taxonomy I can edit. Seed it with categories like how-do-I, broken,
    billing question, access problem, data question, feature request, and
    bug already known.
    
    Report volume by reason first and by channel second. Channel tells me how
    busy support is. Reason tells the rest of the company what to fix, and it
    is the only version of this report that causes anything to change
    outside the support team.
    
    Where reason is missing, say so rather than bucketing into other. The
    proportion of tickets with no reason is itself the first thing to fix.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.

    Worth knowing. Almost every support tool reports by channel and queue because that is what it knows. Reason is the field you have to add, and it is the one that earns the dashboard its place.

  2. Two clocks, and the worst decile

    Because averages hide the people who are actually angry.

    Measure resolution as two separate numbers.
    
    Time to first response, and time to full resolution. Report them apart.
    Slow first response is a staffing or routing problem. Slow resolution is
    a complexity or escalation problem. A single time-to-close figure hides
    which one you have, and the two fixes are unrelated.
    
    Show the median and the ninetieth percentile side by side for both. The
    median is what a team reports; the ninetieth percentile is who is
    actually furious, and the gap between them is the story.
    
    Exclude time spent waiting on the customer from resolution, but track it
    separately and show it. A large share of what looks like slow support is
    a ticket sitting with the person who raised it.
    
    Break both down by reason, so the categories that are slow to resolve are
    visible rather than averaged into the ones that are quick.
  3. Join satisfaction to the ticket

    So a score has a cause attached.

    Add satisfaction, and attach it to the ticket rather than the period.
    
    Import CSAT responses per ticket and NPS responses per contact, with the
    free-text comment kept verbatim.
    
    Then join them: for every low score, show the ticket that produced it,
    its reason, how long it took, who handled it and what the customer wrote.
    An aggregate score with nothing behind it is a mood. A low score with the
    ticket attached is a finding somebody can act on.
    
    Report satisfaction by reason, by agent and by resolution time, so you
    can see whether slow tickets or particular categories drive the low
    scores. Those are usually different answers.
    
    And show response rate. A satisfaction score built on eight percent of
    tickets is a different fact from one built on sixty, and dashboards
    routinely present them identically.
  4. Repeat contacts, and what to send upstream

    The signal support produces and nobody reads.

    Last, build the repeat contact view.
    
    Find customers who contacted you more than once about the same reason
    within a window I set, and customers who reopened a resolved ticket.
    Report the rate, and rank reasons by how often they generate a repeat.
    
    Repeat contacts are the strongest quality signal support has. A category
    resolved quickly and generating repeats was not actually resolved, and
    that is invisible in every other number on this page.
    
    Then produce the report that leaves the support team: the top contact
    reasons by volume, by repeat rate and by dissatisfaction, ranked. That is
    the list to take to product and engineering, and it is the reason to
    build this rather than accept the ticket tool's own reporting.
  5. Connect it to real systems

    The step that turns a working prototype into something with your data in it.

    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Zendesk>. Read every ticket with its dates, assignee, channel and
    outcome. The primary input.
    
    <Okta>. Read the manager relationship, which is what the app checks before
    showing one agent's performance to another.
    
    <Salesforce>. Join tickets to the account and its contract value, so
    volume can be read against who is generating it.
    
    <Snowflake>. Read ticket history at volume, which the support tool will
    not give you cheaply for trend analysis.
    
    <Jira>. Raise the engineering work that would remove a recurring reason,
    and read status back so the dashboard shows what is being fixed.
    
    <Amplitude>. Check whether the customers contacting you about a feature
    are actually using it.
    
    <Slack>. Send the weekly top-reasons digest to product, which is the point
    of the whole dashboard.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.

    Worth knowing. Every name in angle brackets is a placeholder for whatever you run. Helix holds the credential as a workspace authentication, so the app references an alias and never the secret itself.

  6. Ship it

    The last step of every build: a URL, and the right people on it.

    Deploy my app.

    Worth knowing. Your assistant runs helix deploy underneath and the app comes back as a URL. It holds customer comments and per-agent performance, so set Access Control before sharing and think about who should see agent-level detail.

What it connects to

A support dashboard is mostly reads, and the joins between them are where the value is.

  • Zendesk

    Read every ticket with its dates, assignee, channel and outcome. The primary input.

  • Okta

    Read the manager relationship, which is what the app checks before showing one agent's performance to another.

  • Salesforce

    Join tickets to the account and its contract value, so volume can be read against who is generating it.

  • Snowflake

    Read ticket history at volume, which the support tool will not give you cheaply for trend analysis.

  • Jira

    Raise the engineering work that would remove a recurring reason, and read status back so the dashboard shows what is being fixed.

  • Amplitude

    Check whether the customers contacting you about a feature are actually using it.

  • Slack

    Send the weekly top-reasons digest to product, which is the point of the whole dashboard.

Each line says whether the app reads, writes or both. Anything not described as writing should be read only.

Named systems are the ones most teams actually run, not a list of the only ones that work. Swap in whatever you use.

Each connection is an authentication in your Helix workspace, referenced by alias. The app names the connection it wants and never holds the credential, so nothing here ends up in your code and any of it can be rotated or revoked without a redeploy.

Running it for real

The build gets you a working dashboard. It holds verbatim customer feedback and per-agent numbers, so it needs to be run properly.

AI Deployment

Get it to a URL people can open

One command takes the app from your assistant to a live address, so the people who need it get a link rather than instructions for running it locally.

App Security

Put your identity provider in front of it

Per-agent performance and verbatim customer comments are both sensitive, for different reasons. SSO establishes who is looking, and scoped access uses that to show an agent their own numbers and a leader the team.

App Security

Connect the system of record with managed credentials

Pulling tickets and survey responses on a schedule needs real access to your support and survey tools. Granting it to the app rather than pasting keys into it means credentials can be rotated or revoked without a redeploy.

App Registry

Put a name on it

Every app carries a named owner and an entry IT can see, so the tool does not become nobody's problem when the person who built it changes role.

Cost Management

Know what it costs to run

Per-app spend visibility, with budgets and caps, so an internal tool cannot quietly become a line item nobody can explain.

Questions people ask

What should a support dashboard measure that the ticket tool does not?

Contact reason, repeat contacts, and satisfaction joined back to the specific ticket. Ticket tools report volume by channel and queue because that is what they know; reason is the field you add, and it is what produces action outside support.

Why separate first response from resolution?

Because they fail for different reasons. Slow first response is staffing or routing. Slow resolution is complexity or escalation. A single time-to-close number hides which one you have and the fixes are unrelated.

Why report the ninetieth percentile?

Because the median is what a team reports and the ninetieth percentile is who is actually angry. The gap between them is the story, and an average conceals the customers most likely to leave.

What is the point of joining CSAT to the ticket?

A low aggregate score is a mood. A low score with the ticket, the reason, the handling time and the customer's own words attached is a finding somebody can act on. Also report response rate, since a score built on eight percent of tickets is not the same fact as one built on sixty.

Why measure repeat contacts?

Because a category resolved quickly that generates repeat contacts was not actually resolved, and that is invisible in every other number on the page. It is the strongest quality signal support produces and the one most often missing.

Can I build this without an engineering team?

Yes. The prompts here are written for Claude Code, Codex or Cursor and stage the build. The judgement call is your contact reason taxonomy, and it is worth more thought than the rest of the build combined.

Last reviewed September 2026.

Build it, then run it properly

Helix is the governed runtime for AI-built apps. Deploy what you build, put SSO in front of it, connect it to your systems with managed credentials, and give it a named owner.