Immutable. This exact content is served forever at /api/v1/blob/574b9949e33efca9.
---
name: ai-citation-tracker
description: "Track brand mentions, URL citations, and share-of-voice across the 2026 AI search surface — ChatGPT (with browsing), Perplexity, Claude (with search), Google Gemini, Google AI Overviews, Bing Copilot, You.com, Phind, and Microsoft Copilot.."
version: "1.0.1"
category: analysis
platforms:
- CLAUDE_CODE
---
# AI Citation Tracker (the 2026 GEO measurement surface)
You build a multi-engine AI citation tracker. Modern SEO platforms still optimize for Google's blue links. Meanwhile, generative engines deliver 30%+ of informational answers without a click — and those engines DO cite sources, just not in a place Search Console can see. Your job is to make that surface measurable.
============================================================
=== PRE-FLIGHT ===
============================================================
- [ ] **Brand name(s)**: canonical + variants (e.g., "Stripe" + "stripe.com" + product names + key personnel).
- [ ] **Domain(s)**: your URL(s) to detect in citations.
- [ ] **Competitor list**: 5-15 brands you track share of voice against. Without competitors, you have a vanity-metric tracker.
- [ ] **Query universe**: 25-200 priority queries. From: GSC top queries, internal taxonomy, sales objection list, support tickets, customer interviews.
- [ ] **API access**: At least one of — OpenAI API (ChatGPT with browsing), Anthropic API (Claude), Perplexity API, Google AI Studio API (Gemini), Bing Custom Search. Without APIs, fall back to headless browser polling (slower, more brittle).
- [ ] **Storage**: SQLite for solo / Postgres for team / BigQuery for enterprise.
Recovery:
- No competitor list → auto-derive top 5 from cited URLs after 1 week of polling, then prompt user to confirm.
- No API keys → generate Playwright-based engine adapters that hit the consumer UIs (with explicit fragility warning + need-for-residential-proxy notice).
============================================================
=== PHASE 1: ENGINE ADAPTERS ===
============================================================
One adapter per engine. Each adapter answers: "given query Q, what answer was generated and which URLs were cited?"
```python
class EngineAdapter(Protocol):
name: str # "chatgpt" | "perplexity" | "claude" | "gemini" | "ai_overviews" | "bing_copilot"
async def query(self, query: str) -> EngineResult: ...
@dataclass
class EngineResult:
engine: str
query: str
asked_at: datetime
answer_text: str # the synthesized answer
citations: list[Citation] # ordered as cited
sources_attribution: str | None # raw sources HTML/markup if returned
raw_response: dict # for replay/debug
cost_usd: Decimal
@dataclass
class Citation:
rank: int # 1-indexed position in the answer
url: str
title: str | None
snippet: str | None
```
**Engine-specific notes**:
| Engine | Auth | Key URL | Cost ballpark | Notes |
|---|---|---|---|---|
| **ChatGPT (browsing)** | OpenAI API | `/v1/responses` w/ web_search_preview tool | $5-15 per 1k queries | Returns annotations[] with citation URLs |
| **Perplexity** | Perplexity API | `/chat/completions` with `model=sonar-pro` | $5/1M input + $15/1M output | Returns `citations` array natively |
| **Claude (with search)** | Anthropic API | `/v1/messages` w/ `tools=[web_search_20250305]` | $3/1M input + $15/1M output + $10 per 1k searches | Returns citations as part of content |
| **Gemini** | Google AI Studio API | `gemini-2.5-pro` w/ Google Search grounding | $1.25/1M + $5/1M | Returns grounding metadata with URLs |
| **AI Overviews** | SerpAPI / Bright Data SERP | n/a (no first-party API) | $5-20 per 1k queries | Scrape Google SERP, extract AI Overview block + sources |
| **Bing Copilot** | Bing Custom Search + Copilot scraper | n/a (no API) | $5-20 per 1k queries | Headless or SerpAPI |
| **You.com** | You.com API (free tier) | `/api/search` | Free / metered | Returns sources |
| **Phind** | scrape only | n/a | proxy cost | Headless |
VALIDATION: At least 3 engines wired and returning citations end-to-end against a smoke-test query.
FALLBACK: If an engine API is down/rate-limited, the polling job continues other engines + retries the failed one with exp backoff. Single-engine failure never blocks the run.
============================================================
=== PHASE 2: STORAGE SCHEMA ===
============================================================
SQLite/Postgres schema (Prisma-style):
```sql
CREATE TABLE Query (
id INTEGER PRIMARY KEY,
text TEXT NOT NULL UNIQUE,
intent TEXT, -- informational | commercial | transactional
priority INTEGER DEFAULT 5, -- 1=critical, 10=long-tail
added_at DATETIME
);
CREATE TABLE Brand (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL, -- canonical
aliases TEXT, -- JSON array
domain TEXT, -- if applicable
is_self BOOLEAN DEFAULT FALSE, -- our brand vs competitor
added_at DATETIME
);
CREATE TABLE Poll (
id INTEGER PRIMARY KEY,
query_id INTEGER REFERENCES Query(id),
engine TEXT NOT NULL,
polled_at DATETIME NOT NULL,
answer_text TEXT,
cost_usd DECIMAL,
raw_response JSON
);
CREATE TABLE Citation (
id INTEGER PRIMARY KEY,
poll_id INTEGER REFERENCES Poll(id),
rank INTEGER,
url TEXT NOT NULL,
domain TEXT, -- derived
title TEXT,
snippet TEXT,
brand_matched INTEGER REFERENCES Brand(id) -- nullable
);
CREATE TABLE BrandMention (
id INTEGER PRIMARY KEY,
poll_id INTEGER REFERENCES Poll(id),
brand_id INTEGER REFERENCES Brand(id),
mention_count INTEGER, -- in answer_text
cited BOOLEAN, -- did a URL of theirs appear in citations
sentiment REAL -- -1 to 1, optional
);
CREATE INDEX idx_poll_query_engine_date ON Poll(query_id, engine, polled_at DESC);
```
VALIDATION: Schema migrates cleanly. Sample query inserts + reads.
============================================================
=== PHASE 3: POLLING ENGINE ===
============================================================
Generate the polling worker (Python / Node). Schedule:
- **Daily**: top 25 queries × all engines (≈ $5-15/day for ~150 calls).
- **Weekly**: full universe (100-200 queries) × all engines.
- **On-demand**: ad-hoc query investigation.
For each poll:
1. Call engine adapter.
2. Persist `Poll` row + `Citation` rows.
3. Run brand-mention detection on `answer_text`:
- Match canonical + aliases (case-insensitive, word-boundary regex).
- Count occurrences.
- Optional: sentiment via small LLM call on the mention context.
4. Run domain-matching on citations against `Brand.domain`.
Rate-limit aware: respect each provider's RPM. Built-in token-bucket. Exponential backoff on 429.
VALIDATION: Daily run completes within window. Cost stays under budget (configurable, default $20/day cap).
============================================================
=== PHASE 4: METRICS & DELTAS ===
============================================================
Computed per (engine, query, week):
| Metric | Definition |
|---|---|
| **Cited** | Boolean — did our URL appear in citations? |
| **Mentioned** | Boolean — did our brand name appear in answer text? |
| **Citation rank** | If cited, what position (1 = first)? |
| **Share of voice** | (our brand mentions) / (total brand mentions in answer) |
| **Citation share** | (our citations) / (total citations) |
| **Competitor cited count** | Distinct competitor brands cited in answer |
| **Answer length** | Word count of synthesized answer |
| **WoW citation delta** | Cited this week minus cited last week, by query |
| **Top movers** | Queries with largest WoW citation gain/loss |
| **Citation gaps** | Queries where competitors are cited but you aren't |
| **Win-back queue** | Queries where you WERE cited 4 weeks ago but no longer are |
Persist daily; aggregate weekly. Generate `metrics_weekly.csv`.
VALIDATION: Metrics reconcile (per-query sums match aggregates). Weekly delta is non-empty after 2+ weeks of polling.
============================================================
=== PHASE 5: REPORTING ===
============================================================
Generate three reports:
**`weekly_report.md`** — for the team / boss:
- TL;DR: citations gained, lost, share-of-voice movement.
- Top 5 winners (queries newly citing you).
- Top 5 losers (queries no longer citing you).
- Top 5 citation gaps (where competitor X is cited 5+ engines, you're cited 0).
- Recommended content actions (per query, what to write/update to get cited).
**`competitor_matrix.csv`** — engine × competitor matrix of citations:
| Query | ChatGPT | Perplexity | Claude | Gemini | AI Overview | Bing Copilot |
|---|---|---|---|---|---|---|
| "best CRM" | Us, Hubspot, Salesforce | Hubspot, Salesforce | Us | Hubspot | Salesforce, Us | Hubspot |
**`citation_gap_actions.md`** — prescriptive:
For each citation gap, output: target query + which engines miss us + competitor URLs cited + a content brief stub (chain into `/seo-content-brief`).
VALIDATION: Reports render. CSV imports cleanly into Excel/Sheets.
============================================================
=== PHASE 6: ALERTING & DASHBOARD ===
============================================================
Push-style alerts:
- **Brand mention sentiment swing** (sentiment drops > 0.3 in any engine) → Slack/email.
- **Citation loss on top-10 query** → Slack/email same-day.
- **Competitor newly cited on tracked query** → daily digest.
- **Cost over budget** → throttle + alert.
Optional dashboard: Streamlit or Next.js + Prisma. Tabs: Overview, Per-Engine, Per-Query, Competitor Drill, Cost.
VALIDATION: Alerts fire on simulated event in test. Dashboard renders against the SQLite DB.
============================================================
=== PHASE 7: HOW THIS BEATS LEGACY SEO TOOLS ===
============================================================
| Capability | Semrush / Ahrefs | Visibly AI | This skill |
|---|---|---|---|
| Google rank tracking | ✅ | ✅ (via GSC) | (separate skill: gsc-pull) |
| AI Overview citation tracking | partial | ❌ | ✅ |
| ChatGPT citation tracking | ❌ | ❌ | ✅ |
| Perplexity citation tracking | ❌ | ❌ | ✅ |
| Claude / Gemini tracking | ❌ | ❌ | ✅ |
| Share-of-voice across all AI engines | ❌ | ❌ | ✅ |
| Citation-gap → content brief chain | ❌ | partial | ✅ (→ seo-content-brief) |
| Open data (your DB, no vendor lock) | ❌ | ❌ | ✅ |
| Composable with other agents | ❌ | partial | ✅ |
| Cost: per-month | $129-$499 | €39-€399 | API costs only (~$10-50/mo) |
VALIDATION: This positioning resonates with users who already pay for one of the above.
============================================================
=== SELF-REVIEW ===
============================================================
Score 1-5:
- **Complete**: 6+ engine adapters, schema, polling, metrics, reports, alerts?
- **Robust**: Single-engine failure doesn't break the pipeline? Rate-limit / budget controls?
- **Clean**: Citations dedupe? Brand matching handles aliases/case?
- **GEO-credible**: Would a CMO who's seen Visibly / Profound / Otterly / Brand24's AI module recognize this as production-grade?
Common gap: matching only canonical brand name, missing variants. Generate the alias seed list from the user's marketing site + Wikipedia + Crunchbase.
============================================================
=== LEARNINGS CAPTURE ===
============================================================
`~/.claude/skills/ai-citation-tracker/LEARNINGS.md`.
============================================================
=== STRICT RULES ===
============================================================
- Never poll without rate-limit / budget caps. AI engine APIs are billed; runaway loops are expensive.
- Never silently drop a failed engine. Surface the failure in the run report.
- Never use brand matching by canonical name alone. Aliases + variants are required.
- Always include competitor tracking. Share-of-voice without comparison is a vanity number.
- Always preserve raw_response. New citation patterns emerge; you'll want to replay.