# AI Visibility Checker: Brand Mentions in AI Answers (`bottyprojects/ai-visibility-checker`) Actor

Does AI recommend your brand? Ask your buyer questions through the OpenAI, Gemini and Claude APIs with your own keys (free mode: a free Gemini key, built-in knowledge only) and get mentions, citations, rank vs competitors, changes since last run and a plain-English report.

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

## Pricing

from $10.00 / 1,000 answer 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?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## AI Visibility Checker: Brand Mentions in AI Answers

**Does AI recommend your brand when your buyers ask?** Give it your brand, your website or Etsy shop, a few competitors and the questions your customers ask. It asks each question through the official APIs of **OpenAI (the models behind ChatGPT), Google Gemini and Anthropic Claude**, using **your own API keys**. In live mode, OpenAI and Claude search the web. Gemini, and the default free mode, answer from the model's built-in knowledge. You get one row per engine × question: whether you were mentioned, whether your link was cited, your rank against competitors, which sources the AI used, and what changed since the last run. A summary gives a **visibility score per engine** and your **share of voice**, and every run writes a **plain-English report** (HTML + Markdown) with what changed since last time and a few tips.

**New here? Start in free mode.** It's the default: paste a free Gemini key from [Google AI Studio](https://aistudio.google.com/apikey) (no card) and press Start. (Not in the EEA, Switzerland or the UK: there, Google's terms require a paid, billing-enabled key.) Free mode asks Gemini without web search, so it shows what the AI recommends from its **built-in knowledge, not live search**. Switch **Mode** to *Live web search* when you have engine keys that include search. If you press Start without a key, nothing is checked and no per-answer fee is charged: the run ends with a short message (and one free row) explaining how to get a free key.

- ✅ **3 AI answer engines** through their official APIs: OpenAI Responses API (with web search), Google Gemini API (built-in knowledge), Anthropic Claude API (with web search). These are API answers, not the consumer chat apps.
- ✅ **Free mode** – works with only a free Gemini key: one request at a time, spaced out, and it switches to a second free model when the first hits its daily limit
- ✅ **Plain-English report** after every run – score, which questions named you, competitors and sources, what changed since last time, and 2–3 tips from your data. Free
- ✅ **Bring your own keys** – you pay the AI provider directly, at their API prices. A **free Gemini key** from Google AI Studio is enough to start
- ✅ **Mentions** – brand name, spelling variants (`Example Paper Co.`, `ExamplePaperCo`, `example-paper-co`), aliases and your domain in the text
- ✅ **Citations** – your website (incl. subdomains), **Etsy shop and listing links** (`shop.etsy.com`, `etsy.com/shop/…`, `etsy.com/uk/listing/…`), Amazon stores, Pinterest profiles and more
- ✅ **Rank against competitors** – who the AI named first, second, third…, and which competitors were mentioned or cited
- ✅ **Visibility score and share of voice** per engine and overall, plus the most-cited domains
- ✅ **Change tracking** between runs: newly mentioned, dropped, newly cited, citation lost, rank up/down, competitor appeared/dropped
- ✅ **Safe with your keys**: keys are secret inputs, never logged or written to the output, and the Actor never spends your API credits on an answer it can't deliver within your max cost
- ✅ **One failed call never fails the run**: you get a clear, free error row instead. An engine without a key is skipped and noted in the summary. A run where your key is missing or rejected ends with a how-to message and free error rows, not a crash

*The brand names, shop URLs and answers in this README (such as `Example Paper Co.`) are made-up examples only.*

### Use cases

- **Small shops and Etsy sellers.** Find out whether the AI models behind ChatGPT and Gemini suggest your shop for "best printable gratitude journal" or "holiday hosting planner", and which shops they suggest instead.
- **Brands and marketers (GEO / AEO).** Track your AI share of voice against named competitors, on the questions that matter, every week.
- **Agencies.** Run one tracker per client (`trackerId`) and report score changes month over month.
- **Content and PR teams.** See which domains the AI cites (Reddit threads, review sites, blogs). Those are the pages to get featured on.

