---
updatedAt: 2026-06-06T15:15:50.000Z
---

Fetch the complete documentation index at: https://docs.lodgestory.com/llms.txt. Use this file to discover all available pages before exploring further.

# Analytics

<br />

> See what's happening in your inbox right now, what's been happening over the last 7, 30, or 90 days, and write your own SQL widgets when the built-in metrics aren't enough.

> **TL;DR**
>
> * **What it is —** a live operations panel (active chats, unanswered, waiting times, agents available, calls in progress) plus historical charts for response times, resolution, tickets, calls, and bots — and a custom-query builder where you can save and run your own SQL widgets, with an AI assistant that writes the SQL for you from plain English.
> * **Who it's for —** team leads watching the day in real time; managers reviewing weekly and monthly trends; admins building org-specific KPIs the standard dashboard doesn't ship.
> * **Top outcome —** answer *"how are we doing right now?"* in two seconds, *"how were we doing last month?"* in five, and ship a custom widget without writing SQL by hand.

## At a glance

|                    |                                                                                                                                                                                     |
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Plan tier**      | All paid tiers.                                                                                                                                                                     |
| **Who can use it** | All roles can view. Custom-query authoring is recommended for admins.                                                                                                               |
| **Channels**       | Organisation-wide across every channel. Several metrics support a per-channel breakdown.                                                                                            |
| **Integrations**   | Reads from the live inbox, chat states, contacts, tickets, calls, and bot journeys.                                                                                                 |
| **Top limits**     | Right-now tiles refresh every 30 seconds. Historical metrics support 24-hour, 7-, 30-, 90-day presets and any custom range. Custom queries are capped at 5 seconds and 10,000 rows. |
| **API**            | Internal only. Authoring custom queries is the supported way to extend the dashboard.                                                                                               |

## How to find it

**Sidebar → Analytics.**

**Direct URL:** `https://app.lodgestory.com/crm/insights`

📸 `[SCREENSHOT: analytics-nav.png — sidebar with Analytics highlighted]`

## What is Analytics?

### The problem it solves

Most teams need three different answers from their analytics: *what's happening this minute?*, *how have we been doing this week?*, and *the standard dashboard doesn't break it down the way I think about my business — can I get a custom view?*. The first is a real-time operations question. The second is a trend question. The third is "we run a different kind of business and the canned KPIs don't fit." A traditional analytics page answers one well and the others poorly.

The Analytics module answers all three from one page. The top of the page is a live operations panel that refreshes every 30 seconds. Below it, historical metrics for chats, tickets, calls, and bot performance over a date range you choose. And in a separate tab, a custom-query builder where you write SQL once, save it, and run it any time — with the data automatically scoped to your organisation.

### What you get

* **Live operational tiles** that refresh on a 30-second loop — active chats, unanswered chats, the waiting-time distribution against SLAs you configure, oldest waiting chat, agents available, calls in progress, bot sessions in progress. The active and unanswered tiles exclude resolved & closed chats, so a closed thread never inflates your waiting counts.
* **Configurable waiting SLAs** — pick a tight (5m / 15m / 30m), default (5m / 1h / 4h), or relaxed (1h / 4h / 24h) preset, or set custom thresholds. Tiles re-bucket immediately.
* **Historical charts** — message volume, first response time (median), average response time, average resolution time. Each on a date range you choose.
* **Date range picker** — 24-hour, 7-day, 30-day, 90-day presets, plus a custom-range option for any window you want.
* **Agent leaderboard** — every active agent with their name, avatar, messages sent, chats handled, calls handled, talk time, FRT median, and ART average. Click an agent to drill into their profile.
* **Per-agent profile** — six KPI tiles for one agent plus their first-response-time trend.
* **Tickets, Calls, and Bots tabs** — purpose-built charts for each surface (created vs resolved, call volume + handle time, bot containment rate).
* **Availability tab** — total available vs. unavailable time and a per-break breakdown over your date range, plus a per-agent comparison and detail table. Admins see the whole team; an agent sees their own.
* **Custom queries** — write SQL with PostgreSQL syntax highlighting, autocomplete for the org-readable table list, and pick the visualisation type (KPI, bar, line, pie, or table). Save it, activate it, and run it any time.
* **Ask AI** — describe a metric in plain English and the assistant returns a complete query (SQL + name + description + visualisation type) ready to drop into the editor. Multi-turn — refine ("now group by channel", "and only the last 7 days") in conversation.
* **Download CSV** — every result preview and the agent leaderboard exposes a one-click CSV export (UTF-8 with a BOM so Excel opens cleanly).

