SurfacedBySurfacedBy Docs
DocumentationAPIReference

Analytics

Read a domain's analytics, cited sources, trend series, and scored opportunities.

Ask an AI:Open in ChatGPTOpen in Claude

These four read-only endpoints return a domain's measurement results. They are available on Professional and Agency. Each one reads a different slice, so they do not all describe the same period:

EndpointWhat it returnsPeriod
analyticsThe full analytics object the dashboard is built from: scores, platform results, competitors, trends, and recommendations.Current standing as of the latest check, or as of an earlier check when you pass scan_id.
citationsThe sources AI platforms cited in their answers, with Brand Coverage, source types, per-platform totals, and sources gained or lost.Every AI answer from Daily Checks and Full Checks in the last 7 days, all countries.
diffTrend series for Visibility Score, AI Mentions, Average position, and Brand Coverage, plus markers where the measurement changed.Up to 60 of the most recent checks.
opportunitiesScored opportunities, highest opportunity_score first, paginated.Every opportunity not dismissed in the dashboard, across checks.

analytics

The response is one object under data. Pass scan_id (an id from the scans endpoints) to read the analytics as of that check instead of the latest one.

The object carries only these top-level fields. A field missing from the list below is never returned, and a field in the list can be absent when there is no data for it yet.

FieldWhat it holds
domain_id, domain_nameThe tracked domain.
scan_id, last_scan_atThe check the analytics are read from, and when it finished.
country_filterThe country the analytics are filtered to, or all.
visibility_score, visibility_components, score_breakdownThe Visibility Score (0 to 100) and the parts it is built from.
market_positionMarket Position among your competitors (1 is first).
ai_mentionsAI Mentions: answers that cite or name your brand.
ai_search_volume_monthlyNull. Prompt estimates overlap and cannot establish a site-wide total.
overviewThe headline figures the dashboard's Overview shows.
platform_resultsResults per AI platform.
competitors, competitor_source_typesYour competitors' standing, and the kinds of sources that cite them.
recommendationsRecommended actions.
sentimentHow AI answers describe your brand.
visibility_trend, mentions_trend, position_trend, coverage_trendTrend series for Visibility Score, AI Mentions, average position, and Brand Coverage.
theme_sentiment_trend, themes_refreshed_atSentiment over time per Brand Theme, and when your Brand Themes were last refreshed.
version_boundariesMarkers where the measurement changed (see below).

version_boundaries is a list. Each entry has kind, first_scan_at (the first check measured the new way), and label (a short description you can show on a chart). kind is scoring_update when the way scores are computed changed, or prompt_set when the set of tracked prompts changed between Full Checks. Values on either side of a boundary are not directly comparable.

sentiment.measurement_state describes whether sentiment was measured. measured preserves numeric zero and neutral results. Missing results have null scores and labels: missing means no valid result, and unavailable means collection is unavailable for the plan or feature. Daily Checks capture answers without scoring tone. responses_analyzed counts scored answers mentioning the brand; responses_total counts all answers in the scoped result and responses_unscored counts the rest. Sentiment averages and percentages exclude unscored answers. Each by_platform entry also includes measurement_state and a scored count.

Aggregate recommendation strength, tone counts and common attributes use that same scored, brand-present population. Each dimension includes only valid recorded values within that population. Individual answer evidence can retain a valid recommendation strength, tone, attribute, factual flag or quote even when its polarity score is unavailable; those independent fields do not make the answer part of the scored aggregate.

citations

data is an object. The main fields are total_responses (AI answers in the window), brand_coverage_pct (the share of those answers that mention you), total_unique_sources, sources_with_user_included, sources_with_user_missing, sources (one row per cited source domain), per_platform, source_type_distribution, new_sources_count, lost_sources, and platforms_measured. Counts are totals over every answer in the window, not only the latest check.

diff

data is a list with a single object holding exactly visibility_trend, mentions_trend, position_trend, coverage_trend, and version_boundaries, with the same shapes as the fields of the same names on analytics. A series with no data is an empty list. It is not paginated.

opportunities

Each row carries exactly these fields: id, domain_id, the scan_id that produced it, the prompt, country_iso_2, language_code, ai_search_volume, ai_search_volume_state, opportunity_score, priority, action_title, target_url, action_type, change, whether you were cited (user_cited) and at what position (user_position), competitors_count, sources_count, answer_preview, and created_at. Dismissing an opportunity is done in the dashboard, and a dismissed opportunity is not returned.

Only findings that name a concrete change are opportunities. A tracked prompt whose answers do not yet support a change is not returned here; it stays on the prompts and responses lists.

action_title names the recommended move. action_type is the move's kind (content_create, content_update, technical_access, source_positioning, brand_accuracy, and the other action types the dashboard labels). It is null only for advice drawn from the AI answers alone that cannot yet say whether to create a page or improve one. target_url is the page of yours the move applies to, or null for a new page or no page.

One change can answer several tracked prompts: questions a single page answers, or questions asked in nearly the same words. Every opportunity it covers carries the same change.id; the one with change.lead true names the move and counts the related prompts in its action_title, the others name the same move for their own prompt, and change.prompts counts the prompts the change answers. Group by change.id to list each move once. change is null when an opportunity has no content move.

ai_search_volume is a statistical monthly demand estimate for the exact prompt, country and recorded language, derived from search-question data. It does not count observed assistant usage, website visits or conversions. A numeric zero is available only when ai_search_volume_state is estimated. Other states return null: no_estimate for a successful lookup with no estimate, pending before lookup, failed when the lookup failed, unsupported for an unsupported prompt or scope, and legacy_unknown when historical provenance is unavailable.

GET
/domains/{domain_id}/analytics
/domains/{domain_id}/analytics

Path Parameters

domain_id
Required
Domain Id

Query Parameters

scan_idScan Id

Id of an earlier check of this domain (from the scans endpoints). Returns the analytics as of that check instead of the latest one.

Header Parameters

X-API-KeyX-Api-Key

curl -X GET "https://api.surfacedby.com/api/v1/ext/domains/string/analytics?scan_id=string" \
  -H "X-API-Key: string"

Successful Response

null

GET
/domains/{domain_id}/citations
/domains/{domain_id}/citations

Path Parameters

domain_id
Required
Domain Id

Header Parameters

X-API-KeyX-Api-Key

curl -X GET "https://api.surfacedby.com/api/v1/ext/domains/string/citations" \
  -H "X-API-Key: string"

Successful Response

null

GET
/domains/{domain_id}/diff
/domains/{domain_id}/diff

Path Parameters

domain_id
Required
Domain Id

Header Parameters

X-API-KeyX-Api-Key

curl -X GET "https://api.surfacedby.com/api/v1/ext/domains/string/diff" \
  -H "X-API-Key: string"

Successful Response

null

GET
/domains/{domain_id}/opportunities
/domains/{domain_id}/opportunities

Path Parameters

domain_id
Required
Domain Id

Query Parameters

cursorCursor

Header Parameters

X-API-KeyX-Api-Key

curl -X GET "https://api.surfacedby.com/api/v1/ext/domains/string/opportunities?cursor=string" \
  -H "X-API-Key: string"

Successful Response

null

On this page