Keyword Cannibalization Checker: Find Your Competing Pages
Check keyword cannibalization with a site-restricted Google search, your own tags and ranked-keyword data, one call per concept, from your agent.

Find out which of your own pages compete for the same search. Paste this into your agent:
Set up https://monid.ai/SKILL.md, and then use Monid to run the Google search "site:monid.ai mcp gateway", list which monid.ai URLs come back in order, and tell me which of them look like they answer the same question.
One prompt runs the check and reads the list. 1 min setup · 3-10 hrs saved.
You have a site with a lot of pages and you suspect that several of them chase the same query. A keyword cannibalization checker answers one question: for this concept, which of my pages does Google pick, and how many are in the running? This guide shows the quickest way to ask that from your agent, what the calls return (we ran each endpoint on 2026-10-16, on our own site), and where the result misleads you. It runs through Monid, the OpenRouter for agent tools: one key, one balance, every tool priced per call.
What is the easiest way to check keyword cannibalization with an API?
Monid. Install it once, add a key, and your agent runs a site-restricted Google search for each concept you care about and lists your own URLs in the order Google returns them. There is no endpoint with "cannibalization" in its name, and none is needed, because the check is a search plus a count.
- Pay per call. One concept is one call. The Google results endpoint costs $0.001 a call (Verified 2026-10-16 on the search tools page). Buy calls as you need them: no monthly plan and no minimum top-up. Discovery and inspection are free; only a run bills.
- One install, every tool. The same key and balance call the search endpoint, a site mapper, and ranked-keyword data from an SEO suite. A twenty-concept audit is twenty calls.
- Lives inside your agent. Your agent reads
SKILL.md, learns the discover, inspect and run steps, and has the tools whenever you ask for a check, with nothing to keep running. Setup takes about a minute.
How do you check keyword cannibalization on your own site?
Search Google for your concept with a site: restriction, then count the URLs of yours that come back. One or two means a topic. Three or more for the same intent means Google is choosing between your pages, and the choice is the harm. There are three passes, and the first one costs nothing. The SERP API guide covers what else the same endpoint returns.
For agents
Grab an API key at app.monid.ai, then paste this to your agent and hand it the key:
set up https://monid.ai/SKILL.md
It learns the whole discover, inspect, run workflow itself. More in the agent quickstart.
For humans
npm install -g @monid-ai/cli
monid keys add -k <your-api-key> -l main
Pass one: shortlist the concepts from your own files
Every post carries tags. Compare them pairwise and count the overlap. The pairs that share two or more tags are where to spend your calls.
pairs = [(a, b, shared) for a, b in combinations(posts, 2)
if len(shared := set(a.tags) & set(b.tags)) >= 2]
Sort by overlap size. The top of that list is your call budget for pass two. It is a structural smell, not proof: two pages can share tags and answer different questions.
Pass two: one site-restricted search per concept
monid run -p mrscraper -e /serp/google \
--query '{"query": "site:monid.ai mcp gateway", "region": "us", "language": "en"}'
The endpoint takes query, region, language and an optional page. Record which of your URLs come back and in what order. One call per concept, not per page.
Pass three, optional: the unrestricted query
Run the same concept without site:. This tells you whether any of your pages ranks at all, which is a separate question from whether they compete.
monid run -p mrscraper -e /serp/google \
--query '{"query": "mcp gateway", "region": "us", "language": "en"}'
Or hand the whole job to an agent
Give this to your agent![]()
Set up https://monid.ai/SKILL.md, and then use Monid to for each of these concepts, run a site-restricted google search on our domain, list which of our URLs come back in order, and flag any concept where three or more of our own pages appear.Can you check keyword cannibalization for free with Python?
Yes, for a small site, and part of it needs no search at all. The tag scan above is free Python on your own files. Typing site:yourdomain.com and your concept into Google by hand is free too, and for five concepts it takes ten minutes. Google Search Console is the other free source: it lists the queries your property appeared for and the pages that were shown, so a query with two or more of your pages in the list is a candidate.
The limits show up as the list grows. By hand, twenty concepts is twenty tabs, a copy-paste of every result and no record of what the order was last month. Scraping Google results in code means proxies, a parser that breaks when the page layout changes, and a way to handle a block page when it arrives. Search Console reports your own history but not what Google would return for a concept you have never ranked for, and it has no site: view.
The Monid route trades that upkeep for a flat call price: the results come back as JSON with rank and global_rank on every row, and the layout changes are the provider's problem. If the free route is what you want for page text rather than rankings, free web search APIs for agents lists what is on offer.
📖 See also Automate SERP tracking
What does a cannibalization check return, and what can you build?
The search endpoint returns the Google page as JSON, and the part you read is a list of your own URLs with a position on each. We ran it on 2026-10-16 for site:monid.ai mcp gateway, a concept our blog covers, so the fields and counts below are what came back.
The site-restricted result
The response had 10 organic rows, all on monid.ai, each with link, source, display_link, title, description, icon, rank and global_rank (1 to 10). A lighter results list repeated the same links with a relevance label, and pagination listed pages 2 to 4. The rows were not all articles:
1 blog/guides/llm-gateway-vs-mcp-gateway
2 blog/guides/what-is-an-mcp-gateway
3 blog/page/5 (the blog listing)
4 /openrouter-for-agent-tools (product page)
5 blog/claude-for-seo-and-geo
6 /grok-bot (product page)
7 blog/guides/openrouter-mcp-server-tool-layer
8 /amazon-research (product page)
9 /tools/decision-models (tools page)
10 blog/guides/openrouter-alternatives-after-stripe
Four guides, one other blog post, one listing page, three product pages and one tools page. The count that matters is not ten. It is the four guides, plus the product page at position 4 that carries the same sentence about gateways.
The unrestricted result
The same concept without site: returned 8 organic rows, none on monid.ai, four People Also Ask questions and an ai_mode object with a summary text, one citation and two sections. So on the day we ran it, the concept had several of our pages in competition on our own domain and none of them on page one of the open search. Those are separate findings and the list in the previous section only shows the first.
The site map and the ranked keywords
Two other endpoints add context. firecrawl/map with url set to https://monid.ai, search set to gateway and limit 50 returned 47 links for one flat call, each with a url, a title and a description. The first nine were gateway pages; the other 38 had nothing to do with gateways, so the search term ranks pages rather than filtering them out.
ahrefs/site-explorer/organic-keywords returns one row per keyword with keyword, best_position, best_position_url, volume, sum_traffic and cpc. We asked for the top two rows by volume for monid.ai in the US: food barcode lookup at position 5 on one guide, volume 10, and gated email verification at position 9 on /blog, volume 0.
What to build with it
- A concept audit. Keep a list of the concepts you want to own and run one site-restricted search for each. Store the ordered URLs with the date, and the next run shows what moved. Rank tracking: store the position, not the page shows the table to keep.
- A keep-or-merge table. For every concept with three or more URLs, write the one-sentence job of each page. If two jobs read the same, those two are the merge candidates, and the one that holds the links stays.
- A monthly recheck. The call is cheap enough to repeat. Run the same list after you retitle or merge, and the order tells you whether Google changed its choice.
What goes wrong when you check keyword cannibalization?
Four things showed up in our runs or follow from the response shape.
Why are listing and product pages in the count?
Because site: returns every page of the site that matches, not only articles. Our list had a blog listing page at position 3 and three product pages. Two of those product pages carried the same gateway sentence in their description as our guide. Filter the rows by path before you count: a product page ranking next to a guide is not the same problem as two guides, and blog/page/5 is not a page you would ever merge.
Why does the count change between runs?
Because a results page holds whatever Google rendered. The site-restricted search returned 10 rows and the unrestricted one returned 8. Our own earlier audit of the same concept, run on 2026-09-23, found different pages, so a single run is a sample. Run the check on the same list at a fixed interval and compare like with like.
Why can ranked-keyword data not show two pages on one keyword?
Because organic-keywords returns one best_position_url per keyword row. Two of your pages trading places on one query is the classic cannibalization signal, and a one-URL-per-keyword table hides it unless you pull rows for several dates and compare. The site-restricted search shows the competition directly, at the price of not showing history.
Why is cannibalization not the same as not ranking?
Because the two are separate measurements. A concept can have four of your pages in the site-restricted list and none on page one of the open search, which is what the gateway concept looked like on our run. Splitting a topic across many pages does not explain missing from page one. It does mean that if the topic becomes winnable, your authority is spread across several URLs instead of one.
📖 See also Bing SERP tracker after the API
Which endpoint should I use for which job?
| Job | Endpoint | Input | Returns | Billing (Verified 2026-10-16) |
|---|---|---|---|---|
| Which of my pages does Google list for a concept | mrscraper/serp/google | query, region, language, page | Organic rows with rank and global rank, plus PAA and AI Mode when present | Per call, $0.001 |
| Every URL on a site, with titles | firecrawl/map | url, search, limit | URLs with title and description | Per call, $0.001 |
| Which keywords a page ranks for | ahrefs/site-explorer/organic-keywords | target, date, country, limit, order_by | Keyword, best position, ranking URL, volume, traffic | Per row, $0.01548 |
| Search results with page text in one call | context.dev/web/search | query, numResults | Ranked links with relevance, optional markdown | Per result, $0.000253 |
| Sitemap overview of a domain | api.strale.io/x402/sitemap-parse | url | URL count, path segments, lastmod dates, sample URLs | Per call, $0.0594 |
Prices Verified 2026-10-16 with monid inspect. For a full URL list of your own site before you choose concepts, find all URLs on a domain compares the routes. The first row is the check itself. A twenty-concept audit is twenty calls on it, or $0.02. The ranked-keywords row is billed per row, so the limit input is your spending cap: two rows cost $0.03096. The last row was inspected and not run, because one call is above the $0.05 limit we set for testing.
When is another route a better fit?
You need your own ranking history. A search tells you what Google returns today. It cannot show two of your pages swapping places on one query over weeks. An SEO suite or Search Console stores positions per URL per day, and that history is what a cannibalization report is built on.
You have thousands of keywords. The method is one call per concept, so cost and time grow with the list. A suite that already holds your keyword rankings answers the same question across the whole site in one view, and steady volume at that size is what a plan prices well.
Your pages share a word, not an intent. Topical overlap is normal on a site with depth. A definition page and a comparison page on one technology serve different searchers, and a tag scan or a site-restricted list flags them anyway. Judgement beats the heuristic, and no endpoint supplies it.
You want the pages merged for you. The check finds the cluster. Choosing the winner, redirecting the loser and rewriting titles is editorial work, and an agent can prepare the table but not decide what each page is for.
And the disclosure: this is Monid's blog and we resell these endpoints. We also run the check on our own site here, because a worked audit on someone else's domain would be a claim we could not reproduce.
Conclusion
The quickest way to check keyword cannibalization from an agent is one site-restricted Google search per concept through Monid: $0.001 a call (Verified 2026-10-16), one key for this and every other tool, about a minute to set up and ready inside your agent whenever you need it. Doing it by hand works for five concepts and a tag script works for your own files; the call replaces the copy-paste and the scraper upkeep.
Two things matter more than the tool. Count only the pages that answer the same question, because listing and product pages show up in a site: result and are not competition. And repeat the check on a schedule, because a single run is a sample: ours returned different pages in September than in October.
How we estimated the time saved: checking 20 concepts by hand is about 5 to 10 minutes each, so 2 to 3 hours of searching and note-taking, and a script that compares tags and stores the results takes 1 to 2 hours more, with 1 to 5 hours of upkeep over the first months as layouts and lists change. That is 3 to 10 hours. The 1 minute is the install, key and first call once you already have a Monid key.
Free next step: run monid inspect -p mrscraper -e /serp/google, then make one call with site: and your own domain for the concept you most want to own, and count how many of your URLs come back. Start at monid.ai.
FAQ
What is keyword cannibalization?
It is several pages of one site competing for the same query, so the search engine has to choose one and the choice is often not the page you wanted. Signals such as links and engagement spread across the pages instead of building on one, and the page shown can change between crawls.
Should you merge the pages, redirect them or differentiate them?
Differentiate first, because it is reversible: give each page a distinct primary target, retitle it to lead with that target, and make the internal links say which page answers which question. Merge when two pages answer the same question and neither can be narrowed without becoming thin, and redirect the loser to the winner. Choose the winner on links, since those are the part you cannot move.
Does Ahrefs find keyword cannibalization?
Ahrefs keeps your ranking data, so it can show which URL ranks for a keyword and how that changes over time. Through Monid, the ahrefs/site-explorer/organic-keywords endpoint returns the keyword, its best position, the ranking URL, volume and traffic, one URL per keyword row, billed $0.01548 a row (Verified 2026-10-16).
How many pages on one topic is too many?
There is no fixed number. The test is whether you can read the list a site-restricted search returns and say in one sentence what each page is for. Three pages with three crisp jobs are fine; two pages that are both "sort of about gateways" are one page too many, whatever their quality.
Published September 2026.