### How it's different

* **Live + historical on the same page.** Most analytics pages are one or the other. This one shows the day-to-day right now and the trend underneath in one scroll.
* **Configurable SLAs, not fixed buckets.** The waiting-chat tiles bucket against thresholds *you* set. Hospitality teams running 24/7 want different SLAs than agencies with strict business hours; the dashboard adapts.
* **Custom queries built in.** Write your own dashboard widgets in SQL, save them, share visualisations. No second tool needed for org-specific KPIs.
* **AI writes the SQL for you.** The Ask AI assistant has been pre-trained on the full analytics data model — every readable table, the JSON shapes of fields like the latest message blob and bot session variables, and a library of canonical query patterns the built-in metrics already use. You describe what you want; it generates SQL that matches the same patterns.
* **Tenant safety on by default.** Every saved query is scoped to your organisation automatically — there's no path that lets one organisation read another's data, even if a query author writes a sloppy WHERE clause.

### Customer scenarios

* **Daily standup.** Team lead opens Analytics first thing. Live tiles show unanswered count and oldest waiting time; historical chart confirms first-response time is trending in the right direction. They click into the agent leaderboard, sort by FRT, and spot the agent who's slipping.
* **Quarterly review.** Operations manager picks a 90-day range, screenshots the four overview charts, and pastes them into the deck. They flip to the Tickets tab for ticket volume + resolution time, screenshot those too.
* **Custom KPI for marketing.** Marketing wants to track "chats per UTM source per day". They write a SQL query against the conversations and contacts data, save it as "Chats by source", set it to a bar chart, and pin it. They share the URL with their team and check it weekly.
* **SLA breach hunt.** A hospitality customer has chats waiting > 4 hours during weekends. They open the SLA settings, switch to the relaxed preset, and the tiles instantly show the new buckets — they can quantify the problem before staffing weekend shifts.

### How it fits with the rest of Lodgestory

This module is a consumer, not a producer. Every metric is derived from data owned by other modules: message volumes from [Home](home-unified-inbox.md), chat states from [Workflow Lifecycle Stages](../settings/workflow-lifecycle-stages.md), assignments and identities from [Team Members](../settings/team-members.md), tickets from [Tickets](tickets.md), call activity from [Calls](calls.md), bot sessions from [Bot Journeys](../settings/bot-journeys.md). Downstream: [Reports](reports.md) exports raw CSVs when you want to do work in a spreadsheet or BI tool.

📸 `[SCREENSHOT: analytics-landing.png — Analytics overview with live tiles and historical charts]`

## Core concepts

| Term                      | What it means                                                                                          |
| ------------------------- | ------------------------------------------------------------------------------------------------------ |
| **Right-now tile**        | A live counter that refreshes every 30 seconds (active chats, unanswered, agents available, etc.).     |
| **Waiting SLA threshold** | A duration in minutes that defines a bucket on the waiting-chat tiles. Configurable per organisation.  |
| **Historical metric**     | An aggregated value over a date range (e.g., median first-response time per hour for the last 7 days). |
| **Date range**            | The window historical charts are computed over. Four presets plus a custom range.                      |
| **Agent leaderboard**     | One row per agent active in the window, sortable by activity.                                          |
| **Custom query**          | A saved SQL query with a chosen visualisation type. Runs against your organisation's data only.        |
| **Library template**      | A starter custom query published by Lodgestory that any organisation can copy and edit.                |
| **Active vs Draft**       | A custom query in *draft* exists but cannot be run. Activate it once it's reviewed.                    |

## Quick Start — read the dashboard in two minutes

### Step 1 — Open Analytics

Sidebar → **Analytics**.

### Step 2 — Glance at the live tiles

