# AI Brand Visibility Tracker - Google AI Overview and AI Mode (`s-r/ai-brand-visibility`) Actor

Ask the questions your buyers ask and find out whether Google's AI answers name your brand, how early, whether they link you, and which competitors get named instead. One row per question per AI surface.

- **URL**: https://apify.com/s-r/ai-brand-visibility.md
- **Developed by:** [SR](https://apify.com/s-r) (community)
- **Categories:** SEO tools, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## AI Brand Visibility Tracker

Ask the questions your buyers actually ask, and find out whether Google's AI
answers name your brand, how early, whether they link you, and which
competitors get named instead.

Search used to end with ten blue links and a ranking you could measure. An AI
answer ends with a recommendation, and either you are in it or you are not.
This measures that.

### Two surfaces, not one

Google has two AI answers and they are different products. The **AI Overview**
is the summary above the blue links: short, opinionated, three or four sources.
**AI Mode** is the conversational tab: long, structured, often a breakdown by
use case with different brands in it.

They disagree often enough that averaging them would hide the useful part, so
every question is asked on both and each gets its own row. A brand can lead the
Overview and be absent from AI Mode for the same question, and that is a
finding, not noise.

Neither needs an API key from you.

### What a row tells you

- `brand_mentioned` and `brand_mentions` — is the brand named, and how often
- `brand_rank` — **1 means the answer names you before any other brand.** This
  is the number to watch week to week
- `brand_first_position` — where in the answer, as a character offset, so
  earlier is lower
- `brand_context` — the sentence you appear in, which is where you find out
  whether being named was good news
- `brand_cited` and `brand_citation_urls` — whether the answer linked your site

`brand_mentioned` and `brand_cited` are deliberately separate. An answer can
name you without linking you, and can link your domain without naming you. One
is reputation, the other is traffic, and a single "visible" flag would hide
which of the two is missing.

- `competitors_mentioned` — who was named instead, each with the domain it
  cited and where it appears
- `competitor_count` and `share_of_voice` — your slice of every brand mention
  in that one answer

### How competitors are found

Give a list under **Known competitors** and they are matched by name. Leave it
empty and the run works them out: it takes the brand name out of every domain
the answer cited and keeps the ones the answer also names in its text.

That is grounded on the citations on purpose. Pulling capitalised words out of
prose finds "The Best", "However" and every product category at least as often
as it finds a rival. A cited domain that also gets named is a real competitor
by both tests.

Each competitor carries the `domain` it came from, because a token can read as
an ordinary word: `scrape` is the name behind `scrape.do`, and only the domain
tells you which it is.

### Questions with no answer are not failures

Google decides per request whether to offer an AI Overview at all. A question
it declines comes back with `answered: false`, is **not billed**, and is
counted separately in the scorecard as `unanswered`.

This matters more than it sounds. Folding a refusal to answer into your
visibility rate would mix two different problems: "the AI does not recommend
us" and "the AI does not answer this question at all" have different fixes, and
only one of them is about your brand.

### The scorecard

`summary` in the key-value store is the run's own answer:

- `visibilityRate` per surface — answers naming you, over answers given
- `citationRate` per surface — answers linking you
- `averageRank` — where you land among the brands that do get named
- `topCompetitors` — who shows up most across the whole prompt set
- `promptsWithoutBrand` — **the actionable list.** The questions that got a
  real answer with no mention of you

Rates are over answered checks only, for the reason above.

### Writing good prompts

This is the input that decides everything else. A question nobody asks tells
you nothing, however good the measurement is.

Write them the way a buyer types them, not the way you describe yourself.
"best ecommerce price monitoring tool" is a question someone asks; "enterprise
retail pricing intelligence platform" is a phrase from your own homepage.
Include the comparison questions ("X vs Y"), the ones with a qualifier ("for
small business", "free"), and the ones where you expect to lose. The last group
is where the value is.

### Country and language

AI answers are regional. The same question names different brands in the US
than in the Netherlands, so **Country** and **Language** are separate inputs
and both are carried on every row. If you sell in several markets, run them
separately and keep the rows apart.

### Errors

| Code | Meaning |
|---|---|
| `bad_input` | No brand name or no prompts |
| `engine_error` | One surface could not be read for one question |

An `engine_error` on one row does not affect the others; every question and
surface is measured independently.

### Related actors

`google-ai-overview-scraper` and `google-ai-mode-scraper` return the raw
answers without the brand measurement, if you want to do your own analysis.
For the blue links behind them, see the SERP actors.

# Actor input Schema

## `brand` (type: `string`):

The brand to look for in the answers, written the way people write it.

## `brandDomain` (type: `string`):

Your website, without https. Used to tell being named apart from being linked, which are different problems.

## `brandAliases` (type: `array`):

Any other way the brand gets written. A name split across two words is already handled, so this is for genuinely different names such as a former one.

## `prompts` (type: `array`):

One buyer question per line, written the way someone would actually type it. These decide everything: a question nobody asks tells you nothing.

## `competitors` (type: `array`):

Rivals to look for by name. Leave empty and the run reports whoever the answers cite and name instead of you.

## `engines` (type: `array`):

Which of Google's AI surfaces to ask. They are different products and answer differently, so both is the default.

## `country` (type: `string`):

Two-letter country code. AI answers are regional, so the same question names different brands per market.

## `language` (type: `string`):

Two-letter language code the answers come back in.

## `concurrency` (type: `integer`):

How many prompt-and-surface checks to run at once.

## `retries` (type: `integer`):

How often to re-ask before accepting that a surface has no answer for a question. Google decides that per request, so a couple of retries is normal.

## Actor input object example

```json
{
  "brand": "Notion",
  "brandDomain": "notion.so",
  "brandAliases": [
    "Prisync.com"
  ],
  "prompts": [
    "best crm for small business"
  ],
  "competitors": [
    "Price2Spy",
    "Dealavo"
  ],
  "engines": [
    "google_ai_overview",
    "google_ai_mode"
  ],
  "country": "nl",
  "language": "nl",
  "concurrency": 3,
  "retries": 3
}
```

# Actor output Schema

## `checks` (type: `string`):

One row per question per AI surface.

## `summary` (type: `string`):

Visibility and citation rate per surface, the competitors named most often, and the questions you are absent from.

## `errors` (type: `string`):

Checks that could not be completed.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "brand": "Prisync",
    "brandDomain": "prisync.com",
    "brandAliases": [],
    "prompts": [
        "best ecommerce price monitoring tool",
        "competitor price tracking software for retailers"
    ],
    "competitors": [],
    "engines": [
        "google_ai_overview",
        "google_ai_mode"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("s-r/ai-brand-visibility").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "brand": "Prisync",
    "brandDomain": "prisync.com",
    "brandAliases": [],
    "prompts": [
        "best ecommerce price monitoring tool",
        "competitor price tracking software for retailers",
    ],
    "competitors": [],
    "engines": [
        "google_ai_overview",
        "google_ai_mode",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("s-r/ai-brand-visibility").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "brand": "Prisync",
  "brandDomain": "prisync.com",
  "brandAliases": [],
  "prompts": [
    "best ecommerce price monitoring tool",
    "competitor price tracking software for retailers"
  ],
  "competitors": [],
  "engines": [
    "google_ai_overview",
    "google_ai_mode"
  ]
}' |
apify call s-r/ai-brand-visibility --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,s-r/ai-brand-visibility"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/e7EwiC9H5RDvWygpR/builds/8004QT9LX1YdleZlL/openapi.json
