# Support performance dashboard for your Crisp operators

> Open one screen every Monday to see how each support agent actually performed, and clear the oldest unanswered chats without leaving the page.

- Workflow type: app
- Services: Crisp, Google Sheets
- Categories: Customer Support, Operations
- Published: 2026-08-17

## What it does

- Pick any date range and see the headline numbers for that period: chats handled, how many are still sitting open, how fast your team sent its first reply, and how many were resolved.
- Rank every operator side by side on chats assigned, chats resolved, and typical first reply speed, so you can see who is carrying the load and who is falling behind.
- Work the backlog from the same screen. The oldest unanswered chats are listed first, and you can assign one to an agent or mark it resolved in a single click.
- Save the period's numbers to a Google Sheet with one button, building a performance history your team owns instead of a report you cannot export.

## What you'll need

- A Crisp account with live chat running, and permission to view your website's conversations
- The operators on your Crisp website already set up, since the dashboard picks them up automatically
- A Google account and a spreadsheet, if you want to save snapshots and keep a history
- A few weeks of chat history in Crisp so the trends and medians are meaningful

## Prompt

Build me an internal support performance dashboard for Crisp that I open every Monday to answer the question Crisp's own analytics cannot: how did each of my operators actually do this week, and what is still sitting in the backlog. It is a single screen with a date range picker, headline tiles, a per operator table, and an aging backlog queue I can act on. It also saves each period's numbers to a Google Sheet.

A date range picker sits at the top of the page and controls everything below it. Default it to the last 7 days, with quick presets for last 7 days, last 30 days, this month, and last month, plus a custom range. Crisp has no server side date filtering on conversations, so the handler must fetch conversations with Crisp List Conversations and filter them by timestamp itself. Crisp list endpoints take the page number as the last path segment, so the handler needs to keep advancing pages until a page comes back shorter than the page size, then stop. Crisp timestamps are Unix epoch in milliseconds, so convert them before comparing or displaying.

Across the top show four headline tiles for the selected range: conversations handled, unresolved backlog, median first response time, and resolved count. Conversations handled is every conversation with activity inside the range. Unresolved backlog is the count of conversations still in an unresolved or pending state, and this one is a live number rather than a range bound one, so label it clearly. Resolved count is conversations whose state is resolved. Show each tile with a comparison against the previous period of the same length, so the lead can see whether things got better or worse.

First response time is the core metric and Crisp does not give it directly, so compute it. For each conversation in range, call Crisp Get Messages In Conversation and walk the messages in time order. Each message carries a from field that is either user or operator. Find the first message where from is user, then find the first message after it where from is operator, and the gap between those two timestamps is that conversation's first response time. Report the median rather than the mean so a single abandoned chat does not distort the number. Conversations that never got an operator reply must not be counted as zero or dropped silently: track them as a separate never answered count and surface it next to the median, because those are the ones that matter most.

Below the tiles, a per operator table. Load the roster with Crisp List Website Operators, then join each conversation to its assigned operator using Crisp Get Conversation Routing. For every operator show assigned in period, resolved in period, median first reply time, never answered count, and oldest unresolved chat age. Make every column sortable and default the sort to the weakest median first reply time so problems surface first. Include an Unassigned row for conversations with no routing, since those are usually the real gap. Clicking any operator row filters the backlog list below to just their chats.

Then an aging backlog list showing the oldest unresolved conversations first, with the customer name or email, a snippet of the last message, the assigned operator, and the age in days rendered so anything over a few days reads as urgent. Each row has two inline actions so the lead can clear the queue without opening Crisp: an operator dropdown that calls Crisp Assign Conversation Routing, and a state control that calls Crisp Change Conversation State to set pending or resolved. Both actions should update the row optimistically, then refresh the affected numbers, and roll back visibly with an error message if the write fails.

Clicking any row anywhere in the app opens the full transcript inline, in a side panel rather than a new page, using Crisp Get Messages In Conversation. Render visitor messages and operator messages as distinct sides of a conversation with timestamps, and mark the message that set the first response time so the lead can see exactly what was measured. The assign and resolve actions should also be available from inside the transcript panel.

A Save snapshot button appends the current period's numbers as a row to a Google Sheet using Google Sheets Append Values. The row should carry the range start, the range end, the date it was saved, and each headline figure: conversations handled, unresolved backlog, median first response time in minutes, resolved count, and never answered count. This exists because Crisp's own export only returns topline figures and teams want a history they own, so the sheet is append only and never overwritten. Let the user pick the spreadsheet and tab once and remember that choice, and warn before appending a duplicate row for a range that has already been saved.

On behaviour and performance: fetching messages is one call per conversation, so batch those requests with a sensible concurrency limit, cache results within a session, and show the tiles and table filling in progressively rather than blocking the whole page on the slowest call. Crisp rate limits per token and returns 429 or 420 when a limit is hit, so back off and retry rather than failing the whole view. Remember the last selected date range and the chosen spreadsheet per user between visits. The audience is a support lead reviewing their team, so lead with clarity: real numbers, plain labels, and no chart that does not answer a question they actually asked.

## How to customize

- Change the default date range from the last 7 days to whatever period your team reviews, such as a fortnight or a full month.
- Decide what counts as a first reply, for example skipping automated greetings or bot messages so only genuine human replies are timed.
- Point the Save snapshot button at a different spreadsheet or tab, and add extra columns such as a row per operator rather than one row per period.

## FAQ

### Does this replace Crisp's own analytics?

It answers the questions Crisp's built in reports do not, like how each individual operator performed over a period you choose and which chats have been sitting unanswered the longest. It reads the same conversations you already see in Crisp, so nothing is duplicated or moved.

### Why can I not just export this from Crisp?

Crisp exports return topline totals only, so per agent breakdowns and conversation level detail do not come through. This dashboard rebuilds those numbers from your actual chat history, which is also why the Save snapshot button matters: it gives you a record you keep.

### How is first response time measured?

It is the gap between the first message a customer sends in a chat and the first reply from one of your operators in that same chat. Chats that never received a human reply are flagged separately rather than quietly skewing the average, and the dashboard shows the median so one very slow chat does not distort the picture.

### Will assigning or resolving a chat here actually update Crisp?

Yes. Assigning a chat to an operator or changing its state writes straight back to Crisp, so your team sees the change in their normal inbox right away. Nothing is queued or held in a separate system.

### Do I have to connect a Google Sheet?

Only if you want to keep a history. The dashboard works fine without it. The Save snapshot button is there for teams who want each period's numbers appended to a spreadsheet they control, so they can chart trends over months.

### Can I read the full conversation from the dashboard?

Yes. Clicking any row in the operator table or the backlog list opens the full transcript inline, showing which messages came from the customer and which came from your team, so you can check the context before you assign or resolve it.

Use this prompt in General Input: https://www.generalinput.com/prompts/support-performance-dashboard-for-your-crisp-operators