A brand-visibility report does not need to become a full SEO platform. A fixed query list, a set of owned domains, and a few transparent measurements can answer a practical question: where does the brand appear in the search landscape customers are likely to encounter?
The report can be generated from ordinary Google result blocks and analyzed locally.
Define the report's scope
Start by deciding what “visible” means. A useful lightweight report might cover four query groups:
- Navigational: the brand name and common variants
- Problem-aware: questions describing the problem the product addresses
- Category: non-branded names for the product category
- Evaluation: pricing, reviews, alternatives, or implementation questions
Keep each query assigned to one group and freeze the list before collection. A report built only from queries where the brand already performs well is advertising copy, not measurement.
Create an ownership list
List domains the brand controls:
const ownedDomains = new Set([
"example.com",
"docs.example.com",
"status.example.com",
]);
Exact hostnames are safer than substring matching. notexample.com should not count as an owned result for example.com.
function isOwnedUrl(rawUrl, ownedDomains) {
const hostname = new URL(rawUrl).hostname.toLowerCase();
return ownedDomains.has(hostname);
}
If all subdomains should count automatically, implement that as a separate explicit rule.
Preserve nested result blocks
A brand can appear in a parent result, sitelink, or another nested destination. Walk the complete tree while keeping each item's path:
function* walkResults(results = [], parentPath = []) {
for (let index = 0; index < results.length; index += 1) {
const result = results[index];
const path = [...parentPath, index];
yield { result, path };
yield* walkResults(result.children ?? [], path);
}
}
The top-level position and child path are not necessarily organic rank. Label them according to what they actually represent.
Calculate a small set of useful metrics
Owned-domain query coverage
The percentage of valid queries containing at least one owned destination:
owned coverage = queries with an owned URL / valid queries
Calculate this separately for every query group. High navigational coverage is expected; category coverage usually says more about discovery beyond existing brand awareness.
First owned visible position
Record the first declared result position containing an owned URL. Report the median across queries where the brand appears, together with the number of missing queries.
Unique owned pages
Count the normalized owned URLs found across the corpus. This shows whether visibility is concentrated on one homepage or distributed across useful documentation and landing pages.
Third-party mention coverage
Search-result text can reveal pages that mention the brand without using an owned destination:
function mentionsBrand(result, brandPattern) {
return brandPattern.test(result.text ?? "");
}
const brandPattern = /\bExample Brand\b/i;
Treat this as a discovery flag, not a sentiment score. Search text can be abbreviated and does not contain the full page context.
Source diversity
Count the independent registrable domains appearing alongside brand mentions. Ten pages from one publication are not ten independent sources.
Produce query-level rows first
The aggregate report should be reproducible from rows such as:
{
"queryId": "category-004",
"queryGroup": "category",
"collectedAt": "2026-08-26T15:00:00Z",
"ownedUrlPresent": true,
"firstOwnedPosition": 4,
"ownedUrls": ["https://example.com/product"],
"mentioningDomains": ["industry-publication.example"]
}
From those rows, produce a summary:
| Query group | Queries | Owned coverage | Median first position | Third-party mention coverage |
|---|---|---|---|---|
| Navigational | 5 | 100% | 1 | 60% |
| Problem-aware | 12 | 33% | 6 | 17% |
| Category | 10 | 20% | 7 | 10% |
Always show the denominator. “Coverage increased to 50%” means little if the group contains only two queries.
Compare snapshots carefully
When repeating the report:
- Keep the query corpus and locale fixed
- Use the same result depth
- Keep the URL-normalization version
- Separate valid no-presence results from failed requests
- Retain the exact collection time
- Confirm large changes in a second snapshot before escalating them
If the corpus changes, report the old and new versions separately or recalculate historical results using only their shared queries.
What the report does not measure
Search visibility alone does not prove:
- Click-through rate
- Product consideration
- Conversion or sales
- Positive sentiment
- Customer satisfaction
Those require different data. The search report is a compact measure of where owned pages and third-party references appear for a declared set of queries.
That limited scope is what keeps it useful. It can be inspected, repeated, and explained without pretending to model the entire customer journey.
Reserp can provide the result blocks, visible text, and URLs for each query while the reporting logic remains in your application. See the Google Search API documentation for the request format.