AI Visibility API

Export published AI Visibility metrics for a project and one page of the monitored answers behind them. Use it to report brand visibility, compare periods and inspect saved answer/citation evidence. This endpoint does not generate new AI answers or export Claims Trends.


Create with POST https://app.wheremore.com/api/v2/exports/visibility . Retrieve with GET https://app.wheremore.com/api/v2/exports/{export_id} . This guide describes default data contract 2026-09-19 . See API Access and API Keys for credentials and the shared export lifecycle.


Select the scope

Copy the public workspace ID from API Access → Your Workspaces and Markets. Supply the numeric project ID. Optionally supply config_id  to select a persona configuration within that project. Obtain these IDs from your Wheremore configuration or workspace administrator; this export API does not provide a project/persona listing endpoint.


Metrics describe the complete selected date/persona/platform/phase/depth scope. Answer pagination affects the evidence returned and its billing, not the scope of those metrics.


Request fields

Field Required Accepted value
workspace_id Yes Public ws_...  ID.
project_id Yes Positive project ID belonging to that workspace.
date_from , date_to Yes Inclusive UTC YYYY-MM-DD  dates; 1–366 days, no future end date.
config_id No Positive persona configuration ID within the project. Omit for the project scope.
platform No all  (default) or a supported provider key below.
phase No all  (default), awareness , consideration  or decision .
provider_depth No any  (default), top1  or top3 .
page No Positive answer-page number, default 1, maximum 10,000.
limit No Answers per page, 1–100; default 50.
data_contract No 2026-09-19  (default) or 2026-09-10 .
callback_url No Public HTTPS readiness callback.

Supported platform keys are chatgpt , chatgpt-web , chatgpt-adaptive , claude , claude-web , claude-adaptive , gemini , gemini-web , gemini-adaptive , perplexity , perplexity-web , perplexity-adaptive  and google-ai-mode . Search-enabled and non-search variants are distinct identifiers.


Unknown fields are rejected. The old config_name  selector is not supported; config_id  alone no longer replaces the required project_id  and dates.


Create and retrieve the export

Replace the example IDs and dates. WHEREMORE_API_KEY  must already be set securely.


curl --fail-with-body -X POST \
  "https://app.wheremore.com/api/v2/exports/visibility" \
  -H "X-API-Key: ${WHEREMORE_API_KEY}" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: visibility-report-20260919-001" \
  -d '{
    "workspace_id": "ws_your_workspace_id",
    "project_id": 123,
    "config_id": 42,
    "date_from": "2026-09-01",
    "date_to": "2026-09-18",
    "platform": "all",
    "phase": "all",
    "provider_depth": "top3",
    "page": 1,
    "limit": 50,
    "data_contract": "2026-09-19"
  }'

Save the returned export.id . POST returns 201 when ready or 202 when pending; neither charges credits or returns the report. Retrieve it using:


curl --fail-with-body \
  "https://app.wheremore.com/api/v2/exports/exp_0123456789abcdef0123456789abcdef" \
  -H "X-API-Key: ${WHEREMORE_API_KEY}"

A pending GET returns 202. A ready GET returns 200 with the frozen data . Retry the same POST with its original idempotency key; use a new key for another page or report.


Returned report

Field inside data Meaning
data_contract , workspace_id API response format and public workspace ID.
snapshot Reader/metric versions, status, updating/error indicators, pending/failed slices, coverage dates and generation information.
filters Effective project, workspace, persona, platform, phase, depth and dates.
sections kpis , shareOfVoice , customerJourney , sentiment , citationRate  and conversationVisibility .
responses Answer rows, counts, billing-unit count and page metadata.
consistency Statement that metrics and this response page were read in one consistent database snapshot.
definitions Interpretation notes for populations, missing evidence, citations and pagination.

Response filter names follow the shared reader: persona selection is reflected in config_filter ; phases can appear as phase_filter: "phase1" , "phase2"  or "phase3" , corresponding to awareness, consideration and decision. Use the public request values when making subsequent requests rather than copying the response filter object verbatim.