### Input

| Field | What to enter |
|---|---|
| **Brand or business name** (required) | e.g. `Example Paper Co.` |
| **Your URLs** | your website, Etsy shop, Amazon store, Pinterest… e.g. `https://www.etsy.com/shop/YourShop`, `examplepaper.example`. A bare `etsy.com` is ignored, because it would match every shop |
| **Other names (aliases)** | other spellings or product names that should count as a mention |
| **Competitors** | one per line: `Name`, or `Name \| url \| url`, or `Name \| url \| alias:Other name`, or just a URL |
| **Buyer queries** (required) | the questions your customers ask, up to 200 |
| **Mode** | **Free mode: Gemini free key, no live search** (default) or **Live web search: my own engine keys** |
| **AI engines** | live mode only: which engines to run. Engines without a key are skipped |
| **API keys** | Gemini, OpenAI, Anthropic. Secret fields |
| Models | defaults `gpt-5-mini`, `gemini-3.8-flash`, `claude-haiku-5-5` |
| Free mode: models, seconds between requests | defaults `gemini-3.8-flash` → `gemini-3.6-flash` → `gemini-3.5-flash-lite`, 6 s apart |
| Prompt template | `{query}` by default. e.g. `I'm shopping on Etsy. {query}` |
| Samples per query | 1–5. AI answers vary; more samples give a steadier score |
| Searcher country | 2-letter code (e.g. `US`) to localize web search where the engine supports it |
| Always search the web | live mode, OpenAI/Claude: on by default, so answers reflect what the engine finds today |
| Tracker ID | a name for this tracked list. Change tracking compares runs with the same ID |
| Only output changes | output only rows whose status changed (newly mentioned, dropped, …) |
| Include full answer text | off by default. Turn on to store the whole AI answer (`answerText`) in each row |

Free-mode example (the default):

```json
{
  "brandName": "Example Paper Co.",
  "brandUrls": ["https://www.etsy.com/shop/YourShop"],
  "queries": ["What is the best printable gratitude journal?", "Where can I buy a printable holiday hosting planner?"],
  "geminiApiKey": "<your free key>",
  "trackerId": "monthly"
}
```

Live-search example:

```json
{
  "brandName": "Example Paper Co.",
  "brandUrls": ["https://www.etsy.com/shop/YourShop"],
  "competitors": ["Brand A | brand-a.example", "Brand B | brand-b.example"],
  "queries": ["What is the best printable gratitude journal?", "Where can I buy a printable holiday hosting planner?"],
  "mode": "live",
  "engines": ["gemini", "chatgpt"],
  "geminiApiKey": "<your key>",
  "openaiApiKey": "<your key>",
  "trackerId": "weekly"
}
```

