# Changelog of AI Brand Visibility Tracker: ChatGPT, Perplexity & Gemini (`tan_carrel_h1q/ai-search-brand-visibility-monitor`) Actor

- **URL**: https://apify.com/tan_carrel_h1q/ai-search-brand-visibility-monitor/changelog.md
- **Full Actor documentation**: https://apify.com/tan_carrel_h1q/ai-search-brand-visibility-monitor.md

## Changelog

### 0.2.0 – 2026-10-29

- **Run-over-run tracking (headline feature).** Each real run saves a compact snapshot in a named key-value store in the customer's own account (`ai-answer-scorecard-<brand>-<id>`, last 52 runs; input `trackingId` / `trackHistory`) and compares itself with the previous run: visibility %, share of voice, average position and cited-as-a-source %, overall, per engine and per prompt, plus competitor movement (share-of-voice change and places gained/lost, new and dropped competitors). Output: `SUMMARY.tracking` (deltas with ▲/▼ trend and "better" flag, `vsWeekAgo`, last-12-runs history), `previousVisibilityPct` and `changeVsPrevious` on every dataset row, and a trend section in `report.html` (change chips, four inline-SVG sparklines, history table). Tracking never fails a run.
- **Confidence range.** `visibilityRange` (95% Wilson interval) on every visibility figure; shown in the report when *Runs per prompt* > 1. A change whose range overlaps the previous run's is tagged "within noise".
- **Store daily-test fix.** A run that cannot do real checks (free plan on the built-in keys only, or no API key for any selected engine) no longer fails or returns an empty dataset: it makes no AI call, charges nothing, writes a non-empty clearly labelled DEMO dataset, summary and report (`summary.demo`, report banner, status message explaining how to get real results: paid plan or own keys) and exits successfully. Demo results are never written to tracking history.
- **Listing.** Title "AI Brand Visibility Tracker: ChatGPT, Perplexity & Gemini" (Apify caps titles at 63 characters; GEO/AEO is in the SEO title); product name "AI Answer Scorecard" in README and report; README rewritten (no H1, keywords + price first, question-style H3s, tracking, dated comparison, API and Apify MCP sections). Technical name unchanged.
- New inputs: `trackHistory` (default on), `trackingId`, `mockVariation` (demo only). New tests (tracking deltas, demo fallback, two consecutive runs).

### 0.1.2 – 2026-10-29

- **OpenAI answers now always use web search and return cited sources.** The first live run showed `gpt-4o-mini` skipping the optional search (`tool_choice: "auto"`), giving no citations. Requests now send `tool_choice: "required"` with the `web_search` tool (still `max_tool_calls: 1` for non-reasoning models, so exactly one search per check). Reasoning models (gpt-5 / o-series) use `search_context_size: "low"`. The `*-search-preview` models are shut down, so the Responses API tool is the supported route.
- `url_citation` annotations are parsed from all output messages (flat and nested forms), deduplicated, tracking params removed; search queries are read from `action.query` and `action.queries`.
- Cost per OpenAI check estimated at $0.0117 (71% margin on net at $0.05); cost model and PRICING.md compare the alternatives (gpt-5-mini, preview tool, gpt-5-search-api).
- 3 new tests (84 total).

### 0.1.1 – 2026-10-28

- **Free-plan users are blocked from the owner's built-in API keys** (previously a 6-check allowance was considered). Detection: `APIFY_USER_IS_PAYING === '1'` on the platform; a missing or other value counts as free. Free-plan users can run in mock mode or with their own keys (BYOK). If nothing is left to run, the Actor exits immediately and successfully with a clear "paid Apify plan required, or supply your own API keys" status message, writes an `ERRORS` record, makes no AI call and charges nothing. If the run mixes own-key and built-in-key engines, only the own-key engines run.
- Optional owner-only override `FREE_PLAN_OWNER_KEY_CHECK_LIMIT` (default 0) for testing from a free account.
- Input schema and README state the restriction up front.
- OpenAI spend-limit / prepaid-credit-exhausted 429 errors are treated as fatal for the engine (no pointless retries).

### 0.1.0 – 2026-10-28 (initial release candidate)

- Engines: OpenAI (Responses API + web search), Perplexity (Sonar via the Agent API), Google Gemini (optionally grounded with Google Search).
- Per engine × prompt × run dataset rows: brand mentioned, first-mention position, list rank, competitors with positions, cited URLs and domains, share of voice, sentiment snippet, raw answer, timestamp.
- Key-value store: `SUMMARY` (visibility %, share of voice, top cited domains, per-prompt matrix) and a self-contained `report.html`.
- Brand matching: case-insensitive, aliases, Unicode word boundaries, domain and URL matching, no matches inside longer words or other domains.
- Pay-per-event billing with three events (`prompt-check`, `grounded-gemini-check`, `byok-prompt-check`); stops gracefully at the user's maximum charge and never makes a paid AI call it cannot bill.
- Robustness: retries with exponential backoff and `Retry-After`, per-engine rate limiting, bounded concurrency, request timeouts, per-engine circuit breaker, clear errors for missing keys, run resume after a migration/restart.
- Bring-your-own-key (BYOK) inputs; custom models only with the user's own key.
- Mock mode (`mockMode: true`) – runs end to end with no keys and no cost.
- Known limitations: see the README ("Limitations").
