Content Decay Audit - Google Search Console Traffic Drop
Pricing
$1.00 / 1,000 page analyzeds
Content Decay Audit - Google Search Console Traffic Drop
Content decay audit for Google Search Console: compare Pages exports (CSV, GSC ZIP, Excel or Google Sheets link, any language) and find pages losing traffic. Labels LOST, RANK_SLIP, DECAYING, CTR_DROP, ranked by clicks lost, with a content refresh plan. 25 pages free, then $0.001/page.
Pricing
$1.00 / 1,000 page analyzeds
Rating
0.0
(0)
Developer
Umair Saleem Mohammad Saleem
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
13 days ago
Last modified
Security
Limited permissionsShare
Content Decay Audit: Google Search Console Traffic Drop & Content Refresh Plan
Answer first: this actor is a content decay audit for Google Search Console. Give it two GSC Pages exports (previous vs current period) or one GSC compare export: pasted CSV, a public CSV link, the ZIP from "Download CSV", an Excel (.xlsx) export or a Google Sheets link (the Pages tab is found for you). It labels every page LOST, RANK_SLIP, DECAYING, CTR_DROP, STRIKING_DISTANCE, NEW, GROWING or STABLE, ranks pages by clicks lost and attaches a content refresh plan to the biggest losers. First 25 pages free every run, then $0.001 per page ($1 per 1,000 pages). No Google login, no API key, no crawl.
| Quick facts | |
|---|---|
| Best for | Content decay audits, "which pages lost Google traffic?", GSC traffic drop diagnosis, content refresh planning |
| Input | Two GSC Pages exports, or one compare export (both periods): pasted CSV, CSV link, GSC ZIP, Excel .xlsx or Google Sheets link. Any GSC language |
| Output | One row per page: status, clicksLost, click / impression / CTR / position changes, refreshPlan, merged URL variants, note when a row needs a manual check |
| Price | First 25 pages free every run, then $0.001 per page. No start fee |
| Needs | No Google login, no API key, no proxies |
| Not included | Live GSC API connection, query-level analysis, content rewriting |
Unlike dashboards that only show % change, it names the failure mode (lost vs rank slip vs CTR drop vs shrinking demand), so you know which kind of fix each page needs, and it merges URL variants (?srsltid=, utm_*, http/https, www, trailing slash) so one page is never split into several half-rows.
Sample output (real run, 20 Oct 2026)
Input: the public example.com sample CSVs below (11 current rows incl. a ?srsltid= variant and an http://www. variant, 9 previous rows). Output from build 0.1.9 (run bruD3Q2Ux8mFwEJlO, identical to the 0.1.8 run of 19 Oct), ranked by clicks lost:
| Page | Status | Clicks prev → now | Clicks % | Impr. % | Position prev → now |
|---|---|---|---|---|---|
| /seo-guide/ (2 URL variants merged) | DECAYING | 800 → 455 | -43.1% | -21.9% | 4.2 → 6.1 |
| /old-checklist/ | LOST | 120 → 0 | -100% | -100% | 5.5 → – |
| /keyword-research/ | CTR_DROP | 210 → 90 | -57.1% | -3.2% | 8.9 → 9.4 |
| /link-building/ | RANK_SLIP | 140 → 35 | -75% | -33.3% | 8.1 → 14.2 |
| /meta-descriptions/ | CTR_DROP | 190 → 95 | -50% | -3.1% | 3.7 → 3.9 |
| /local-seo/ | CTR_DROP | 70 → 18 | -74.3% | -17.4% | 6.9 → 7.2 |
| /schema-markup/ | STRIKING_DISTANCE | 55 → 60 | +9.1% | +8.3% | 12.1 → 11.8 |
| /new-ai-seo/ | NEW | 0 → 150 | – | – | – → 5.2 |
| /technical-seo/ | STABLE | 290 → 300 | +3.4% | +2.6% | 4.1 → 4.0 |
| /content-calendar/ (2 URL variants merged) | STABLE | 48 → 52 | +8.3% | +4% | 5.4 → 5.5 |
One full dataset row:
{"page": "https://example.com/seo-guide/","status": "DECAYING","clicksLost": 345,"clicksPrev": 800,"clicksNow": 455,"clickChangePct": -43.1,"impressionsPrev": 21000,"impressionsNow": 16400,"impressionChangePct": -21.9,"ctrPrev": 3.81,"ctrNow": 2.77,"positionPrev": 4.2,"positionNow": 6.1,"positionChange": 1.9,"mergedUrlVariants": ["https://example.com/seo-guide/","https://example.com/seo-guide?srsltid=AfmBOooX12"],"refreshPlan": ["Demand or coverage is shrinking: check if the topic moved to new queries in GSC","Re-target the page at the growing queries; update title/H1 and add an answer-first summary","Consider merging with an overlapping page"],"charged": false}
The SUMMARY record of the same run: pagesAnalyzed 10, pagesFree 10, pagesBilled 0, urlVariantsMerged 2, totalClicksPrev 1,923, totalClicksNow 1,255, totalClicksLost 837, byStatus {DECAYING 1, LOST 1, CTR_DROP 3, RANK_SLIP 1, STRIKING_DISTANCE 1, NEW 1, STABLE 2} and the topLosers list.
Try it yourself with the public sample CSVs (no Apify login needed to download):
- Current period: https://api.apify.com/v2/datasets/44dJteNosBdwBxz3f/items?format=csv
- Previous period: https://api.apify.com/v2/datasets/R3ZVEpeKr4XOj5kln/items?format=csv
How the labels work
| Status | Meaning | First fix |
|---|---|---|
| LOST | Had at least minPrevClicks clicks before, now zero or gone from the report | Check indexability, redirects, canonical |
| RANK_SLIP | Clicks down 30%+ and average position worse by 3+ | Compare with the current top 3, add what is missing |
| DECAYING | Clicks down 30%+ and impressions down 20%+ (demand or coverage shrinking) | Re-target growing queries, consider merging |
| CTR_DROP | Clicks down 30%+ while rankings and impressions held | Rewrite title and meta description, check new SERP features |
| STRIKING_DISTANCE | Position 8–20 with 100+ impressions | Expand content, add internal links |
| GROWING | Clicks up 20%+ | Leave it, learn from it |
| NEW | Only in the current period | – |
| STABLE | No action needed | – |
Thresholds match the code (minPrevClicks default 10; pages below it are only checked for striking distance, so noise does not flood the report). Label priority when several rules match: LOST → RANK_SLIP → DECAYING → CTR_DROP → STRIKING_DISTANCE → GROWING → NEW → STABLE.
Input
| Field | What to put in |
|---|---|
currentCsvText / currentCsvUrl | Search Console → Performance → Pages → Export, recent period. A compare export with both periods also works here |
previousCsvText / previousCsvUrl | The same export for the earlier period. Leave empty for a compare export |
normalizeUrls (default true) | Merge http/https, www, trailing-slash, #fragment and tracking-parameter variants of one page |
minPrevClicks (default 10) | Minimum previous-period clicks before a page can be called LOST / decaying |
maxRefreshPlans (default 25) | How many top losers get a refresh plan |
- A URL always wins over pasted text. What the URL can point to:
- a CSV (Dropbox, S3, any public link, an Apify dataset
?format=csv) - the ZIP that Search Console's Export → Download CSV gives you:
Pages.csvis picked out of it (Queries.csv comes first in that ZIP and is skipped) - an Excel .xlsx file (Download Excel): the
Pagessheet is used - a Google Sheets link (the
/editlink of a sheet shared as "Anyone with the link", or a Publish to web link): the whole workbook is read and the Pages tab is used, even if the link points at the Queries tab - Google Drive
/file/d/…/viewand Dropbox?dl=0share links are turned into direct downloads
- a CSV (Dropbox, S3, any public link, an Apify dataset
- Columns are detected automatically:
page/Top pages,clicks,impressions,CTR,position; comma, semicolon or tab separated, UTF-8 or UTF-16. - Search Console in another language? If the headers are not English (e.g.
Top-Seiten, Klicks, Impressionen…), the URL column is found from its values and the metrics are read in Search Console's fixed column order (5 columns, or 9 for a compare export). TheSUMMARYinputNotessay when this happened. - Decimal commas (a German or French Google Sheet:
6,1,2,8 %,1.234) are detected per file and read correctly (numberFormatinSUMMARY). - The 1,000-row limit: the Search Console UI exports at most 1,000 rows. If a file has exactly 1,000 rows,
SUMMARY.warningssays so, and pages that are LOST only because they are missing from the current file get anotewith the most clicks they could still have (the file's lowest row). - Compare exports: both "Last 3 months / Previous 3 months" columns and custom date-range columns (e.g.
10/1/25 - 12/31/25 Clicksvs7/1/25 - 9/30/25 Clicks) are recognised; the later range is treated as current. - Leave every CSV field empty to run the free built-in example.com demo. If you paste your own current CSV but leave the example previous CSV in the form, the run stops with a clear message instead of mixing demo data into your report (nothing is charged).
Pricing (pay per event)
| Pages in the report | You pay |
|---|---|
| First 25 pages every run | Free |
| 100 pages | $0.075 (75 × $0.001) |
| 500 pages | $0.475 |
| 1,000 pages (a full GSC UI export) | $0.975 |
| 5,000 pages | $4.975 |
- Event:
page-analyzed, $0.001 per page after the free 25. Refresh plans are included. No start fee. - Failed runs stop before any charge, with a message that says what to export instead: empty or unreadable file, a web page instead of a CSV (a private Sheet or a share page), the Queries / Countries / Dates table instead of Pages, or an old
.xlsfile. - Set a maximum total charge in the run options: the actor stops adding rows at your limit, so you never pay for rows you did not get.
- Compute is a CSV parse only (seconds, 512 MB default memory). For very large API exports (50,000+ rows) raise memory to 1 GB.
How it compares (live Apify Store data, verified 20 Oct 2026)
Free-plan list prices and "monthly users" read from the Apify Store API on 20 October 2026.
| Actor | What you get | Price | ~1,000 pages | Monthly users |
|---|---|---|---|---|
| cygnix_labs/content-decay-audit (this) | GSC CSV compare → status label + refresh plan, URL variants merged | $0.001 / page, first 25 free, no start fee | ~$0.98 | 1 |
| junipr/content-decay-signal-auditor | Crawl + decay signals + recommendations | $0.0115 / page + $0.0115 / signal + $0.0115 / recommendation + $0.035 start ($0.40 executive report) | $11.50+ | 1 |
| kuantum/seo-decay-radar | Content monitoring observations | $0.015 / result | ~$15 | 0 |
| sprightly_blackberry/content-portfolio-audit | Site content → refresh plan report | $1 / report | Per report, not per page | 1 |
| siteverdict/siteverdict-gsc-ga4-analyst | Live GSC + GA4 property analysis | $0.35 / property + $0.005 / URL inspected | Different job (API connection) | 1 |
| datascoutapi/google-search-console-mcp | Live GSC data via MCP | $0.005 / result (Free plan) + $0.001 start | ~$5 per 1,000 results | 3 |
| scrapeai/google-search-console | Live GSC query rows (needs your Google auth) | $0.00249 / result | ~$2.49 per 1,000 rows | 1 |
| alizarin_refrigerator-owner/gsc-data-analyzer | General AI GSC insights | $0.10 start + $0.08 / analysis + $0.01 / opportunity + $0.03 / AI insight | Not page-level rows | 0 |
Honest take. For "which pages are losing clicks and why", this is roughly 10x cheaper than the other page-level decay tools. It works from exports you provide; if you want an actor that connects to the live GSC API for you, siteverdict or the datascoutapi MCP do that. Monthly-user counts are small across this whole niche, ours included.
For AI agents / MCP
When an agent should call this actor: the user asks which pages are losing Google traffic, about content decay, a traffic drop in Search Console, or which old posts to refresh first, and can share GSC Pages exports (CSV text or links).
Connect the Apify MCP server with only this actor enabled (Claude, ChatGPT, Cursor, VS Code, Codex or any MCP client):
https://mcp.apify.com?tools=cygnix_labs/content-decay-audit
Or find it with search-actors using keywords such as content decay, Search Console, traffic drop, content refresh.
Example call-actor input (these sample URLs are public and work as-is):
{"currentCsvUrl": "https://api.apify.com/v2/datasets/44dJteNosBdwBxz3f/items?format=csv","previousCsvUrl": "https://api.apify.com/v2/datasets/R3ZVEpeKr4XOj5kln/items?format=csv","minPrevClicks": 10,"maxRefreshPlans": 10}
What to read from the result: dataset rows are sorted by clicksLost; read page, status, clicksLost, clickChangePct, positionPrev → positionNow and refreshPlan. The SUMMARY record gives totalClicksLost, byStatus, topLosers and pagesBilled. Use currentCsvText / previousCsvText to paste CSV inline, or pass a public CSV / GSC ZIP / .xlsx / Google Sheets link in currentCsvUrl. On a failed run, statusMessage tells you which export to ask the user for.
Cost control for agents: 25 pages or fewer are free; a full 1,000-row GSC export costs under $1. Pass maxTotalChargeUsd in callOptions for a hard cap. Pay-per-event, so it also works with Apify agentic payments.
Example prompt: "Compare my last 3 months vs the previous 3 months of GSC pages and give me a refresh plan for the 10 pages that lost the most clicks."
FAQ
What is content decay? A page that used to earn steady search traffic and is now losing clicks, because rankings slipped, the SERP changed (lower CTR) or demand for the topic shrank. This actor separates those causes because each needs a different fix.
Which periods should I compare? Last 3 months vs the previous 3 months, or year over year for seasonal sites. In Search Console use Date → Compare, then export Pages.
Do I need a Google login or API key? No. Export from Search Console → Performance → Pages and paste the CSV or give a public link (CSV, the ZIP, an .xlsx or a Google Sheet).
Can I give it the ZIP from "Download CSV" as it is? Yes. Put its public URL in currentCsvUrl (for a compare export, that's the only field you need). Pages.csv is picked from the ZIP and SUMMARY.inputNotes says which file was used.
I exported to Google Sheets. Which link do I use? Share the sheet as "Anyone with the link can view" and paste the normal /edit link. The actor downloads the workbook and uses the Pages tab. A private sheet fails with a clear message and no charge.
My run failed with "this is the Search Console Queries export". You gave the Queries tab. Content decay works per page: open the Pages tab in Performance, then Export.
My Search Console is in German / Spanish / Japanese. Does it work? Yes. Headers in any language are handled by column order, and decimal-comma numbers (6,1) are read as 6.1. Check SUMMARY.inputNotes.
Why does a LOST page have a note? Your current file has exactly 1,000 rows, the Search Console UI export limit. A page missing from it may sit just below the cutoff instead of being gone, so check it in GSC (or export through the API / Looker Studio).
Why are my URLs merged? Google often reports the same page as several URLs (?srsltid= from Merchant Center, utm_ links, http vs https, www, trailing slash). Clicks and impressions are summed, position is impression-weighted and the variants are listed in mergedUrlVariants. Set normalizeUrls to false to keep every URL separate.
Why are some low-traffic pages STABLE? Pages below minPrevClicks previous clicks (default 10) are only checked for striking distance.
Does it rewrite content? No. It tells you what to fix and in what order. Pair it with Keyword Clusterer + Content Brief for briefs.
Can I cap spend? Yes: set a maximum total charge in the run options. Rows stop at the limit.
Integrations
Run it via the Apify API, schedule it weekly or monthly, or send results to Google Sheets, Make, Zapier, n8n, Slack or webhooks.
Changelog
- 0.1.9 / 0.1.10 (2026-10-20): Bug fixes: (1) The ZIP from Search Console's Download CSV and Excel .xlsx exports could not be read: the run failed with a misleading "Provide the previous-period CSV" error. They are now read directly (Pages.csv / Pages sheet). (2) A Queries, Countries or Dates table instead of Pages finished as a "successful" run with 0 rows. It now fails with a message saying which export to use (no charge). (3) Decimal-comma numbers were misread: position
8,8became 88 and clicks1.144became 1, which mislabeled pages as CTR_DROP or RANK_SLIP. They're now detected per file. (4) Non-English headers (e.g.Top-Seiten, Klicks) gave 0 rows. They're now mapped by Search Console column order. New: Google Sheets / Drive / Dropbox share links become direct downloads; a web page instead of a CSV fails with a clear message; a 1,000-row (UI limit) warning plus anoteon LOST rows that may just be below the cutoff;SUMMARY.inputNotes,warnings,numberFormat. Results for normal English CSVs are unchanged (sample identical). Price unchanged. - 0.1.7 / 0.1.8 (2026-10-19): Bug fix: CSV URLs were ignored when the text fields kept their default demo data, so API and MCP calls with
currentCsvUrl/previousCsvUrlreturned the example.com demo. URLs now always win, and a leftover demo CSV next to your own data stops the run (no charge). New: URL-variant merging (normalizeUrls), duplicate rows summed instead of overwritten, custom date-range compare exports,ctrPrev/ctrNow,chargedflag per row, richerSUMMARY(topLosers, free vs billed, rows read).minPrevClicks: 0no longer marks zero-click pages as LOST. Rows are written in batches (lower memory) and theSUMMARYfree/billed counts match the real charged events. Default memory 1024 → 512 MB. Price unchanged. - 0.1.6 (2026-10-18): README rewritten answer-first, comparison verified 18 Oct, agent section.
- 0.1.1 (2026-10-16): Store comps, cost table.
More SEO and AEO tools by Cygnix Labs
- Website SEO Audit + AEO/GEO Checker (full-site crawl)
- AEO & GEO Audit + llms.txt Checker (URL list)
- Internal Link Audit & Orphan Page Finder
- Keyword Cannibalization Checker (Search Console)
- Keyword Clustering + Content Briefs
- Search Intent Classifier
- Website Tech Stack Detector
- Free local SEO MCP server: cygnix-seo-mcp (
npx -y cygnix-seo-mcp)
Questions or a feature request? Open an issue on this actor's Issues tab.