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

# Get Hotel Sources

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

Per-provider normalized-host recurrence over the period-selected runs.

For each publisher-host-capable provider (OpenAI, Perplexity, Claude), returns the
normalized hosts that recurred across this experiment's source-captured results, each
with ``n`` = distinct source-captured results the host appeared in, alongside ``M`` =
the provider's source-captured result count for the period (captured-zero included,
null-capture excluded). Hosts are normalized (lowercased, leading ``www.`` stripped)
— NOT registrable domains; subdomains are preserved.

Gemini is surfaced as a distinct ``reconstructed`` state: its captured URLs are
``vertexaisearch`` redirects with no derivable publisher host, so hosts are
reconstructed best-effort from Gemini's own source labels
(``GeoResultSource.provider_title``, i.e. its ``web.title``) — never the redirect URL —
with a real ``M`` and a per-occurrence ``unresolved_sources`` count for labels that are
not domain-shaped.

Hosts are ranked and trimmed to a single **global** top-N set (ranked by the summed
``n`` across all providers, keyed by host string), so every returned host appears for
every provider that cited it — no per-provider false-absence. ``providers`` stays
provider-major (per-provider ``M``/``state``/``hosts``); the response also carries the
global ``total_hosts`` (pre-trim distinct-host count) and the contributing ``runs``.

``limit``/``offset`` select the ``[offset, offset + limit)`` window of that global
ranking. They bound the response only: ``total_hosts`` is always the full pre-trim
distinct-host count, so it stays the pagination denominator, and an ``offset`` past the
end returns empty ``hosts`` for every provider rather than an error. Sending neither
reproduces the historic top-``_SOURCES_TOP_N`` response exactly.

## Path parameters

- `experiment_id` string, uuid, required

## Query parameters

- `period` '7d' | '14d' | '30d' | '90d'
- `limit` integer
- `offset` integer

## Response `200`

Successful Response

- SourcesResponse
  - `period` '7d' | '14d' | '30d' | '90d', required
  - `manual_snapshot` boolean
  - `providers` SourceProviderRecurrence[], required
    - `platform_id` string, uuid, required
    - `platform_name` string, required
    - `state` 'ok' | 'unavailable' | 'reconstructed', required
    - `sources_measured_results` integer, nullable
    - `total_hosts` integer
    - `hosts` SourceHostRecurrence[]
      - `host` string, required
      - `n` integer, required
    - `unresolved_sources` integer
  - `total_hosts` integer
  - `runs` RunRef[]
    - `run_id` string, uuid, required
    - `completed_at` string, date-time, nullable
  - `owned_domain` string, nullable
  - `owned_hosts` OwnedSourceHost[]
    - `host` string, required
    - `rank` integer, required
    - `n` integer, required

## Other responses

- `404` — Experiment 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)
