Read Search Analytics — top queries, zero-result, click-through
Every in-app search your team runs — the?q= filter on messages, contacts, calls, campaigns, and the inbox, plus the global command-palette search — is recorded per tenant against a normalized form with personal data masked. The Search Analytics dashboard (console route /insights/search-analytics) reads those rows back as four panels so you can see what your team types most, which queries come back empty, how often someone clicks a result, and which inputs the search grammar rejects.
This guide is the narrative counterpart of the Search Analytics API reference — use the console first, and reach for the API when you need export or integration.
What Search Analytics measures
Each completed search writes one analytics row: the normalized query, the surface it ran against (messages, contacts, calls, campaigns, inbox, or the global search), the result count, and whether the query parsed. Click attribution ships separately viaPOST /api/v1/search-analytics/click — the dashboard fires that call the moment a user opens a result, stamping the click back to the search that produced the list. The call is idempotent and silent on unknown ids, so frontend clients can fire-and-forget.
Four read aggregations sit on top of those rows:
All four GET endpoints share the same range filter (
from, to, surface, limit), so a dashboard can keep one filter state across panels. The lookback is capped at 90 days; a deeper from is silently pinned to 90 days before to. Searches run under support impersonation are excluded from a customer’s own numbers by design. See the API reference for the full shape of every panel.
Reading the dashboard
Open/insights/search-analytics in the console. A window selector (24h, 7d, 30d, 90d — plus a custom date range) and a per-surface selector sit at the top of the page; the same pair applies to every panel below it. Read the selectors before interpreting any number, because a panel that spans 24 hours looks nothing like the same query over 90 days.
The four tabs — Top queries, Zero-result queries, Click-through, and Parse failures — each answer a different question, and they are designed to be read together:
- Top queries by volume is the ground truth for what your team is actually looking for. If a surface you rely on (the messages hub, say) top-ranks on queries none of your dashboards surface, that is a coverage signal: the quick filters or saved views need to catch up to real behaviour.
- Zero-result is the most actionable panel. Every row is a query your team expected to match something and did not. Read it as a binary: either the data genuinely does not exist (nobody ever sent that campaign, so nothing is wrong) or the index is missing terms that should match (and the team keeps paying a search tax every day).
- Click-through and zero-result are the relationship to read together. A query with a high zero-result count and a low CTR is the classic “the search index misses common terms” symptom — people type something plausible, get nothing, and give up. A query with low zero-result count and low CTR is a ranking or snippet problem, not an index problem — the results exist, but the snippet does not earn the click.
- Parse failures is the lexicon and grammar signal. Every row is an input the search syntax rejected before it ever reached the index. A cluster of parse failures on phrases such as
rma return labelorref: 1234tells you the free-text-to-field mapping needs work — the team has settled on a convention (a return-merchandise-authorization code, an RMA dash format) that the grammar does not yet accept. This is the endpoint the operator points at when deciding whether to extend the keyword lexicon, add an alias, or fix the suggested-query examples in the search box.
Operator playbook — working a zero-result spike
Worked example: a support director notices a spike in zero-resultrma return label queries on the 30d window. The operator playbook is the same three-step loop every time — diagnose the mechanism (parse failure, index miss, or genuinely missing data), remediate the lexicon or the grammar, then confirm recovery in click-through across two windows.
Step 1 — diagnose. Open /insights/search-analytics, set the window to 30d, and scan the Zero-result panel for the phrase. If rma return label appears with a high count, check the Parse failures panel in the same window. Two outcomes are common:
- The phrase also shows up in Parse failures (with a representative raw sample like
rma return labelorrma:RMA-1234), meaning the search grammar rejected the input before it ever reached the index. The gap is in the grammar — the field prefix you need is not one the grammar recognizes, or the dash and slash characters in the convention are unsupported. Personal data is masked in the sample, so the row aggregates safely across customers. - The phrase does not appear in parse failures — the query parsed fine, and the index genuinely did not match it. That narrows the fix to the index and the keyword lexicon that maps raw terms to fields, rather than the syntax itself.
?q= DSL consults (the same DSL the messages hub search box uses; see Search message history for the full field reference). For the rma return label convention, the remediation is one of:
- Register
rmaas an accepted field alias (alongside the surface it should search — typically the messages surface for a support note, or the contact surface for a return-owner lookup), sorma:RMA-1234parses as a fielded clause. - Add
rmaandrma return labelas aliases for the existing return-reference field, so a free-text search mentioning the phrase resolves to the right indexed column rather than no column at all. - If the phrase parses but keeps returning zero results, the lexicon is fine and the remediation is indexing the return-reference column on the surface the search hits (a conversation or message text field) rather than changing the grammar again.
rma), because that is where the operator can close the gap without a platform change on their side beyond the tenant-level alias configuration.
Step 3 — confirm recovery in click-through across two windows. Remediation without confirmation is guessing. After the alias change ships, run the confirmation loop in two windows to prove the fix:
- Reopen the Click-through panel on the same 30d window and locate
rma return label. The CTR should now rise toward the baseline of other fielded searches on that surface. On the pre-fix window, the query sat near zero CTR because the runs returned nothing; post-fix, the same inputs produce results and clicks. - Switch to the shorter 7d window to isolate the new traffic. The post-fix 7d window is the rolling confirmation: high CTR here, paired with a dropping zero-result count, proves the remediation is behaving. If the zero-result count stays flat on the new window even after the alias shipped, the alias did not register — recheck the operator-side change, or the index needs the new column indexed (Step 2, option three).
Using the API directly
Most operators read the dashboard; reach for the API when you need the numbers off-console — a weekly CSV, a Slack alert on zero-result spikes, or a merge into your own BI layer. The four read endpoints take the same query parameters (from, to, surface, limit) and return a standard envelope with data.rows plus the resolved range. All roles that can log into the dashboard (owner, admin, developer, viewer) can read the analytics over the API — the analytics read surface inherits the same read posture as the dashboard does per role. Validation failures return 422 VALIDATION_ERROR; see Error codes.
Top queries.
surface to compare engagement across panels.
query_text_sample shows one representative raw input, with personal data (emails, phones, tokens) masked before it is returned.
recorded: false indicates the analytics-row id did not match a search in your tenant or it aged out of retention — the endpoint reports this as 200 rather than 404 so clients can stay fire-and-forget without ever confirming an id exists in another tenant.
See also
- Search Analytics API reference — full endpoint shapes for the four read aggregations plus click attribution
- Insights dashboards guide — sibling operator walkthrough for the broader Insights console surfaces
- Search message history — the fielded DSL every per-surface search uses
- Error codes —
VALIDATION_ERRORand the standard error envelope