Top of the page. They refresh every 30 seconds; a pulsing green dot and "last update HH:MM:SS" confirm they're alive.

### Step 3 — Tune the waiting SLAs once

The gear icon next to "Right now" opens a small settings panel. Pick a preset that fits your business, or type your own thresholds in minutes. Tiles re-bucket immediately.

### Step 4 — Pick a date range

Top right — **24h**, **7d**, **30d**, **90d**, or **Custom**. Custom opens a popover with two date pickers.

### Step 5 — Read the four overview charts

Message volume, FRT (median), ART (average), and average resolution time, all over the selected window.

### Step 6 — Drill into an agent

Open the **Agents** tab. Click any row to see that agent's full profile — six KPI tiles plus their FRT trend.

### Step 7 — (Optional) Write a custom query

Open the **Custom queries** tab → **+ New query**. Write SQL, choose a visualisation, toggle Active, save, and click **Run**.

## How it works

The right-now tiles read directly from your live data — there's no separate snapshot. Every 30 seconds the page asks for fresh values; the database returns them in well under 100 milliseconds.

The historical charts run aggregations across the date range you've chosen. Standard time-bucketed views (per hour, per day) come back in milliseconds for typical organisations.

Custom queries run under a locked-down read-only role with a five-second hard time-out and a 10,000-row cap. Tenant filtering is enforced automatically — your queries only see your organisation's data.

## Features in depth

### Right-now tiles

* **Active chats** — open conversations with state machine still active.
* **Unanswered** — chats whose latest message is from a guest.
* **Waiting tiles** — one tile per configured SLA threshold, showing how many unanswered chats are older than each. Severity colour shifts from neutral to warning to danger as the threshold is crossed.
* **Oldest waiting** — the age of the longest-waiting unanswered chat, formatted as `5m`, `2h`, `3d`.
* **Agents available** — team members with availability turned on.
* **Active calls** — calls connected right now.
* **Active bot sessions** — bot journeys mid-flight.

### SLA configuration

The gear icon opens a settings popover with three preset templates and three minute-input fields:

* **Tight** — 5m / 15m / 30m
* **Default** — 5m / 1h / 4h
* **Relaxed** — 1h / 4h / 24h

Pick a preset, or type your own. You can configure between 1 and 5 thresholds. They're sorted ascending automatically. **Save** updates the right-now tiles immediately.

### Date range

Four presets — **24h**, **7d**, **30d**, **90d** — plus a **Custom** button that opens a popover with two date pickers. The active selection is highlighted; when a custom range is picked, the button shows the actual dates.

### Overview charts

* **Message volume** — bar chart, inbound vs outbound counts per hour or day.
* **First response time (median)** — area chart of median seconds between a guest message and the first agent reply, per hour.
* **Average response time** — area chart of mean seconds across every guest→agent gap, per hour.
* **Average resolution time** — line chart of mean seconds from chat open to closure, per day.

All four use a single primary colour for clarity. Hovering shows the bucket value.

### Agent leaderboard

A sortable table covering every agent active in the window:

| Column   | Description                                    |
| -------- | ---------------------------------------------- |
| Agent    | Name + email + avatar with relative-volume bar |
| Messages | Outbound messages this agent sent              |
| Chats    | Distinct conversations they handled            |
| Calls    | Calls they handled                             |
| Talk     | Total minutes spent in calls                   |
| FRT p50  | Their median first-response time, in seconds   |
| ART avg  | Their average response gap, in seconds         |

Click any row to open the per-agent profile.

### Per-agent profile

Header with avatar, name, and email. Six KPI tiles: messages, chats handled, calls handled, talk time, FRT p50, ART average. Below them, a chart of that agent's FRT trend over the same date range.

A back arrow returns to the leaderboard.

### Tickets, Calls, Bots tabs

* **Tickets** — created per day (bar) and average resolution time per day (line).
* **Calls** — total per hour (bar, grouped by direction) and average handle time per hour (line).
* **Bots** — bot containment rate per day (line). Containment = completed sessions that did not hand off to a human, divided by total completed sessions.

Each tab has its own date range picker.

### Availability

