---
title: "Get Overview"
method: GET
path: "/api/v1/geo/experiments/{experiment_id}/overview"
tags: ["geo-monitoring", "geo-dashboard"]
---

# Get Overview

`GET /api/v1/geo/experiments/{experiment_id}/overview`

AI Presence Overview: the Report Card for one experiment.

When ``scan_id`` is provided the header (AI Visibility, stability, average
position, evidence, source ecosystem) is that scan only — the same
``load_dashboard_scan_selection`` resolver the Prompts / Changes tabs use,
including ``completed_with_errors``. Period is ignored for the evidence
population so a historical ``?scan=`` cannot keep showing the live rollup.

When omitted, headline AI Visibility Rate is the P2-cell rate over the
selected period, computed from ALL eligible data-bearing runs (scheduled AND
manual) whose canonical local day falls in the period, grouped by
tenant-local day and pooled within each ``(cell, local day)``: the
unweighted mean over measured prompt×provider cells of each cell's
unweighted mean daily mention rate. Every measured cell is weighted
equally regardless of usable samples or days measured; evidence depth
surfaces only in Measurement Confidence, and multiple runs in one local
day count as one measured day. Cells come from persisted results, so a
prompt deactivated mid-period still counts for the days it ran
(``is_active`` never filters the rate). Failures/unavailability never
become non-mentions. Scheduled-run health and the latest attempts still
come from the canonical one-run-per-day ``load_period_run_selection``
(a distinct scheduler-reliability signal, not the metric's evidence
population). Computed on read; nothing is persisted.

## Path parameters

- `experiment_id` string, uuid, required

## Query parameters

- `period` '7d' | '14d' | '30d' | '90d'
- `scan_id` string, uuid, nullable

## Response `200`

Successful Response

