AI Answer Change Alert
Pricing
Pay per event
AI Answer Change Alert
Track whether an AI assistant's answer to a query you care about changed since last time — new sources cited, old ones dropped, or the answer rewritten. Grounded via Perplexity Sonar, GPT or Gemini, no API key needed. A scheduled diff, not a one-shot snapshot.
AI Answer Change Alert — Did the AI's Answer About Your Market Just Change?
Ask Perplexity or ChatGPT "best crm for small business" today, and it cites five sources. Ask again next week and the wording might be rewritten, a competitor might get cited for the first time, or a source that used to show up might be gone. This Actor remembers what the answer looked like last time you ran it and tells you exactly what's different — new domains cited, old ones dropped, or the answer simply rewritten — so you don't have to read the whole thing again to notice.
What you get
- A diff, not a snapshot. Every run compares against the answer this Actor saved for you the last time you checked the same query × model × language — not just a one-off citation list.
changeTypetells you what kind of change it was:new-domains(a source got cited that wasn't before),lost-domains(one dropped out),answer-rewritten(the wording changed but the cited domains stayed the same), ornone.- Works out of the box — no API key needed. LLM access is built in and covered by the per-row price. Prefer your own OpenRouter key? Pass it and the tokens bill to your account at cost instead, nothing marked up.
- Any language. Set
langand the grounded model answers natively. - One row per check, in the normal case. Every completed query × model check produces
one dataset row — filter
changedyourself (in the dataset view, via the API, or downstream) if you only want to see what moved on a scheduled run. On the rare occasion this Actor's own storage hiccups right after a billed check, a second, unbilled follow-up row can be delivered to warn you about it (seebaselineWriteErrorbelow) — that row is never a duplicate charge, just a free warning tied to the check right before it. - Runs on Apify: schedule it daily or weekly, monitor it, call it from the API or the MCP server, export to JSON/CSV/Excel, or push straight into your own pipeline.
How to run it
- Click Try for free — no card needed on the free plan.
- Paste your queries into Queries and, optionally, extra models into Models. No API key needed.
- Press Start. The first run for each query × model creates a baseline (
found: true,baselineCreated: true) — there's nothing to compare against yet, sochangedisfalse. Schedule the same input to run again later (daily/weekly) and every row after that compares against what was saved last time.
Pricing
Pay-per-event: $0.005 per GB of memory at run start + $0.05 per query × model check. Apify charges the start event once per GB of allocated memory (minimum one), so a default 4 GB run starts at $0.020. A "check" means a completed LLM call, whether the answer changed or not — the first run that creates a baseline for a query is billed exactly the same as every run after it, because the model was actually called and the citations were actually parsed either way. The per-check price covers the grounded-search model call itself: you do not need an OpenRouter account, and if you supply your own key the tokens go to your account instead. 20 checks (e.g. 20 queries against 1 model) ≈ 0.020 + 20 × 0.05 = $1.02. The most a single run can charge is the schema maximum, 20 queries × 3 models = 60 checks ≈ $3.02, no matter how large you set the fields.
Rows where the LLM call itself failed, or where this Actor's own baseline lookup failed
(found: false, with an error), are always returned for transparency and are never
charged — this Actor checks its own deployed pricing at the start of every run and refuses
to proceed (with a loud error, no paid work) if the platform ever charges anything for a
plain dataset write on top of the two named events above, so the "never charged" and the
"$1.81 maximum" claims above hold by construction, not by assumption.
Pass your own openrouterApiKey and the LLM tokens bill to your OpenRouter account instead,
at cost — the Actor's row price stays the same either way.
Input
| Field | Required | What it does |
|---|---|---|
queries | yes | Prompts a real buyer would ask. Up to 20 per run. Each is checked against every model in models and compared against its own stored baseline. |
models | no | OpenRouter model IDs to check — grounded options: perplexity/sonar, openai/gpt-4o-mini:online, google/gemini-2.0-flash-001:online. Up to 3 per run. Default ["perplexity/sonar"]. |
lang | no | Answer language, e.g. en, ru, tr. Default en. |
openrouterApiKey | no | Optional. Leave empty to use the built-in LLM access (included in the row price). Pass your own OpenRouter key to have tokens billed to your account instead. |
maxConcurrency | no | Parallel LLM calls, 1–3 (default 1), kept low to respect rate limits and to bound how many LLM calls can be wasted if a run's spend limit is hit mid-run. |
{"queries": ["best crm for small business"],"models": ["perplexity/sonar"],"lang": "en"}
Output
One row per query × model pair, compared against the baseline this Actor saved last time.
Both rows below are real — the first is what a first-ever check for this query looks like,
the second is the same query checked again minutes later, where the model rewrote its
answer without changing which domains it cited:
First check — no baseline existed yet:
{"query": "best crm for small business","model": "perplexity/sonar","lang": "en","found": true,"changed": false,"baselineCreated": true,"changeType": "none","citedDomains": ["fayedigital.com", "fitsmallbusiness.com", "pcmag.com", "techradar.com", "zapier.com"],"addedDomains": [],"removedDomains": [],"answerSnippet": "The **best CRM for a small business** depends on what you need most, but **Bigin by Zoho CRM** is ranked **best overall** by PCMag for 2026, while **HubSpot CRM** is also widely recommended as a strong all-around option for small teams.[1][4]\n\nIf you want the quickest recommendat","previousCheckedAt": null,"baselineWriteError": null,"summary": "perplexity/sonar on \"best crm for small business\": first check — baseline created, 5 domain(s) cited.","checkedAt": "2026-07-28T19:20:15.000Z"}
Same query, checked again — answer rewritten, same 5 domains still cited (citedDomains is always sorted, so an identical set always serializes identically):
{"query": "best crm for small business","model": "perplexity/sonar","lang": "en","found": true,"changed": true,"baselineCreated": false,"changeType": "answer-rewritten","citedDomains": ["fayedigital.com", "fitsmallbusiness.com", "pcmag.com", "techradar.com", "zapier.com"],"addedDomains": [],"removedDomains": [],"answerSnippet": "The **best CRM for a small business depends on your priority**, but the strongest all-around picks in current reviews are **HubSpot CRM** and **Bigin by Zoho CRM**.[1][4] If you want the simplest answer: choose **HubSpot CRM** for the best overall small-business experience, or **","previousCheckedAt": "2026-07-28T19:20:15.000Z","baselineWriteError": null,"summary": "perplexity/sonar on \"best crm for small business\": answer changed (answer-rewritten) — +0/-0 domain(s) vs 2026-07-28T19:20:15.000Z.","checkedAt": "2026-07-28T19:24:46.330Z"}
| Field | What it means |
|---|---|
query / model / lang | Echo of the input for this row |
found | Whether the LLM check succeeded |
changed | Whether the answer differs from the stored baseline |
baselineCreated | true the first time this query × model × lang is checked — nothing to compare against yet |
changeType | none, new-domains, lost-domains, or answer-rewritten |
citedDomains | The domains this run's answer is grounded in |
addedDomains / removedDomains | Domains that appeared / disappeared versus the stored baseline |
answerSnippet | First 280 characters of the model's current answer |
previousCheckedAt | Timestamp of the run this one was compared against, or null on a first check |
summary | Human-readable one-line summary of the change |
baselineWriteError | Normally null. On a rare storage hiccup right after a billed check, saving the new baseline for next time can fail — this is retried a few times automatically before being treated as a real failure. The originally billed row is always delivered as usual (never withheld over this); if saving still fails after retries, a second, unbilled follow-up row with this field populated is delivered right after, warning that the next run's comparison may repeat (and re-charge for) the same change until the baseline saves successfully |
found: false | The LLM call failed, or this Actor's own lookup of your stored baseline failed — same shape with an error field, no charge either way. A baseline-lookup failure is deliberately never treated as "no baseline yet": if it were, and this check then created a fresh baseline over a real one that this Actor simply couldn't read at that moment, whatever change your real baseline was tracking would be lost permanently the next time it compared successfully. |
Need the rest of the picture?
These run on the same account, take the same shape of input and bill the same way, so they slot into an existing pipeline without new plumbing.
| Actor | What it does |
|---|---|
| AI Crawler Access Checker | Check which AI crawlers (GPTBot, ClaudeBot, PerplexityBot, Google-Extended & more) can access your website |
| AI Overview Citation Tracker | For each query that matters, see which sources and domains AI assistants cite in their answer — grounded… |
| B2B Lead Enricher | Turn a list of company websites into sales-qualified lead cards: detected tech stack, a rough revenue… |
| Chotot Vietnam Listings Scraper | Pull live classified ad listings (real estate, vehicles, electronics, jobs and more) straight from… |
| Clinical Trials Monitor | Watch conditions, drugs or sponsors for new and updated clinical trials |
FAQ
Do I need an API key? No — it works out of the box, LLM access is built in and covered by the row price. Passing your own OpenRouter key is optional.
Why was I charged for a run where nothing changed? The Actor still had to call the model and parse its citations to know nothing changed — that work is what you're paying for, not just the alert. This applies to the very first run too (it creates the baseline).
What this is NOT. It is not a general web-search monitor — it only tracks what a
grounded LLM answers and cites for the exact query you give it, which can itself shift
run to run for reasons unrelated to the underlying sources (the model rephrasing itself).
It does not trust an ungrounded model's citations either: an ungrounded model will simply
produce a thinner citedDomains list scraped from its own text.
Known limitation: overlapping runs on the same queries can still double-bill, rarely.
Comparisons against the stored baseline are fully serialized only within a single run.
Across two overlapping runs (a schedule landing on top of a manual run, or two runs started
close together) this Actor takes out a short best-effort lease per query × model × language
before checking it, and skips (for free, no LLM call) any pair another run's lease still
covers — this closes the common case, and that skipped check costs nothing. But Apify's
key-value store has no atomic compare-and-swap, so if two runs check the lease at close
enough to the same instant, BOTH can find it clear and both proceed — there is no
storage-level fix for that available here. When this Actor detects an existing lease for a
pair (even a stale one from a crashed run) it flags the resulting row with
concurrentRunSeen: true in the dataset (not just the raw JSON), so a near-miss is visible.
The tightest possible race — two checks starting at almost the exact same moment, neither
ever seeing the other's lease — leaves no trace on either row; only a duplicate charge and
two identical changed: true rows for the same query/model/lang would reveal it. Running
one schedule per query set at a time avoids the situation entirely.
Why did my run FAIL instead of complete? In the rare case where this Actor cannot even
manage to warn you about a storage problem after retrying (see baselineWriteError above),
it deliberately crashes the run instead of quietly reporting success — a check you were
billed for must never disappear into a log line nobody reads. If you see a FAILED run, check
the run log; retrying the schedule normally resolves it once the underlying storage hiccup
clears.
Found a wrong result, or need a model we don't list? Open an issue on this Actor's page.