The **Availability** tab turns each agent's availability history into a duration report over your chosen date range:

* **Three headline tiles** — total time the team was available, total time unavailable, and the availability rate (available ÷ total).
* **Break breakdown** — a horizontal bar chart of total time per break label (*Lunch*, *Meeting*, …), grouped by the label recorded at the time.
* **Available vs. unavailable by agent** — a stacked bar per agent, sorted by unavailable time. *(Admins only.)*
* **Per-agent detail table** — each agent's available and unavailable totals, with a chip per break and its duration. *(Admins only.)*

Admins see the whole organisation; an agent without admin rights sees only their own numbers. Durations are computed from the gaps between availability changes, so the report is only as complete as the history — an agent who has never changed their status has nothing to show yet. Break labels come from [Break Types](../settings/break-types.md), and agents set their status from the [Home / Unified Inbox](home-unified-inbox.md#availability-status) dropdown.

### Custom queries

The **Custom queries** tab lists every query for your organisation plus library templates published by Lodgestory. Library templates have a faded border so they're easy to spot.

**+ New query** opens an editor with:

* A name and description
* A SQL editor with PostgreSQL syntax highlighting, line numbers, bracket matching, code folding, and ctrl-space autocomplete. Autocomplete knows the table and column names of every readable table in your organisation's data.
* A visualisation picker — KPI, bar, line, pie, or table.
* An **Active** toggle. New queries default to Draft; activate once you've reviewed the SQL.
* A **Run** button that executes the query and renders the result inline. The chosen visualisation drives the rendering — KPI shows the first numeric value as a big number, bar/line/pie chart the data appropriately, table shows everything in a sortable grid.

Tenant filtering is automatic — your queries only ever see your organisation's data. The convention is to reference `$1` in your `WHERE` clause; Lodgestory binds your organisation ID to it before the query runs.

Every result preview also exposes a **CSV** button that downloads the rows as a UTF-8 CSV (Excel-compatible).

📸 `[SCREENSHOT: analytics-custom-editor.png — custom query editor with SQL highlighted and a pie chart preview]`

### Ask AI — generate queries from plain English

Click the **✨ Ask AI** button on the editor. A side panel opens with a chat input. Describe the metric:

> "Top 10 contacts by inbound message volume in the last 7 days"
> "Median first response time per hour, last 24 hours"
> "Tickets opened vs resolved by priority over the last 30 days"
> "Bot containment rate per day for the last 2 weeks"
> "Average call handle time per hour, inbound only"

The assistant returns a complete widget — SQL, suggested name and description, and a visualisation type — rendered in the panel for review. Click **Insert into editor** to populate every field at once.

The conversation is multi-turn, so you can refine without retyping:

> "Now restrict to WhatsApp only" — adds the channel filter.
> "Group by hour of day instead" — switches the bucketing and the chart type.
> "Exclude archived chats" — adds the soft-delete filter.
> "Only open chats" / "exclude closed chats" — the assistant knows the resolved-&-closed flag and adds the `resolvedAt IS NULL` filter; ask for "resolved chats" or "chats closed by *agent*" to go the other way.

The assistant has been instructed to:

* Generate read-only SQL only — no writes, no schema changes.
* Always scope queries to your organisation.
* Refuse out-of-scope requests, attempts to read tables outside the analytics allowlist, and prompt-injection attempts.
* Surface caveats in **Warnings** when a query has an obvious limitation (for instance, agent display names are resolved by Lodgestory after the query runs, not by the SQL itself).

If a generated query has a lint warning, the panel surfaces it inline so you can fix or accept before inserting. Generated queries land in **Draft** state — review them and toggle **Active** before running.

📸 `[SCREENSHOT: analytics-ask-ai.png — Ask AI panel with a chat transcript and the generated SQL preview]`

## Roles and permissions

| Action                                         | Account Owner | Admin | User |
| ---------------------------------------------- | :-----------: | :---: | :--: |
| View Analytics                                 |       ✓       |   ✓   |   ✓  |
| See colleagues' stats in the agent leaderboard |       ✓       |   ✓   |   ✓  |
| Configure waiting-chat SLAs                    |       ✓       |   ✓   |   —  |
| Create / edit / activate custom queries        |       ✓       |   ✓   |   —  |
| **Use Ask AI to generate SQL**                 |       ✓       |   ✓   |   —  |
| Run an active custom query                     |       ✓       |   ✓   |   ✓  |
| Download results as CSV                        |       ✓       |   ✓   |   ✓  |
| Delete a custom query                          |       ✓       |   ✓   |   —  |

Every team member sees every other member's numbers in the agent leaderboard. Custom-query authoring is admin-only by default; if you want a user-facing builder for non-admins, request it.

## Cross-module workflows

### "Are we keeping up right now?" daily check

Team lead opens Analytics. Live tiles show **Unanswered: 3** and **Oldest waiting: 12m**. They sort the agent leaderboard by FRT to confirm coverage looks right, then move on with their day. Total time: 30 seconds.

**Modules involved:** Analytics → [Home](home-unified-inbox.md) (to actually act on the unanswered chats).

### "Why is response time creeping up?" investigation

Manager picks a 30-day range, sees FRT trending upward in the last week. Switches to 7d, sees it's spiking on weekends. Opens the agent leaderboard for last weekend, identifies whose numbers slipped. Checks [Team Members](../settings/team-members.md) for their schedule.

**Modules involved:** Analytics → Team Members → optionally [Reports](reports.md) for deeper export.

### "Custom KPI for our hospitality model"

Operations team needs to track "chats per property" — a custom field on contacts. They write a SQL query that joins conversations to contacts, groups by the property field, and renders as a bar chart. Save → Activate → Run. Pin the URL. Check weekly.

**Modules involved:** Analytics (custom queries) → [Contacts](contacts.md) (where custom fields are defined).

### "I don't know SQL — let the AI write it"

Marketing manager wants a "messages per UTM source per day" widget. They open Custom queries → New → click **✨ Ask AI** → type *"messages per day grouped by the utm\_source custom field on the contact"*. The assistant returns a query joining conversations to contacts, extracting `customFields->>'utm_source'`, with a bar visualisation pre-selected and a name like "Daily messages per UTM source". They click **Insert into editor**, toggle **Active**, hit **Run**. If the chart looks right they're done; if they want a refinement ("only the last 30 days, only inbound"), they re-open the panel and add a follow-up turn — the assistant edits the existing query rather than starting fresh.

**Modules involved:** Analytics (custom queries + Ask AI) → [Contacts](contacts.md).

### "SLAs are breaking on weekends"

Manager opens SLA settings, switches from Default (5m / 1h / 4h) to a Tight preset to see the breakdown more granularly. The waiting tiles re-bucket; they screenshot. Then they switch back to Default for the next staffer who picks up the dashboard.

**Modules involved:** Analytics (live tiles + SLA configuration).

## Limits a user will run into

| Limit                          | Value                                                                                         |
| ------------------------------ | --------------------------------------------------------------------------------------------- |
| Right-now tile refresh         | 30 seconds                                                                                    |
| Waiting SLA thresholds         | 1–5 entries, in minutes                                                                       |
| Date range                     | 4 presets + custom                                                                            |
| Agent leaderboard size         | Every active agent in the window (no top-N cap)                                               |
| Custom query — execution time  | 5 seconds                                                                                     |
| Custom query — result size     | 10,000 rows                                                                                   |
| Custom query — readable tables | An explicit allowlist of analytics-relevant tables. Anything else returns a permission error. |
| Ask AI — turns per session     | 30 (chat history is held in your browser; closing the editor clears it)                       |
| Ask AI — message length        | 8,000 characters                                                                              |
| CSV export                     | Whatever's currently displayed (capped by the 10,000-row execution limit)                     |

## Errors & FAQ

| You see                                                        | Likely reason                                               | What to do                                                                                    |
| -------------------------------------------------------------- | ----------------------------------------------------------- | --------------------------------------------------------------------------------------------- |
| *Failed to load*                                               | Network or session                                          | Reload; sign in again if the session is stale                                                 |
| *Query is not active. Activate it before running.*             | Custom query saved as Draft                                 | Toggle the **Active** checkbox and save                                                       |
| *SQL lint failed: Query must reference&#x20;*`$1`*&#x20;…*     | Custom query missing the tenant filter parameter            | Add `WHERE "organisationId" = $1` (or include `$1` in another join condition)                 |
| *SQL lint failed: forbidden keywords*                          | The query contains `INSERT/UPDATE/DELETE/DDL`               | Read-only `SELECT` only                                                                       |
| *Unknown table — likely off the analytics allowlist or a typo* | Query references a table outside the readable allowlist     | Restrict the query to allowlisted tables; ask the AI to rewrite if you're unsure              |
| *Unknown column / Unknown function or cast*                    | Typo in a column name or function                           | Re-check the column names; the editor's autocomplete (Ctrl-Space) lists every readable column |
| *Invalid value for type (e.g. malformed UUID)*                 | A parameter value didn't match the expected type            | Check the query parameters — UUIDs need `::uuid` casts                                        |
| *Statement timeout*                                            | Query took longer than 5 seconds                            | Add filters or aggregations to bring it under the cap                                         |
| *AI generation failed upstream* / *AI response was empty*      | The AI service was slow or returned an unexpected shape     | Try rephrasing the prompt or simplifying the request, then send again                         |
| *Request timed out* (Ask AI)                                   | The whole chat round-trip took longer than the panel allows | Refresh, simplify the prompt, or break the request into smaller turns                         |

### Frequently asked

**How real-time are the right-now tiles?**
They refresh every 30 seconds. The page header shows the last update time so you can tell at a glance.

**Can I get a custom date range?**
Yes — click **Custom** in the date range picker. Two date inputs let you pick any window.

**Can my organisation have its own SLAs?**
Yes — the gear icon next to the Right Now header opens the SLA settings. Pick a preset or type your own thresholds in minutes. The tiles re-bucket immediately.

**Why don't I see my colleague's calls under their agent profile?**
You should — the leaderboard counts both messages and calls. If a number looks zero, the agent didn't have activity in the chosen date window. Try widening the range.

**Why is there no live ticket count tile?**
The Right Now panel focuses on chat-level operations. For ticket volume use the **Tickets** tab; the *open ticket count* is on the roadmap.

**Can I share a custom query with another organisation?**
Not directly. Library templates published by Lodgestory are visible to every organisation. If you want a custom query promoted into the library, ask support.

**Can I export results from a custom query?**
Yes — every custom-query result preview and the agent leaderboard has a **CSV** download button. Output is UTF-8 with a BOM so Excel auto-detects encoding. For very large or scheduled exports, [Reports](reports.md) is the dedicated tool.

**How does the AI know about our data?**
The Ask AI assistant is briefed on the full analytics data model — every readable table, the JSON shapes of fields like the latest message blob and bot session variables, the canonical query patterns the built-in metrics use, and a list of known limitations (e.g. agent display names need to be resolved by Lodgestory after the query runs). It does not see your actual data — only the static schema and your prompt.

**What if the AI generates a wrong query?**
The assistant lands queries in **Draft** by default — you must toggle **Active** explicitly before running. If the syntax is broken, the editor's pre-flight check rejects it with a clear error before any data is read. If the logic is wrong, refine in the chat panel ("now group by channel", "exclude archived") or edit the SQL directly.

**My custom query worked yesterday but is failing today with a column error.**
Likely the underlying field structure changed. SQL queries reference fields by name; if a name was renamed elsewhere in the product, your query needs to be updated. Open the query and re-run — the error message points at the missing field.

## Related modules & next steps

* [Reports](reports.md) — raw CSV export for anything beyond the dashboard.
* [Home (Unified Inbox)](home-unified-inbox.md) — the primary data source for chat metrics.
* [Tickets](tickets.md) — ticket creation, resolution, and assignment that feed the Tickets tab.
* [Calls](calls.md) — call activity behind the Calls tab.
* [Team Members](../settings/team-members.md) — drill-down on individual agents.
* [Bot Journeys](../settings/bot-journeys.md) — sessions behind the Bots tab.
* [Campaigns](campaigns.md) — broadcast-level progress (separate from this page).

<br />