**Getting a key:** Gemini – [Google AI Studio](https://aistudio.google.com/apikey) (free tier available). OpenAI – [platform.openai.com](https://platform.openai.com/api-keys) (prepaid credits). Anthropic – [console.anthropic.com](https://console.anthropic.com/).

### Output

One row per engine × query (× sample), plus one free summary row. Dataset views: **Overview**, **Changes**, **Sources**, **Errors**.

```json
{
  "recordType": "answer",
  "engine": "chatgpt",
  "model": "gpt-5-mini",
  "query": "best printable gratitude journal",
  "brandMentioned": true,
  "brandMatchedTerms": ["ExamplePaperCo"],
  "brandRank": 2,
  "brandCited": true,
  "brandCitedUrls": ["https://www.etsy.com/shop/YourShop"],
  "mentionedBrandsInOrder": ["Brand B", "Example Paper Co."],
  "competitorsMentioned": ["Brand B"],
  "citedDomains": ["etsy.com"],
  "citations": [{ "url": "https://www.etsy.com/shop/YourShop", "title": "etsy.com" }],
  "answerSnippet": "Try Brand B or ExamplePaperCo on Etsy.",
  "changeStatus": "newly-mentioned",
  "changes": ["newly-mentioned"],
  "checkedAt": "2026-10-31T19:31:22.600Z"
}
```

| Field | Meaning |
|---|---|
| `brandMentioned`, `brandMentionCount`, `brandMatchedTerms` | whether and how your brand was named in the answer |
| `brandRank` | your position among the tracked brands (you + competitors) in the order they're first mentioned. 1 = named first |
| `brandListPosition` | your item number when the answer is a numbered or bulleted list |
| `brandCited`, `brandCitedUrls` | whether one of your URLs is among the answer's cited sources |
| `brandInSearchResults` | your URL was in the engine's search results but not cited (Claude) |
| `competitorsMentioned`, `competitorsCited`, `competitorDetails` | the same, for each competitor |
| `citations`, `citedUrls`, `citedDomains` | all sources the answer cites |
| `answerSnippet`, `answerText` | a short snippet around your mention (or the start of the answer), and the full answer if you turn on **Include full answer text** (off by default) |
| `changeStatus`, `changes` | `baseline`, `unchanged`, `changed`, `newly-mentioned` or `dropped`, and the detailed change list |
| `checkedAt` | when the answer was fetched (UTC) |

The **summary** row (also saved as the `RUN_SUMMARY` record) has, per engine and overall: mention rate, citation rate, top-1 rate, average rank, **visibility score** (0–100), **share of voice**, top cited domains, the previous run's score and the change, plus a query × engine matrix, skipped engines and errors.

Every answer row also has `liveSearch` (true/false) and `answerSource`: `live web search` or `built-in knowledge, not live search`. The summary has `mode`, `answerSource`, `modelFallbacks` (free-mode model switches) and `report` (links to the report).

#### The report (`REPORT` and `REPORT_MD`)

After each run the Actor saves a one-page report for a small-shop owner to the run's key-value store: **`REPORT`** (HTML; open it in a browser) and **`REPORT_MD`** (the same in Markdown, easy to paste into an email or doc). `RUN_SUMMARY.report.html` and `.markdown` link to them, and the Output tab links to the HTML report. It shows:

- the visibility score, and how many questions named you or linked to you
- a question-by-question table: mentioned, linked, rank, and who was named instead
- the competitors and sources (or, in free mode, the sites the AI linked from memory) that appeared, plus other names the AI often used
- **what changed since the last run with the same Tracker ID**: score up or down, questions newly mentioned or lost, links gained or lost, new or gone competitors, new sources. The first run is the "before" picture
- 2–3 tips chosen from the data (for example: not named at all, named but not linked, which sites to get listed on)

The report is free (no charge event). The report links work for anyone who has the link, so share them with care.

**Visibility score** = 50 points for being mentioned, 30 for being cited, 20 for being in the top 3, averaged over the answers. **Share of voice** = answers mentioning a brand ÷ all brand mentions across you and your competitors.

### How change tracking works

The Actor keeps a small memory in a named key-value store, `ai-visibility-checker-state`, in **your** account: one record per tracker ID, engine and query, plus one report snapshot per tracker ID. Built-in-knowledge answers (free mode and all Gemini answers) are tracked separately from live-search answers, so switching modes doesn't show up as false changes. Each run compares the new answer with the last one: **newly mentioned**, **dropped**, **newly cited**, **citation lost**, **rank improved/worsened**, **competitor appeared/dropped**. The first run is the `baseline`. The memory is only updated when the row was delivered, so a failed call or a max-cost cut-off never shows up as "dropped".

**Tip:** schedule a weekly run with a fixed **Tracker ID**, and add the Slack or email integration to get the changes. AI answers vary from run to run, so use 2–3 samples per query if you want to alert on drops.

Run datasets follow your Apify plan's data retention. The named state store keeps only aggregates (queries, mentioned or cited flags, rank, competitor names, cited domains and URLs, no answer text) until you delete it in Storage → Key-value stores.

### Pricing

Pay per event: **$0.01 per answer checked** (one engine × one query × one sample). The summary and error rows are free. You pay the AI provider for the API call separately, with your own key.

Examples (Actor fee):

- Free mode, 10 queries (free Gemini key): **$0.10**, and $0 for Google on the free tier. "Free mode" means no AI provider cost; the Actor fee still applies. The report is free
- 10 queries × 3 engines: **$0.30**, plus roughly $0.20–$0.35 in API costs to OpenAI and Anthropic (Gemini on the free tier: $0)
- Weekly 20 queries × 2 engines: **$0.40 a week**

Set **Max cost per run** to cap any run. The Actor checks the cap before each AI call, so it stops cleanly and never spends your API credits on an answer it can't deliver.

### FAQ

**Why do I need my own API keys?** You pay the AI providers directly at their own API prices (this Actor adds nothing to them; its $0.01 per answer fee is separate), and the answers come from the official APIs, not from scraping the chat apps. That's why the Actor fee is only $0.01 per answer. Start with a free Gemini key.

**Are the answers the same as in the ChatGPT / Gemini / Claude apps?** Close, not identical. The apps add personalization, memory, location and different default models. The APIs with web search are the most consistent, repeatable way to measure what these models recommend. Treat the score as a trend, not as exactly what one person sees.

**Why do results change between runs?** AI answers are non-deterministic and the web changes. Use **Samples per query** (2–3) for a steadier score, and watch trends over several runs.

**Is the Gemini free tier enough?** For small checks, yes. That's what free mode is for. Gemini is always asked without Google Search, so its rows are labelled "built-in knowledge, not live search". Each free model has a daily request limit (about 20 requests a day per model at the time of writing). Free mode spaces requests out and switches to the next free model when one runs out. With three models that's roughly 60 answers a day, so keep free-mode runs to about 10–20 questions × 1–2 samples. If every free model hits its limit, you get a clear error row, the summary says when it resets, and the answers so far are kept.

**Free mode is not for users in the EEA, Switzerland or the UK.** Google's terms allow only paid (billing-enabled) Gemini API use there. In those regions, turn on billing for your Gemini key first. On the free tier, Google uses your questions and answers to improve its products, and human reviewers may read them, so don't put personal, sensitive or confidential information in your questions. You must be 18 or older to use the Gemini API.

**Is my key safe?** Keys are secret inputs (encrypted by Apify). They're sent only to the provider's API, never logged, and scrubbed from any error message.

**Does it measure sentiment?** No. It measures mentions, citations, rank and share of voice. The full answer text is included if you turn on **Include full answer text**, if you want to review the tone.

**Can I track people instead of brands?** No. Use it for business, brand, product and shop names only. Don't enter private individuals' names, and don't use it to monitor or profile people. AI answers can name real people, such as founders and reviewers, so treat stored answers as personal data where your law requires it.

**What counts as a mention?** Your brand name and aliases, as whole words, in common variants: spaces, hyphens or no spaces (`ExamplePaperCo`), any case, with or without apostrophes. Your own domain in the text also counts. Short or generic names can false-match, so use a distinctive name or add aliases.

**Does it work with Etsy?** Yes. Add your shop URL (`https://www.etsy.com/shop/YourShop`). Citations of your shop, its `yourshop.etsy.com` address and listing URLs you add (`etsy.com/listing/123…`) count as yours, including country versions like `/uk/` and `/de-en/`. Other Etsy shops don't.

**Does Gemini cite live sources?** No. Google's terms for Grounding with Google Search don't allow tools to store or analyze grounded answers or collect their links, so this Actor asks Gemini without Search grounding in every mode. Gemini rows show what it recommends from its built-in knowledge, and any links it writes come from memory.

**Something broke?** Open an issue on the Actor's Issues tab. The error rows and the `RUN_SUMMARY` record show the engine, HTTP status and message.

### Disclaimer

This Actor is an independent tool and is not affiliated with, endorsed by or sponsored by OpenAI, Google or Anthropic. ChatGPT, Gemini and Claude are trademarks of their respective owners. The Actor uses each provider's official API with the API keys you supply, and your use of those APIs is subject to each provider's terms.

No guarantee: the Actor reports what AI models answered at the time of the run. AI answers vary between runs, models and versions, and API answers can differ from what people see in the ChatGPT, Gemini or Claude apps. AI answers can be wrong, incomplete or out of date, so check any claim before you rely on it. The score is a trend indicator, not a ranking guarantee. Nothing here is SEO, marketing or legal advice. The Actor's creator isn't the AI provider and has no control over what the models say.

# Actor input Schema

## `brandName` (type: `string`):

The name buyers would see in an AI answer. Variants are matched automatically: "Example Paper Co." also matches "ExamplePaperCo" and "example-paper-co".

## `brandUrls` (type: `array`):

Used to detect when an AI answer cites you. Own domains match all their pages and subdomains. Marketplace URLs match only your shop: https://www.etsy.com/shop/YourShop (also matches yourshop.etsy.com and localized Etsy URLs), an Etsy listing URL (matches that listing), or an Amazon /stores/ page. A bare etsy.com or amazon.com is ignored because it would match every seller.

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

Other names that count as a mention of you, e.g. an old shop name or a product line. Etsy shop names from your URLs are added automatically.

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

One per line: "Name | url | url | alias". Parts that look like URLs/domains are used for citation matching; other parts are extra names. Example: "Brand A | brand-a.example | alias:Brand A Planner" or just an Etsy shop URL.

## `queries` (type: `array`):

The questions your buyers ask AI assistants. Write them as a buyer would, without your brand name, e.g. "What's the best printable gratitude journal?". Each query is asked to each engine.

## `mode` (type: `string`):

<b>Free mode</b> needs only a free Gemini API key (Google AI Studio, no card). It asks Gemini without web search, so results show the AI's <b>built-in knowledge, not live search</b>. It runs one request at a time, spaces requests out and switches to a second free model if the first hits its daily limit. Not for users in the EEA, Switzerland or the UK, where Google allows only paid Gemini API use. On the free tier Google may use your questions and answers to improve its products, so don't include personal or confidential information. The engine and model settings below are ignored in free mode.<br><b>Live web search</b> uses the engines and API keys you choose below (paid keys usually needed).

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

Live web search mode only (free mode always uses Gemini). Engines to ask. An engine is skipped (and logged) if you don't give its API key below.

## `geminiApiKey` (type: `string`):

From Google AI Studio (aistudio.google.com/apikey). Free-tier keys work in free mode (not for users in the EEA, Switzerland or the UK, where a billing-enabled key is required). Gemini is always asked without Google Search. Stored encrypted; never logged or output.

## `openaiApiKey` (type: `string`):

From platform.openai.com. Billed by OpenAI to you (web search tool calls + tokens). Stored encrypted; never logged or output.

## `anthropicApiKey` (type: `string`):

From platform.claude.com. Web search must be enabled for your organization. Billed by Anthropic to you. Stored encrypted; never logged or output.

## `openaiModel` (type: `string`):

Any Responses-API model that supports the web_search tool. gpt-5-mini is cheap; use a flagship model to mirror ChatGPT more closely.

## `geminiModel` (type: `string`):

Default gemini-3.8-flash. Gemini answers from its built-in knowledge (no Google Search grounding) in every mode.

## `claudeModel` (type: `string`):

Any Claude model that supports the web search tool.

## `promptTemplate` (type: `string`):

How each query is sent. {query} is replaced by the query. Keep "{query}" to ask exactly what a buyer would type.

## `samplesPerQuery` (type: `integer`):

AI answers vary. Ask each query this many times per engine (1–5) for a steadier picture. Each sample is one charged check and one API call on your key.

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

2-letter country code (e.g. US, GB) passed as approximate user location to OpenAI and Claude web search. Leave empty for none.

## `freeModels` (type: `array`):

Free mode starts with the first model and moves to the next when one hits its free daily limit or is not available to your key.

## `freeModeDelaySecs` (type: `integer`):

Spacing between Gemini requests in free mode, to stay under the free per-minute limit.

## `forceWebSearch` (type: `boolean`):

Force a web search on OpenAI so every answer has sources. Turn off to let the model decide, as the consumer apps do. (Claude decides for itself; Gemini never searches the web.)

## `trackerId` (type: `string`):

Runs with the same tracker ID are compared to find changes (newly mentioned, dropped, rank changes). Letters, digits, - and \_ only.

## `onlyChanges` (type: `boolean`):

Output only answers whose result changed since the last run with this tracker ID (plus first-time baselines). Every check is still charged because the AI call was made; the summary record is always output.

## `includeFullAnswer` (type: `boolean`):

Store the whole AI answer in each row (answerText) as evidence. Off (default): only a short snippet.

## `snippetLength` (type: `integer`):

Characters of answer text around your first mention (or the answer start).

## `maxConcurrencyPerEngine` (type: `integer`):

Lower this if you hit your API rate limits (e.g. free Gemini or new API accounts).

## `outputErrors` (type: `boolean`):

Add a free row for each failed check (e.g. invalid key, rate limit) instead of only logging it.

## Actor input object example

```json
{
  "brandName": "Example Paper Co.",
  "brandUrls": [
    "https://www.etsy.com/shop/YourShop",
    "examplepaper.example"
  ],
  "competitors": [
    "Brand A | brand-a.example",
    "Brand B | brand-b.example",
    "https://www.etsy.com/shop/SomeCompetitorShop"
  ],
  "queries": [
    "What is the best printable gratitude journal?",
    "Where can I buy a printable holiday hosting planner?",
    "cozy home printables on Etsy"
  ],
  "mode": "free",
  "engines": [
    "chatgpt",
    "gemini",
    "claude"
  ],
  "openaiModel": "gpt-5-mini",
  "geminiModel": "gemini-3.8-flash",
  "claudeModel": "claude-haiku-5-5",
  "promptTemplate": "{query}",
  "samplesPerQuery": 1,
  "freeModels": [
    "gemini-3.8-flash",
    "gemini-3.6-flash",
    "gemini-3.5-flash-lite"
  ],
  "freeModeDelaySecs": 6,
  "forceWebSearch": true,
  "trackerId": "default",
  "onlyChanges": false,
  "includeFullAnswer": false,
  "snippetLength": 300,
  "maxConcurrencyPerEngine": 2,
  "outputErrors": true
}
```

# Actor output Schema

## `answers` (type: `string`):

No description

## `changes` (type: `string`):

No description

## `report` (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 = {
    "brandName": "Example Paper Co.",
    "brandUrls": [
        "https://www.etsy.com/shop/YourShop"
    ],
    "queries": [
        "What is the best printable gratitude journal?",
        "Where can I buy a printable holiday hosting planner?"
    ],
    "mode": "free"
};

// Run the Actor and wait for it to finish
const run = await client.actor("bottyprojects/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 = {
    "brandName": "Example Paper Co.",
    "brandUrls": ["https://www.etsy.com/shop/YourShop"],
    "queries": [
        "What is the best printable gratitude journal?",
        "Where can I buy a printable holiday hosting planner?",
    ],
    "mode": "free",
}

# Run the Actor and wait for it to finish
run = client.actor("bottyprojects/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 '{
  "brandName": "Example Paper Co.",
  "brandUrls": [
    "https://www.etsy.com/shop/YourShop"
  ],
  "queries": [
    "What is the best printable gratitude journal?",
    "Where can I buy a printable holiday hosting planner?"
  ],
  "mode": "free"
}' |
apify call bottyprojects/ai-visibility-checker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,bottyprojects/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/qkxbR0doKemdebsMt/builds/y0lDvECzqSVjV9OaG/openapi.json
