Analytics Overview
Search analytics in AACSearch — what's measured, where the data lives, and how to use it to drive relevance, content, and conversion improvements.
AACSearch records every search, every click, every conversion, and every operational event that touches your indexes. The data is exposed in three places — the Dashboard analytics page, the search analytics oRPC procedures, and a CSV / JSON export — so you can both diagnose specific queries and close the loop by feeding insights back into relevance tuning, content gaps, and revenue analysis.
This section is the customer-facing reference for that data. The dashboard page covers UI; this section covers concepts, schemas, and the workflows that turn telemetry into improvements.
What's measured
| Surface | What is recorded | Where it lands |
|---|---|---|
| Search | Every /api/search and /api/search/multi call with query, filters, result count, latency. | SearchUsageEvent |
| Click | Every click on a result, with position, productId, queryId. | SearchUsageEvent |
| No-result | Searches that returned 0 hits (also surface in the dashboard). | SearchUsageEvent + Zero Queries panel |
| Filter / sort | filter_used events with the filter expression. | SearchUsageEvent |
| Widget open | First impression of the widget. | SearchUsageEvent |
| Conversion | Post-search purchase / signup / custom event. | SearchUsageEvent (type=conversion) |
| AI answer | Every /api/search/ai/answer call with searchTimeMs and totalTimeMs. | SearchUsageEvent (type=ai_answer) |
| Knowledge ask | Every knowledge.ask / askStream call with token spend. | SearchUsageEvent (type=knowledge_ask) |
| Admin activity | Index created, key rotated, reindex started/finished, sync job completed, quota warning. | SearchActivityEvent |
| Rate limit | 429 rejections (debug only). | SearchRateLimitBucket |
Tenant scope: every row has organizationId. No cross-org reads, ever (Invariant 5).
Event schema (customer view)
Public event capture goes through POST /events/track (see packages/api/modules/search/events-public.ts). The accepted shape is intentionally narrow — no email, no full IP, UA capped at 256 chars — so you can plug it into any storefront safely:
{
type: "search_query" | "zero_results" | "result_click" | "widget_open"
| "filter_used" | "conversion" | "visit" | "click";
sessionId?: string;
anonymousUserId?: string;
query?: string;
productId?: string;
position?: number;
filters?: Record<string, unknown>;
sort?: string;
locale?: string;
referrer?: string;
queryId?: string; // joins clicks to the search that produced them
conversionType?: string; // "purchase", "signup", "add_to_cart", …
metadata?: Record<string, unknown>;
}Batch up to 50 events per request ({ events: [...] }) and use sendBeacon on page unload — both are first-class supported paths in the widget.
The exact names (search_query, result_click, …) are what surface in the analytics tables and what the SDK / widget emits. Keep them aligned; do not invent custom types in client code.
Where to read the data
Dashboard
Analytics dashboard — KPI tiles, time-series chart, Top Queries, Failed Queries, Activity feed. The UI is for everyone; period selector controls all tabs. Retention varies by plan (24 h on all; 30 d on paid).
oRPC procedures
For programmatic access, the protected procedures in packages/api/modules/search/router.ts:
| Procedure | What it returns |
|---|---|
search.usageSummary | Period totals: searches, clicks, CTR, p50/p95 latency. |
search.topQueries | Ranked top queries with searches, clicks, CTR, zero-results flag. |
search.analytics | Time-series and aggregated counts by event type. |
search.recentActivity | Activity feed from SearchActivityEvent. |
search.ctrAnalytics | Daily CTR trend. |
search.analyticsEvents | Raw event retrieval (paginated, filtered). |
knowledge.usageMetrics | Knowledge module token spend and query count. |
Each accepts organizationId + a period (24h, 7d, 30d) and returns Prisma-shaped rows you can render anywhere.
Export
CSV and JSON export — see Export.
The closed loop
Analytics in isolation is just a dashboard. The point is to turn each metric into an action:
| What you see | Where it points |
|---|---|
| High-volume queries with low CTR | Relevance tuning — synonyms, queryBy weights, curations. |
| Zero-result queries | No-results loop — content gap or synonym/curation rule. |
| High-volume queries with no conversion | Conversions — funnel analysis; consider AI answers or guided merchandising. |
| Spike in failed queries (4xx / 5xx) | Operations / errors — rate limit, scoped-token issue. |
| Rising no-result rate | Re-ingest cadence — see Ingest and reindex. |
| Falling CTR despite stable volume | Curation drift or synonym noise — audit Relevance panel. |
| Widget-open events without subsequent search | Widget UX — see Widget overview. |
For an e-commerce example, the typical loop is: zero-results → spot the missing brand → add a synonym → measure recovery in the same query's CTR over the next period. For SaaS / knowledge-base search, the loop is: low-CTR query → reword the article title → re-ingest → measure CTR rise.
Retention and privacy
- Retention. All event rows are retained for the plan's window — typically 90 days. Aggregated counts in
SearchActivityEventare kept longer. - PII. The public event endpoint deliberately accepts no full IP or email. UA is capped.
metadatais opaque but capped at 4 KB JSON. - GDPR / DPA. Personal-data scope for AACSearch is documented in Security & Compliance. The widget's analytics path is included in the standard DPA.
- Right-to-be-forgotten. Deletion is per
anonymousUserId— see the Data privacy doc for the redaction procedure.
Examples
E-commerce
Watch: top queries, conversion rate per query, no-result rate, brand-facet usage.
What to read together:
topQueriesfor the week +ctrAnalyticsdaily trend.analyticsEventsfiltered totype=conversionfor revenue attribution.noResultspanel + content team's brand additions to close the loop.
SaaS / knowledge-base search
Watch: zero-result rate, click-to-article rate, AI-answer refusal rate.
What to read together:
- Top zero-result queries → content gaps in the help center.
knowledge.usageMetricstoken spend + refusal-rate spikes → quality regression after a docs update.
Related pages
- Queries — popular, low-CTR, reformulations
- Conversions — search-to-click, search-to-conversion
- No-results — the recovery loop
- Relevance quality — feeding analytics back into ranking
- Export — CSV / JSON pulls, retention, BI integration
- Analytics dashboard — the in-product UI
- Widget analytics events — what the widget emits
Module Knowledge & Administration
Le module Knowledge pour les questions-réponses internes sur des documents (RAG/GraphRAG) et la section d'administration pour les administrateurs du site.
Query Analytics
Popular queries, low-CTR queries, reformulations, and how to read them to drive relevance improvements.