- OverviewResponse — AI Presence Overview: the period-scoped Report Card headline + diagnoses. ``ai_visibility_rate`` is the P2-cell rate over the selected period: the unweighted mean over measured prompt×provider cells of each cell's unweighted mean daily mention rate. Every measured cell has equal product weight regardless of usable samples or days measured; evidence depth surfaces only in ``measurement_confidence``. Reduces to the single-scan rate when the period holds one run. Failures/unavailability never become non-mentions.
  - `period` '7d' | '14d' | '30d' | '90d', required
  - `manual_snapshot` boolean
  - `ai_visibility_rate` number, nullable, required
  - `avg_position_when_mentioned` number, nullable, required
  - `mentioned_usable_responses` integer, required
  - `usable_responses` integer, required
  - `eligible_cells` integer, required
  - `methodology_version` string, required
  - `visibility_diagnosis` VisibilityDiagnosis, required — Where the property's remaining measured visibility gap is concentrated. ``has_measured_gap`` is False at 100% measured visibility (total deficit 0); the lists are then empty and the UI renders a no-gap state — no gap shares are computed (no division by a zero total).
    - `has_measured_gap` boolean, required
    - `provider_gap` ProviderGapShare[]
      - `platform_id` string, uuid, required
      - `platform_name` string, required
      - `gap_share` number, required
      - `measured_cells` integer, required
      - `planned_cells` integer, required
    - `top_deficit_cells` DeficitCell[]
      - `prompt_id` string, uuid, required
      - `prompt_text` string, required
      - `platform_id` string, uuid, required
      - `platform_name` string, required
      - `deficit` number, required
      - `days_measured` integer, required
  - `stability_diagnosis` StabilityDiagnosis, required — Recommendation Stability: how consistently repeated searches return the same result. ``stability_rate`` is the majority-agreement rate in ``[0.5, 1.0]`` (rendered as a percentage), the unweighted mean over Stability-eligible cells of each cell's unweighted mean daily ``max(p, 1 - p)`` — the same equal-cell hierarchy as ``ai_visibility_rate``, never a 0–100 score. ``None`` when no cell had ≥2 usable repeats on any measurement (insufficient repeated evidence — distinct from 100%, which needs eligible evidence with no variation). The ``*_cells`` / ``*_cell_measurements`` counts are factual support only (they never weight the score): ``eligible`` requires ≥2 usable repeats, ``measured`` requires ≥1. ``eligible_cell_measurements`` vs ``measured_cell_measurements`` exposes when a Stability value rests on few repeated measurements even though many cells were Visibility-measured.
    - `unstable_cell_count` integer, required
    - `unstable_cells` UnstableCell[]
      - `prompt_id` string, uuid, required
      - `prompt_text` string, required
      - `platform_id` string, uuid, required
      - `platform_name` string, required
      - `unstable_days` integer, required
      - `measured_days` integer, required
    - `stability_rate` number, nullable
    - `eligible_cells` integer
    - `measured_cells` integer
    - `eligible_cell_measurements` integer
    - `measured_cell_measurements` integer
  - `measurement_confidence` PeriodMeasurementConfidence, required — Period-level confidence: technical coverage + per-cell temporal support. Separate from model-output variability (which lives in the Stability Diagnosis): high variability is not low measurement quality.
    - `coverage` CompetitorReportCoverage[]
      - `platform_id` string, uuid, required
      - `platform_name` string, required
      - `planned` integer, required
      - `succeeded` integer, required
      - `failed` integer, required
    - `period_health` PeriodHealthRead, required
      - `completed_days` integer, required
      - `partial_days` integer, required
      - `failed_days` integer, required
      - `in_flight_days` integer, required
      - `observed_days` integer, required
    - `latest_scheduled_attempt` RunAttemptRead
      - `run_id` string, uuid, required
      - `status` string, required
      - `run_type` 'scheduled' | 'manual', required
      - `created_at` string, date-time, required
    - `latest_manual_attempt` RunAttemptRead
      - `run_id` string, uuid, required
      - `status` string, required
      - `run_type` 'scheduled' | 'manual', required
      - `created_at` string, date-time, required
    - `low_support_cells` CellSupport[]
      - `prompt_id` string, uuid, required
      - `prompt_text` string, required
      - `platform_id` string, uuid, required
      - `platform_name` string, required
      - `measured_days` integer, required
      - `planned_days` integer, required
  - `source_position` SourcePosition, required — The URL-provider source environment observed around the property this period. ``concentration_topk_share`` is the top hosts' share of **captured source appearances** (Σ distinct-result-per-host, a result×host quantity) — never a measure of "what AI trusts". ``cross_provider_host_count`` counts hosts recurring across ≥2 assistants over the **full** eligible set (not just the shown top-k). ``hosts`` is a single ranked evidence list (top-k, presentation only).
    - `source_state` 'unavailable' | 'no_comparable_hosts' | 'available', required
    - `distinct_hosts` integer, required
    - `concentration_topk_share` number, required
    - `cross_provider_host_count` integer, required
    - `hosts` SourceHost[]
      - `host` string, required
      - `distinct_result_count` integer, required
      - `provider_count` integer, required
  - `destination_benchmark` DestinationBenchmark, required — How the property's observed source environment relates to the domains LLMs cite for its destination (Source Tracker). Association only: Source Tracker observes which domains are **cited** for the destination — never that they are "trusted", and absence is **not** proof that gaining presence would improve AI visibility. Matching is **exact normalized host** (subdomains stay distinct); Gemini is excluded (reconstructed hosts aren't join-safe). ``snapshot_week`` is always present when ``available`` so an older weekly benchmark is never shown as contemporaneous with the whole period.
    - `benchmark_state` 'available' | 'unmapped' | 'no_snapshot' | 'no_property_evidence', required
    - `region_display_name` string, nullable
    - `snapshot_week` string, date, nullable
    - `aligned_count` integer
    - `gap_count` integer
    - `top_aligned` BenchmarkDomain[]
      - `domain` string, required
      - `citation_index` integer, required
      - `evidence_count` integer, required
      - `authority_tier` string, required
      - `playbook_note` string, required
      - `cited_by` EngineCitation[]
        - `platform_name` 'chatgpt' | 'perplexity' | 'gemini' | 'claude', required
        - `citation_index` integer, required
    - `top_gap` BenchmarkDomain[]
      - `domain` string, required
      - `citation_index` integer, required
      - `evidence_count` integer, required
      - `authority_tier` string, required
      - `playbook_note` string, required
      - `cited_by` EngineCitation[]
        - `platform_name` 'chatgpt' | 'perplexity' | 'gemini' | 'claude', required
        - `citation_index` integer, required
    - `source_type_coverage` BenchmarkTierCoverage[]
      - `authority_tier` string, required
      - `aligned` integer, required
      - `total` integer, required
  - `source_ecosystem_by_provider` ProviderSourceEcosystem[]
    - `platform_name` string, required
    - `source_position` SourcePosition, required — The URL-provider source environment observed around the property this period. ``concentration_topk_share`` is the top hosts' share of **captured source appearances** (Σ distinct-result-per-host, a result×host quantity) — never a measure of "what AI trusts". ``cross_provider_host_count`` counts hosts recurring across ≥2 assistants over the **full** eligible set (not just the shown top-k). ``hosts`` is a single ranked evidence list (top-k, presentation only).
      - `source_state` 'unavailable' | 'no_comparable_hosts' | 'available', required
      - `distinct_hosts` integer, required
      - `concentration_topk_share` number, required
      - `cross_provider_host_count` integer, required
      - `hosts` SourceHost[]
        - `host` string, required
        - `distinct_result_count` integer, required
        - `provider_count` integer, required
    - `destination_benchmark` DestinationBenchmark, required — How the property's observed source environment relates to the domains LLMs cite for its destination (Source Tracker). Association only: Source Tracker observes which domains are **cited** for the destination — never that they are "trusted", and absence is **not** proof that gaining presence would improve AI visibility. Matching is **exact normalized host** (subdomains stay distinct); Gemini is excluded (reconstructed hosts aren't join-safe). ``snapshot_week`` is always present when ``available`` so an older weekly benchmark is never shown as contemporaneous with the whole period.
      - `benchmark_state` 'available' | 'unmapped' | 'no_snapshot' | 'no_property_evidence', required
      - `region_display_name` string, nullable
      - `snapshot_week` string, date, nullable
      - `aligned_count` integer
      - `gap_count` integer
      - `top_aligned` BenchmarkDomain[]
        - `domain` string, required
        - `citation_index` integer, required
        - `evidence_count` integer, required
        - `authority_tier` string, required
        - `playbook_note` string, required
        - `cited_by` EngineCitation[]
          - `platform_name` 'chatgpt' | 'perplexity' | 'gemini' | 'claude', required
          - `citation_index` integer, required
      - `top_gap` BenchmarkDomain[]
        - `domain` string, required
        - `citation_index` integer, required
        - `evidence_count` integer, required
        - `authority_tier` string, required
        - `playbook_note` string, required
        - `cited_by` EngineCitation[]
          - `platform_name` 'chatgpt' | 'perplexity' | 'gemini' | 'claude', required
          - `citation_index` integer, required
      - `source_type_coverage` BenchmarkTierCoverage[]
        - `authority_tier` string, required
        - `aligned` integer, required
        - `total` integer, required
  - `owned_domain_sources` OwnedDomainSources — How much of the captured source activity pointed at the hotel's own domain. Grain is the **source occurrence** (one ``GeoResultSource`` row), NOT the result and NOT exclusively the literal citation: these rows span ``answer_citation``, ``search_result``, ``grounding_source`` and ``unknown`` evidence types, so one response referencing the hotel's site three times contributes three. This is deliberately a different grain from the Sources tab's ``n``/``M``, which are distinct-result counts. Scoped to the **Sources** run population for the selected period (see ``_resolve_sources_run_ids``) so the numbers reconcile with the Sources tab rather than with the surrounding Overview metrics. Two distinct empty states, never collapsed: ``owned_domain is None`` means the property has no ``website_url`` configured; a real ``owned_domain`` with zero counts means the hotel IS configured and the selected period simply produced no source-captured runs.
    - `owned_domain` string, nullable
    - `owned_source_occurrences` integer
    - `total_source_occurrences` integer
    - `owned_source_occurrences_without_url` integer
    - `unattributable_source_occurrences` integer
    - `runs_measured` integer
    - `urls` OwnedDomainSourceUrl[]
      - `url` string, required
      - `source_occurrences` integer, required

## Other responses

- `404` — Scan not found
- `422` — Validation Error

---

[API](https://skmtc.dev/getanana/apis/cleon-api.md) · [All operations](https://skmtc.dev/getanana/apis/cleon-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/getanana/cleon-api/revisions/c0f54348e251/schema)
