Monthly keyword cannibalization audit into Asana

First Monday each month, find queries where two or more of your own pages compete in Google search, and file ready-to-action consolidation tasks in Asana.

Agentic Task
Google Search ConsoleAsanaMarketingResearch & MonitoringAI Reports

On the first Monday of every month at 9am in my local timezone, run a keyword cannibalization audit against my Google Search Console property and file consolidation tasks in Asana, one per real conflict, so the SEO team has a ready-to-action queue instead of a raw report.

Inputs I want to configure once: the Search Console property (URL-prefix or sc-domain form, use the exact value returned by List Sites), the Asana workspace and the project where tasks should land, a short list of brand terms and product names to exclude, and an optional default assignee for the created tasks.

Pull the data from Google Search Console using Search Analytics Query over the last 90 full days (account for the 2 to 3 day data lag), grouped by query and page together, with searchType web, dataState all, and rowLimit 25000 paginated via startRow until the rows array comes back smaller than the limit. Use the data to build, for each query, the set of URLs that ranked for it with their clicks, impressions, CTR, and average position.

Flag a query as a real cannibalization conflict only when ALL of these are true: two or more of my URLs each have at least a meaningful share of the query's impressions (default: each competing URL has at least 100 impressions and at least 10 percent of the query's total impressions), the average positions of the top two URLs are within 3 of each other, no single URL already owns more than 80 percent of the clicks for that query, and the query does not contain any of my brand or product terms. These thresholds should be easy to edit at the top of the agent's instructions.

For each conflict, pick a recommended canonical winner. Score URLs by traffic share (clicks first, then impressions as a tiebreaker), better average position, and clearer intent fit based on the URL path and any title signal you can infer. Optionally call Inspect URL on the top two competing URLs to confirm their Google-selected canonical and indexing state, and use that to back the recommendation. Then choose a recommended action from: consolidate the losing page into the winner, set up a 301 redirect from loser to winner, rework internal links to point at the winner, or noindex the loser. Pick the action that best fits the situation and explain why in one sentence.

For every flagged conflict, call Asana Create a Task in the configured project. The task title should be: Cannibalization: "<query>". The notes (description) should include the recommended winner URL, the loser URLs, each URL's clicks, impressions, CTR, and average position over the last 90 days, the impression and click split, a severity tag (High when position difference is under 3 and the impression ratio is above 0.5, otherwise Medium), the recommended action with a one-sentence rationale, and the indexed canonical from URL Inspection if available. If a default assignee is configured, set it. Use the project gid from the configured Asana project and pass it in the projects array on the request body. Include opt_fields=name,permalink_url so I can log a link back to the created task.

Sort conflicts by severity then total impressions so the highest-impact tasks land first in the project. To stay polite with Asana's rate limit and avoid flooding the project, cap the run at the top 25 conflicts by default and make that cap configurable.

Before creating any tasks, de-duplicate against the last run: if a task with the same query title already exists in the project and is still open, skip creating a new one and instead add a brief comment noting the latest impression and click numbers so we do not pile up duplicates month over month.

At the end of the run, return a short summary: how many queries were scanned, how many conflicts passed the filter, how many Asana tasks were created versus updated via comment, and the top 3 highest-severity conflicts inline.

Additional information

What does this prompt do?
  • Pulls the last 90 days of Google Search Console data and finds queries where two or more of your own URLs are ranking against each other.
  • Filters out noise so you only see real conflicts, not coincidences. Branded queries and lopsided splits where one URL already dominates get skipped.
  • Picks a recommended winner page for each conflict based on traffic share, average position, and intent fit, and suggests an action: consolidate, redirect, rework internal links, or noindex.
  • Creates one Asana task per conflict in the project you choose, with the query in the title and the winner, losers, traffic splits, and recommended action in the description.
What do I need to use this?
  • A Google account with verified access to the Search Console property you want to audit.
  • An Asana workspace and a project where the consolidation tasks should land.
  • A rough list of your brand terms so they can be excluded from the audit.
How can I customize it?
  • Change the schedule. Weekly, biweekly, or quarterly all work if monthly is too noisy or not noisy enough.
  • Tune the conflict threshold. The default flags conflicts when positions are close and impressions are reasonably split. You can tighten this to only catch severe cases, or loosen it to surface more candidates.
  • Swap the Asana destination. Point the tasks at a different project, add a section, set an assignee, or apply tags so the queue fits your team's existing workflow.

Frequently asked questions

What counts as keyword cannibalization?
Two or more pages on your site compete for the same query in Google. Both earn impressions, their average positions are close, and neither clearly wins. The result is that you split clicks, confuse Google about which page to rank, and underperform what a single consolidated page could do.
Will this catch every shared-URL query?
No, and that is the point. Lots of queries naturally pull multiple URLs without any of them actually competing. This audit only flags conflicts where both pages have meaningful traffic and their positions are close enough that one is cannibalizing the other.
How are branded queries handled?
You give the workflow a short list of your brand terms and product names, and any query containing those words is skipped. Branded queries almost always pull multiple pages from your own site by design, so including them would drown the real signal.
What goes into the Asana task?
Each task has the cannibalized query as the title and a description with the recommended winner URL, the losing URLs, the click and impression split for each page, and a suggested action like consolidate, set up a 301 redirect, rework internal links, or noindex.
Why monthly instead of weekly?
Cannibalization patterns shift slowly and Search Console data lags a few days. A monthly cadence gives you enough new signal to act on without flooding your Asana project. If you publish a lot of content, weekly or biweekly is easy to switch to.
Does this work if I am on Asana Free?
Yes. The workflow only creates tasks, which all Asana plans support. Premium features like the search API are not required.

Stop letting your own pages compete with each other.

Connect Google Search Console and Asana once, and Geni delivers a clean queue of consolidation tasks on the first Monday of every month.