# AI Visibility Checker for Local Businesses — ChatGPT & Gemini (`manno15/ai-visibility-checker`) Actor

Does ChatGPT, Gemini or Claude recommend your plumber, med spa, dentist or agency client when someone asks? Same fixed buyer questions for a category + city every month, so the 0-100 score is comparable over time. Returns rank, competitors named, and the websites the AIs cite. Errors never billed.

- **URL**: https://apify.com/manno15/ai-visibility-checker.md
- **Developed by:** [Emmanuel Doremy](https://apify.com/manno15) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $30.00 / 1,000 prompt checkeds

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 Visibility Checker for Local Businesses

**When someone asks ChatGPT, Gemini or Claude "who's a good plumber in Marietta?", does your business come up?**

A growing share of customers don't search, they ask. The AI answers with three to five names. This Actor tells a local business (or the agency that serves it) whether it is one of those names, how often, in what position, who gets recommended instead, and which websites the AIs trust when they decide.

### Why this one, when there are others

Most AI-visibility tools let you type any prompt you like. That makes month-over-month numbers meaningless, because you never ask the same thing twice. This Actor is built differently:

- **Same questions every month.** Prompts are generated deterministically from `category` + `location` + `batteryVersion`. Run it in October and again in November and the score measures the same thing. That is what makes it a report, not a screenshot.
- **Built for local businesses.** Input is a category and a city, not a keyword list. The questions are the ones real customers ask: *"affordable but reliable…", "who should I call…", "which ones should I avoid…"*.
- **Tells you why, not just whether.** Every answer's cited websites are collected and ranked. If the AIs keep citing Yelp and Expertise.com and you're not on either, that is your to-do list.
- **You only pay for answers.** Engine errors, rate limits and empty responses are never billed.
- **Cheaper at agency volume.** Bring your own OpenAI / Gemini / Anthropic keys and pay a fraction of the per-question price.

### A real run

Superior Plumbing, a real plumber in Marietta, GA, 5 questions × 3 engines, September 2026:

```json
{
  "rowType": "summary",
  "brand": "Superior Plumbing",
  "category": "plumber",
  "location": "Marietta, GA",
  "visibilityScore": 47,
  "mentionRate": 0.267,
  "avgRankWhenMentioned": 3,
  "shareOfVoice": 0.138,
  "competitorShareOfVoice": {"Plumb Doctor": 0.241, "Dupree Plumbing": 0.241, "Greenlee Plumbing": 0.138},
  "topCitedSources": [{"source": "expertise.com", "count": 18}, {"source": "benjaminfranklinplumbing.com", "count": 13}, {"source": "plumbdoctorga.com", "count": 12}],
  "engineBreakdown": {
    "gemini":    {"prompts": 5, "mentioned": 3, "mentionRate": 0.6, "avgRank": 1},
    "openai":    {"prompts": 5, "mentioned": 0, "mentionRate": 0.0, "avgRank": null},
    "anthropic": {"prompts": 5, "mentioned": 1, "mentionRate": 0.2, "avgRank": 9}
  }
}
```

The story in one line: **Gemini ranks them #1, ChatGPT has never heard of them, and the AIs are reading Expertise.com.** That is the conversation an agency wants to have with a client.

### What you get

One row per question × engine:

| field | meaning |
|---|---|
| `mentioned` | did the answer name the business |
| `rank` | position among the businesses named (1 = first) |
| `competitorsNamed` | every other business the answer recommended |
| `sentiment` | how the answer treated the business |
| `citedSources` | websites the answer relied on |
| `promptIntent` | `best`, `affordable`, `emergency`, `compare`, `near_me`… so you can see *where* it is weak |
| `answerSnippet` | the first 400 characters of what the AI actually said |
| `error` | why an answer is missing, if it is (never billed) |

Plus one `summary` row with the **Visibility Score (0–100)**, mention rate, average rank, share of voice vs competitors, per-engine and per-intent breakdowns, and the top cited sources. The summary is also stored under the `SUMMARY` key in the run's key-value store for chaining into report generators.

### Engines

- **ChatGPT** — OpenAI Responses API with web search (real citations)
- **Gemini** — Google API with Search grounding (real citations)
- **Claude** — Anthropic API with web search (real citations)
- **Perplexity** — coming soon
- **Google AI Overviews** — coming soon, via a licensed SERP data provider; no scraping

### Inputs

`brand` and `category` are required. Add `location` for local businesses; leave it empty for national brands. Optional `competitors` pins the share-of-voice comparison to names you care about; leave it empty and the Actor ranks whoever the AIs actually recommend.

**Bring your own keys:** pass `byoKeys` (`{"openai": "sk-…", "gemini": "…", "anthropic": "…"}`) and you are billed at the lower BYO per-question price.

### Pricing

Pay per event, no subscription. Roughly: 10 questions × 3 engines ≈ $1, a 25-question monthly report ≈ $2.35. Errors are free. Exact per-event prices are on the pricing tab.

### Use cases

- **Agencies:** run it for every local client monthly; the `summary` row drops straight into a report or a Google Sheet.
- **Local businesses:** find out which AI assistants ignore you and what sites they cite instead.
- **AI agents:** enabled for agentic usage; call it with a brand, a category and a city and read `SUMMARY`.

# Actor input Schema

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

The business name exactly as customers would say it, e.g. "Superior Plumbing". Works for national brands too.

## `website` (type: `string`):

Used to disambiguate the brand and to detect citations of its own site.

## `category` (type: `string`):

What the business is, in a customer's words: "plumber", "med spa", "family dentist", "HVAC company".

## `location` (type: `string`):

City + state/region for local businesses, e.g. "Marietta, GA". Leave empty for national/online brands.

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

Names to track for share of voice. Leave empty to auto-detect from answers.

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

Which AI assistants to ask. All three are on by default so you see where the business is invisible. Perplexity and Google AI Overviews are coming soon.

## `promptCount` (type: `integer`):

How many buyer questions to ask each engine. 10 = quick check (~$1), 25 = monthly report (~$2.35), 50 = deep audit.

## `byoKeys` (type: `object`):

JSON object of API keys, e.g. {"openai": "sk-...", "gemini": "..."}. Using your own keys is billed at a lower per-event price.

## `batteryVersion` (type: `string`):

Keep this fixed across months so scores stay comparable. Bump only when you intentionally change prompts.

## Actor input object example

```json
{
  "brand": "Superior Plumbing",
  "category": "plumber",
  "location": "Marietta, GA",
  "engines": [
    "openai",
    "gemini",
    "anthropic"
  ],
  "promptCount": 5,
  "batteryVersion": "v1"
}
```

# Actor output Schema

## `results` (type: `string`):

No description

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

No description

# 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": "Superior Plumbing",
    "category": "plumber",
    "location": "Marietta, GA",
    "engines": [
        "openai",
        "gemini",
        "anthropic"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("manno15/ai-visibility-checker").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": "Superior Plumbing",
    "category": "plumber",
    "location": "Marietta, GA",
    "engines": [
        "openai",
        "gemini",
        "anthropic",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("manno15/ai-visibility-checker").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": "Superior Plumbing",
  "category": "plumber",
  "location": "Marietta, GA",
  "engines": [
    "openai",
    "gemini",
    "anthropic"
  ]
}' |
apify call manno15/ai-visibility-checker --silent --output-dataset

```

## MCP server setup

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

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/t22krgMqrxUuQsIu9/builds/WRV8mweW4OisHuhSE/openapi.json