The six KPI entries in sections.kpis.metrics  cover Brand Visibility, Share of Voice, Top Recommendation Rate, Cited Answer Rate, Owned Website Evidence and Third-party Evidence. Preserve the returned current/comparison values, units, setup flags and comparison warnings. Different monitored populations can make a period comparison less reliable even where both periods contain observations.


This export includes those six sections; other dashboard panels, saved analysis reports and Claims inventory/verification results are outside its response.


Answer evidence

Each item in responses.answers  includes:


Field or group Meaning
observation_id , run_id , config_id , query_id Stored observation, run, persona and monitored-question identifiers.
platform_key , phase_key , observed_at Provider, stored phase and observation time.
question , answer_text , text_available Question and available full answer text. Missing text is identified explicitly.
brand_matches_selected_depth Whether an own-brand mention meets the chosen rank depth.
brands Stored brand keys/names/roles, minimum ranks and sentiment keys.
citations Citation ID, title, URL, rank and scope. An unavailable/unsupported URL can be null.
web_sources Separate web-search sources, each with title and URL.

An illustrative pagination fragment is:


{
  "total_answers": 75,
  "returned_answers": 50,
  "billable_conversations": 20,
  "pagination": {"page": 1, "limit": 50, "has_more": true}
}

These counts belong inside responses . Fifty answer rows can represent fewer than fifty conversation/persona pairs because different platforms or observations can relate to the same monitored question.


Depth, missing data and interpretation

top1  and top3  describe the rank of stored provider mentions, not the number of answers to return. Answers without a qualifying own-brand mention remain in the evaluated denominator and the evidence page; brand_matches_selected_depth  annotates the match. Missing or unprocessed answers are not evaluated zero-visibility answers.


Read snapshot.status , isUpdating , hasProjectionErrors  and coverage metadata. A ready export can contain the last available committed reporting data while processing continues. Before the first usable publication, an export can remain pending. A published selection with no answer rows can return an empty, free first page.


A citation, brand mention or recommendation does not establish truth, endorsement, a purchase or commercial impact. Answer citations and web-search sources are separate evidence. Escape all question/answer text when displaying it and handle null URLs.


Pagination and charges

If responses.pagination.has_more  is true, create a new export using the same filters and limit with page  increased by one. Give that POST a new idempotency key. A page beyond the selected answer population is rejected, except that page 1 can represent an empty selection.


Each page is a separate snapshot. Source data can change between page requests, so pages are not a frozen dataset-wide cursor and can overlap or shift. Store observation IDs to recognize repeated evidence; do not assume all pages share one publication.


The first successful GET costs 0.5 credits per distinct (config_id, query_id)  pair on that page, shown as responses.billable_conversations . In the example fragment, the charge is 10 credits. Multiple answers for one pair on the same page count once; the same pair on another export page is billable again. Full-scope metrics are not charged as additional units.


Repeat GETs of the same paid export are free and return identical data. An answer-empty export has zero billable units. Exports expire seven days after creation. The 8 MiB payload cap still applies; long answers may require a smaller limit  or narrower scope.


Troubleshooting

  • 400: check required project/dates, exact filter identifiers, page bounds and obsolete fields.
  • 403 after a successful earlier retrieval: workspace/project access may have changed, or the selected persona may have moved or been removed. Saved data does not override current permissions.
  • 503: a required published reader or permission service may be unavailable. Retain the request ID for support.
  • Brand-setup flags: configure the project's own brands and, where required, brand websites before interpreting those metrics.
  • Page contains answers without your brand: expected; they remain part of the evaluated denominator.
  • 413: reduce limit , dates, platform or persona scope, then create a new export.
  • Data does not change on GET: the export is immutable; create another report for a later publication.

Use API Access and API Keys for key errors, insufficient credits, callbacks and retention.

Did this answer your question? Thanks for the feedback There was a problem submitting your feedback. Please try again later.