skills/apify-ai-search-visibility-tracker/SKILL.md
Track whether a brand and its competitors get cited or mentioned across Google AI Overviews, Google AI Mode, ChatGPT Search, Perplexity, Microsoft Copilot, and Google Gemini for a defined set of prompts, on a recurring schedule. Use when user asks to track AI visibility, monitor brand mentions in AI search, track ChatGPT citations, do AI search SEO tracking, GEO tracking (Generative Engine Optimization), AEO tracking (Answer Engine Optimization), monitor Perplexity citations, track AI Overviews mentions, or see if their brand shows up in AI search.
npx skillsauth add apify/awesome-skills apify-ai-search-visibility-trackerInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Snapshots brand citations and mentions across six AI search surfaces (Google AI Overviews, Google AI Mode, ChatGPT Search, Perplexity, Microsoft Copilot, Google Gemini) on a recurring schedule. Every run appends to a named Apify Dataset, writes the raw item to a named Apify Key-Value Store, and produces a Markdown report comparing today's snapshot to every prior run. Recurrence is driven by the operating system's own scheduler -- launchd on macOS, cron on Linux, Task Scheduler on Windows. See reference/scheduling.md.
(No need to check upfront)
APIFY_TOKEN saved in a .env file next to config.json (the runner auto-loads it).pip3 install requests (only third-party dependency); pip3 install tldextract recommended for accurate registrable-domain matching on multi-part TLDs.schtasks instructions.Copy this checklist and track progress:
Task Progress:
- [ ] Step 1: Load or collect the seven required inputs
- [ ] Step 2: Confirm AI sources and cadence
- [ ] Step 3: Write config.json + .env, then install the OS schedule
- [ ] Step 4: Run a snapshot now so the user sees the first report
- [ ] Step 5: Deliver the history report (diff vs. all prior runs)
If config.json exists in the user's working directory, load it and skip to Step 4 unless the user asks to reconfigure. On first run, ask all seven anchors before any Actor call:
| # | Input | Why it matters |
|---|-------|----------------|
| 1 | Brand URL | Primary domain. Drives registrable-domain citation matching (blog.apify.com -> apify.com). |
| 2 | Brand name(s) | Surface forms for text-mention matching (e.g., Apify, apify.com, @apify). URL-only matching misses mentions without links. |
| 3 | Competitor brands | Ask explicitly: "Which competitors do you want tracked alongside your brand?" Accept name + domain pairs. Zero is allowed; the question must still be asked on first run. |
| 4 | Prompts to monitor | One or more search queries. Each runs through every enabled AI source. |
| 5 | Cadence | daily / weekly / monthly. Drives the schedule entry that install_cron.sh writes. |
| 6 | Which AI sources | Present the six (AI Overviews, AI Mode, ChatGPT, Perplexity, Copilot, Gemini), all enabled by default. Each adds per-result cost -- current pricing on the Actor page (https://apify.com/apify/google-search-scraper). |
| 7 | Apify Dataset name | The named dataset to append to. If absent, created on first run; the name is recorded in config.json. |
After those seven, ask optional follow-ups: countryCode, languageCode, location (UULE), preferred run hour (default 09:00 local).
Then one verbosity question -- save as config.json:include_full_answers:
on_demand (default): report shows short quoted snippets around each surface-form match. Full LLM answers live in the named KV store; user can ask later.always: report embeds the full LLM answer verbatim whenever any entity is mentioned. Useful for one prompt; gets unwieldy at 5+ prompts.Echo back the user's seven choices in a single paragraph for confirmation. If the user toggles sources, update the in-memory config before writing.
config.json + .env, Then Install the OS ScheduleCreate the working directory layout next to where the user wants reports to land:
working-dir/
config.json # copied from the skill's config.example.json, edited with collected values
.env # APIFY_TOKEN=apify_api_xxx (chmod 600)
cp ${CLAUDE_PLUGIN_ROOT}/reference/scripts/config.example.json ./config.json
# then edit with the collected values, save
echo 'APIFY_TOKEN=your_token_here' > ./.env
chmod 600 ./.env
Then install the OS schedule. The installer detects macOS / Linux / Windows and writes the right entry. It validates that config.json and .env both exist before doing anything, and shows the user the exact schedule entry before applying it:
bash ${CLAUDE_PLUGIN_ROOT}/reference/scripts/install_cron.sh --cadence daily --hour 9
Cron expression mapping (the installer fills these in):
| Cadence | Cron expression | When |
|---------|-----------------|------|
| daily | 0 H * * * | every day at H:00 local |
| weekly | 0 H * * 1 | every Monday at H:00 |
| monthly | 0 H 1 * * | the 1st of every month at H:00 |
H is the user's chosen hour (0-23, default 9).
The schedule entry contains no credentials. The runner reads APIFY_TOKEN from .env at fire time. Rotating the token is echo 'APIFY_TOKEN=new_value' > .env -- no reinstall needed. Full mechanics in reference/scheduling.md.
Fire one snapshot immediately so the user sees the first report without waiting for tomorrow's schedule:
macOS:
launchctl kickstart "gui/$(id -u)/com.apify.ai-visibility-tracker"
tail -f ~/Library/Logs/ai-visibility-tracker.log
Linux / generic:
python3 ${CLAUDE_PLUGIN_ROOT}/reference/scripts/run_snapshot.py --config ./config.json
Both paths:
apify/google-search-scraper with the configured prompts + AI-source toggles.reference/output-schema.md).reports/snapshot-<ISO-date>.md next to config.json.The runner reads its input only from --config and env vars. It never prompts on stdin -- the scheduler has no stdin to give it.
Snapshot summaries are entity-major: one Markdown table per tracked entity (brand, then competitors), one row per AI source, columns Source | Cited | Mentioned | SoV% | Matched URLs | History. Each table is followed by a one-line interpretive note quoting the surface-form context where the entity was mentioned. The runner emits this format; chat summaries should mirror it. Full template in reference/output-schema.md.
Open reports/snapshot-<ISO-date>.md and surface the top findings in chat. From the second run onwards the report compares today's snapshot to every prior run (unless the user asks for last-run-only). Lead with:
Don't restate the full report -- point the user at the file. Per-source scorecards + per-prompt detail + top-10 most-cited URLs are already in there.
The skill uses a single Actor -- apify/google-search-scraper -- for all six AI surfaces. AI Overviews ride alongside the organic SERP automatically; do not set disableGoogleSearchResults: true. Input schema and field-name mapping in reference/apify-actor-usage.md. Pricing changes; check the Actor's pricing tab before quoting numbers.
run_snapshot.py -- launchd / cron has no stdin.\bbrand\b, case-insensitive) so Apify doesn't match Apifying. See reference/citation-matching.md.blog.apify.com counts as apify.com). See reference/citation-matching.md.cited: false, mentioned: false, answer_text: "[no answer returned]". Continuity is required for the history diff.APIFY_TOKEN not found -- Tell the user to put it in .env next to config.json (echo 'APIFY_TOKEN=...' > .env && chmod 600 .env). Token at https://console.apify.com/account/integrations.
config.json not found -- Run Step 3 first to create it from the template.
Dataset name not set -- Ask the user for a name; the runner will create the dataset on first append.
Actor run FAILED -- Print the console link from the runner output and ask the user to inspect it.
AI source returned no answer -- The row is still written with [no answer returned]. Not an error.
Schedule not firing -- See reference/scheduling.md troubleshooting section: macOS launchctl list | grep ai-visibility, Linux crontab -l, check the log file at ~/Library/Logs/ai-visibility-tracker.log (macOS) or ~/.ai-visibility-tracker.log (Linux).
No previous run to diff against -- First run only. The report renders the snapshot without a history section.
development
Builds a list of verified business emails from Google Maps, Google SERPs, or a user-supplied URL list. Verification happens inside the same Apify run — no third-party verifier needed. Use when user asks to find verified emails, build a leads list, scrape emails from Maps or SERP, verify emails for a URL list, or find an Apollo / Hunter alternative.
development
Find sites ranking for target keywords, score every prospect with Ahrefs domain authority and page-level traffic, identify the strongest pitch angle per row ("links to competitor", "mentions brand without linking", "top-3 SERP", "resource page", "outdated content"), generate brand-voice-matched outreach emails using an outreach-type-aware template (unlinked-mention claim, competitor-link replacement, resource-page inclusion, outdated-content replacement, topical niche-edit), and propose a concrete in-article link placement as three artifacts — the verbatim source sentence, the same sentence rewritten with the link spliced in, or a fully-drafted new insertion if no natural fit exists. Use when user asks to find link building opportunities, prospect link partners, recover unlinked brand mentions, replace competitor links, build a tiered outreach list, or run cold email outreach for SEO link building.
tools
Discover Instagram brand–creator partnerships by chaining Apify Actors. Use when the user asks who collabs with a brand, which brands a creator has done paid posts for, wants to audit an influencer's branded-content history, or wants to scope a brand's sponsorship roster. **Triggers:** - "who collabs with [brand] on Instagram?" - "what brands has [creator] done sponsored posts for?" - "find paid partnerships / branded content for [handle]" - "audit [influencer]'s brand deals" - "show me [brand]'s influencer roster" Works in either direction — brand → creators or creator → brands — and detects direction from the data, so don't ask the user to declare it. Requires Apify MCP tools.
development
Look up official company data from European public registries across 11 countries/regions (CZ, SK, PL, DE, UK, NL, RO, HR, SE + EU-level + ESG). Covers company registration, ownership, financial filings, VAT status, ESG data. Use when the user asks to "look up a company", "check registry", "find company info", "look up IČO/KRS/LEI/CRN", "company due diligence", "check VAT status", "find ownership structure", or needs official data from European registries. Reads tracked companies from data/companies.json. Some lookups use Python scripts (stdlib), some fall back to Apify actors for scraping-based registries.