Competitor Keyword Research: Ranked Keywords API
Pricing
from $30.00 / 1,000 domain summaries
Competitor Keyword Research: Ranked Keywords API
Competitor keyword research API: every keyword a website ranks for in Google, with position, ranking URL, search volume, CPC, intent and estimated traffic, plus organic competitors and a plain-English summary per domain. $0.03 per domain + $2 per 1,000 keywords.
Pricing
from $30.00 / 1,000 domain summaries
Rating
0.0
(0)
Developer
Meridian Labs
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
21 hours ago
Last modified
Categories
Share
Competitor Keyword Research shows every keyword a website ranks for in Google: position, the ranking URL, search volume, CPC, competition, keyword difficulty, search intent, estimated traffic and the SERP features on the page. Add organic competitors (the sites ranking for the most of the same keywords) and you get a plain-English summary per domain: total ranked keywords, page-one keywords, estimated monthly traffic and what it's worth in ads, top pages and closest competitors. Analyse up to 100 domains per run and up to 20,000 keywords per domain. The input form is pre-filled, so the easiest way to try it is to click Start: 100 keywords for one domain cost $0.23.
It's built for SEO specialists and content marketers reverse-engineering a competitor, agencies preparing audits and pitches, e-commerce teams checking which product pages win search traffic, and AI agents that need ranking data through an API, without a monthly SEO-suite subscription.
What data do you get for each domain?
One row per ranked keyword (rowType: "keyword"), most estimated traffic first:
- ๐ Keyword and its position among Google's organic results (
position;absolutePositioncounts ads, maps and boxes too). - ๐ Ranking URL (
url) and the page title shown in the results. - ๐ Search volume (
searchVolume, monthly, Google Ads Keyword Planner figure), CPC (USD), competition (0โ1 and LOW/MEDIUM/HIGH). - ๐ฏ Keyword difficulty (0โ100) and search intent (informational, navigational, commercial, transactional).
- ๐ฆ Estimated traffic (
estimatedTraffic): monthly visits this keyword brings, from its volume and the click-through rate at that position, plus what those visits would cost in ads (trafficValueUsd). - ๐งฉ SERP features on the page (people also ask, local pack, images, video, AI overview and more), featured-snippet flag, and movement since the previous check (new, up, down).
One row per organic competitor (rowType: "competitor", if you switch it on): the competitor's domain, shared keywords (and what share of yours that is), its average position on them, its traffic from them, and its own total keywords and estimated traffic.
One summary row per domain (rowType: "summary", saved last):
- ๐ A plain-English summary, for example: "heathceramics.com ranks for 9,813 keywords in the United States (English), 1,735 of them on page one (312 at #1). Estimated organic traffic: about 24,035 visits a month, worth about $23,067 a month in ads. Top page among the 100 keywords returned: https://www.heathceramics.com/ (~10,363 visits a month from 18 of them). Biggest keyword: "ceramics" (#2, 110,000 searches a month). Closest organic competitors: homedepot.com, target.com, crateandbarrel.com."
- ๐ Totals for the whole domain: ranked keywords, #1 / top-3 / page-one keywords, estimated monthly traffic and its ad value, keywords new, up and down since the last check.
- ๐ Top pages by estimated traffic among the keywords returned.
Why use this competitor keyword tool?
- ๐งพ The whole list, not a teaser. Ask for 5,000 keywords and you get 5,000 when the domain ranks for that many (up to 20,000 per domain).
- ๐ฃ๏ธ A summary you can paste into a report. Every domain gets totals and a readable paragraph, so you don't need a spreadsheet to say how a competitor is doing.
- ๐ฏ Filters that save money. Minimum search volume, a position range (e.g. 4โ20 for "almost page one" keywords) and excluded terms are applied by the data provider before you're charged.
- ๐ธ Fair billing. You pay per domain analysed and per row returned. Failed lookups, invalid entries and domains that don't exist are free, and the run stops exactly at your maximum spending limit.
- ๐ค AI-agent ready. Documented output schema, three table views and stable field names. It works from the Apify API, integrations (Make, Zapier, n8n, Google Sheets) and MCP clients.
How do I see which keywords a competitor ranks for?
- Enter one or more domains (
competitor.com), one per line.https://www.competitor.com/pageworks too: it's reduced to the domain. - Pick the country (default United States) and, if it has several, the language.
- Set Max keywords per domain (default 1,000) and any filters: Minimum monthly searches, Best / Worst position to include, Exclude keywords containing.
- Switch on Find organic competitors if you want them.
- Click Start. Open the Ranked keywords, Organic competitors or Summary per domain view on the Output tab, or export everything as JSON, CSV or Excel.
How do I find a competitor's best pages?
Run the domain with Max keywords per domain at 1,000 or more. The summary row lists the top pages by estimated traffic; for the full picture, open the Ranked keywords view and sort or group by url.
How do I find keywords where a site is almost on page one?
Set Best position to include to 4 and Worst position to include to 20, and Minimum monthly searches to, say, 100. You get the keywords ranking #4โ20 with real demand: the usual quick wins.
How do I find my organic competitors?
Enter your own domain, switch on Find organic competitors and set Max keywords per domain to 0 if you only want the competitor list and the summary. Each competitor row says how many keywords you share and how much traffic it gets overall. Giant general sites (Google, YouTube, Facebook, Wikipedia and similar) are left out.
How much does it cost?
$0.03 per domain analysed, plus $0.002 per ranked-keyword row ($2 per 1,000 keywords) and $0.002 per competitor row. Failed lookups are free.
| Event | Price | Charged when |
|---|---|---|
| Domain summary | $0.03 per domain | The lookup for a domain answered, including a clean "ranks for no keywords" for a site that exists: the lookup ran and answered. |
| Ranked keyword | $0.002 per row | Each keyword row saved. |
| Organic competitor | $0.002 per row | Each competitor row saved (only if you switch competitors on). |
- ๐ Free: errors, invalid entries, domains that don't exist (no DNS record: they aren't even looked up), and domains or rows skipped because the run reached your maximum spending limit or its time limit.
- Examples: 1 domain with its top 100 keywords = $0.23. 1 domain with 1,000 keywords = $2.03. 5 competitors ร 1,000 keywords = $10.15. 1 domain, summary and 10 competitors only = $0.05.
- Free to try: Apify's free plan includes $5 of platform usage every month: about 2,400 keyword rows, or 160 domain summaries. Platform usage is included in the price.
- Set a maximum cost per run in the run options: the Actor only fetches rows it can charge for and stops exactly there. Domains it didn't reach are listed as
skippedand not charged.
Output example
Data source: DataForSEO Labs (Google rankings from DataForSEO's own search-results database; search volume, CPC and competition are Google Ads Keyword Planner figures), stated on every row as dataSource.
A keyword row (real output, October 2026):
{"rowType": "keyword","domain": "heathceramics.com","keyword": "ceramics","position": 2,"absolutePosition": 6,"url": "https://www.heathceramics.com/","searchVolume": 110000,"cpc": 1.29,"competition": 0.07,"competitionLevel": "LOW","keywordDifficulty": 52,"intent": "informational","estimatedTraffic": 5657.8,"trafficValueUsd": 7298.53,"serpFeatures": ["local_pack", "people_also_ask", "related_searches", "images"],"isFeaturedSnippet": false,"rankChange": "up","country": "US","language": "en"}
A competitor row:
{"rowType": "competitor","domain": "heathceramics.com","competitorDomain": "crateandbarrel.com","sharedKeywords": 2501,"sharedKeywordsPct": 25.5,"avgPositionOnShared": 21.1,"sharedKeywordsTraffic": 7036.6,"competitorKeywords": 607500,"competitorTop10Keywords": 107617,"competitorTraffic": 1724760.7}
A summary row (trimmed):
{"rowType": "summary","domain": "heathceramics.com","status": "ok","rankedKeywords": 9813,"firstPositionKeywords": 312,"top10Keywords": 1735,"estimatedMonthlyTraffic": 24035,"trafficValueUsd": 23067,"summary": "heathceramics.com ranks for 9,813 keywords in the United States (English), 1,735 of them on page one (312 at #1). ...","topPage": "https://www.heathceramics.com/","keywordsReturned": 100,"keywordsLimitedBy": "maxKeywordsPerDomain","competitorsReturned": 3,"charged": true}
Summary status is one of:
ok: the domain ranks for keywords.no_rankings: the site exists but ranks for no keywords in that country (or none matching your filters). Charged: the lookup ran and answered.error: the lookup failed, the entry isn't a valid domain, or the domain doesn't exist (DOMAIN_NOT_FOUND). Not charged.skipped: not analysed because the run hit its spending, time or data-cost limit. Not charged.
keywordsReturned says how many keyword rows you got and keywordsLimitedBy why you got fewer than the domain ranks for (maxKeywordsPerDomain, SPENDING_LIMIT, RUN_TIME_LIMIT). For each domain, its keyword and competitor rows come first and the summary row last.
Input
| Field | What it does |
|---|---|
domains | Domains to analyse, one per line (up to 100). https://www.example.com/page counts as example.com; other subdomains (blog.example.com) are analysed on their own. Duplicates are removed. |
country, language | The Google market (94 countries; default US). Language is optional: empty = the country's main language. |
maxKeywordsPerDomain | Most keyword rows per domain, most estimated traffic first (0โ20,000; default 1,000). 0 = summary and competitors only. |
minSearchVolume | Only keywords searched at least this often a month. |
minPosition, maxPosition | Position range to include (1โ100), e.g. 1โ10 for page one. |
excludeKeywords | Up to 5 terms; keywords containing any of them are dropped (e.g. the domain's own brand). |
includeCompetitors, maxCompetitors | Also return organic competitors, most shared keywords first (1โ100; default 10). |
failOnErrors | Mark the run failed if any lookup errors (for schedules and monitoring). Failed lookups are still free. |
Example:
{"domains": ["heathceramics.com", "eastfork.com"],"country": "US","maxKeywordsPerDomain": 1000,"minSearchVolume": 50,"maxPosition": 20,"includeCompetitors": true,"maxCompetitors": 10}
Switching from another competitor-keywords Actor?
These input names work too, so an existing input usually runs unchanged: domainsText (a pasted list), database (country market such as us or uk), minVolume, discoverCompetitors and competitorsPerDomain. maxKeywordsPerDomain, maxPosition and excludeKeywords mean the same here.
How to read the numbers
- Estimated traffic is a model, not analytics. It's search volume ร the typical click-through rate at that position, summed over keywords. Use it to compare sites and pages, not as a visit count.
- Totals cover the whole domain; top pages cover the rows returned. With filters on, the totals count only matching keywords (the summary says so).
- Positions and volumes differ between tools. Every ranking database checks results pages on its own schedule (
serpCheckedAton each row); compare within one source.
How do I track a competitor's rankings every month?
- Fill in the input (the competitor's domain, a keyword limit) and click Save as a new task.
- Open Schedules โ Create new, pick the task and choose monthly.
- Compare runs on
positionandrankChange, or send the dataset to a spreadsheet (next section).
How do I send keyword data to Google Sheets, Make, Zapier, n8n or an AI agent?
- Google Sheets (one formula): save your input as a task and schedule it, then put this in cell A1 of a sheet and click Allow access on the yellow bar Sheets shows about external data:
=IMPORTDATA("https://api.apify.com/v2/acts/meridianlabs~competitor-keywords/runs/last/dataset/items?status=SUCCEEDED&format=csv&view=keywords&token=YOUR_TOKEN")It loads your latest successful run, and picks up a newer one when Google refreshes imported data (about once an hour) or when you reopen the sheet. For the other tables, changeview=keywordstoview=summaryorview=competitors. Anyone who can open the sheet can see the token, so create one with limited permissions in Console โ Settings โ API & Integrations. For a saved task, useactor-tasks/<your-username>~<task-name>/runs/last/...instead. - Make: Apify "Run an Actor" (Run synchronously: Yes) โ Apify "Get Dataset Items" โ Google Sheets, add rows.
- n8n: Apify trigger "Actor Run Finished" โ Apify "Get Items" (Datasets) with the run's
defaultDatasetIdโ Google Sheets, append. - Zapier: trigger "Finished Actor run" โ "Fetch dataset items" โ Google Sheets.
- Webhooks: Integrations โ HTTP webhook on "Run succeeded" sends the run details to your URL.
- AI agents (MCP): add
https://mcp.apify.com?tools=meridianlabs/competitor-keywordsto your MCP client (Claude, Cursor, VS Code and others).
Limitations
- Google only, top 100 organic positions, one country and language per run.
- Up to 20,000 keywords per domain and 100 domains per run.
- Pages are reduced to their domain. For a single page's keywords, filter the keyword rows by
url.
FAQ
Where does the data come from?
From DataForSEO Labs: rankings come from DataForSEO's own regularly refreshed database of Google results pages, and search volume, CPC and competition are Google Ads Keyword Planner figures. This Actor queries it live on every run; it isn't a scraper of any SEO tool's website, so it doesn't break when a website changes. Not affiliated with Google.
Can I use it with the API, AI agents or MCP?
Yes. Run it through the Apify API or client libraries, schedule it, connect it to Make, Zapier, n8n or Google Sheets, or call it from MCP clients.
Python (pip install apify-client):
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("meridianlabs/competitor-keywords").call(run_input={"domains": ["heathceramics.com"], "maxKeywordsPerDomain": 500, "maxPosition": 10,})for row in client.dataset(run.default_dataset_id).iterate_items():if row["rowType"] == "keyword":print(row["keyword"], row["position"], row["searchVolume"], row["url"])
Does it collect personal data?
No. Rows contain keywords, public page URLs and titles, and aggregate search statistics. The Actor doesn't store anything in your account beyond the run's own dataset.
What happens if a run times out or restarts?
If a run approaches its timeout, the Actor stops starting new lookups: domains it didn't reach are listed as skipped (not charged), and a domain cut short keeps the rows already delivered, with keywordsLimitedBy: "RUN_TIME_LIMIT". If the platform restarts a run, it picks up where it left off without charging twice.
More from Meridian Labs
- Backlink Checker: domain rank, backlinks, referring domains and spam score for up to 1,000 domains, plus full backlink and referring-domain lists. $0.03 per domain + $4 per 1,000 rows.
- Keyword Search Volume & CPC API + Google Trends: monthly search volume, CPC, competition, difficulty and intent for keyword lists, keyword ideas from a seed, plus a Google Trends summary per keyword. From $3 per 1,000 keywords.
- Google Trends Scraper & API: interest over time, by region and rising related searches for hundreds of keywords, as a maintained pytrends alternative. $5 per 1,000 keyword lookups.
- Greenhouse, Lever & Ashby Jobs Scraper: open jobs from companies on six hiring systems, with salary normalised to min, max, currency and period. $2 per 1,000 jobs.
- Startup Funding Rounds & Founders API: US startups that just raised, from SEC Form D filings: amount raised, investor count, founders and executives, and a one-line summary. $10 per 1,000 filings.
- EU & UK Tenders Scraper: public tenders and contract awards from the EU's TED and the UK's Find a Tender, with buyer, value, deadline and a one-line summary. $3 per 1,000 notices.
Support
Something looks wrong, or you need a field we don't return? Open an issue on the Issues tab with the input you used. We read every one.
If this saved you time, a rating helps others find it; if something's off, open an issue and we'll fix it fast.