Competitor Keywords Scraper — Ranked Keywords of Any Domain avatar

Competitor Keywords Scraper — Ranked Keywords of Any Domain

Pricing

from $1.50 / 1,000 ranked keywords

Go to Apify Store
Competitor Keywords Scraper — Ranked Keywords of Any Domain

Competitor Keywords Scraper — Ranked Keywords of Any Domain

The keywords any domain or page ranks for on Google — position, ranking URL, search volume, CPC, keyword difficulty, search intent and estimated traffic for each, in 94 countries. From $1.50 per 1,000 keywords plus a $0.02 lookup per domain; a domain that ranks for nothing is never charged.

Pricing

from $1.50 / 1,000 ranked keywords

Rating

0.0

(0)

Developer

Steadyfetch Team

Steadyfetch Team

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

1

Monthly active users

3 days ago

Last modified

Share

Competitor Keywords Scraper: the keywords any website ranks for on Google, with the numbers to act on them. Give it a competitor's domain, or one page, and get back the keywords it ranks for in Google's top 100, one row each: its position, the page that ranks, monthly search volume, CPC, competition, keyword difficulty (0–100), search intent and the traffic it is estimated to bring — in 94 countries. A domain with no ranked keywords is never charged.

Using an AI agent? Pin this actor in Apify's MCP server with one link: https://mcp.apify.com?tools=steadyfetch/competitor-keywords-scraper

  • Actor id: steadyfetch/competitor-keywords-scraper
  • Input: { "domains": ["ahrefs.com"] } — the one field you have to set. Add "maxResultsPerDomain": 1000 for more keywords.
  • Cap the bill: set maxTotalChargeUsd on the run (a run option, not Actor input), e.g. 0.50 — the run stops when it reaches it, and never buys keywords it cannot sell you.
  • How often it changes: the source re-checks the Google results behind each ranking about every 75 days, and each row's lastUpdated says when — a monthly schedule catches most moves.
  • Run it on a schedule: save your input as a Task and run it monthly on an Apify Schedule; from the second run on, each row says where the keyword ranked last time (previousPosition, positionChange, isNew).

If it earned its keep, a rating helps other buyers find it, and saving the actor keeps it one click away.

See a real run before you spend anything: sample dataset — ten keywords backlinko.com ranks for in the United States from one verified run, unedited, with the domain's overview row and the run's own summary row last: ten keywords delivered and charged, plus one lookup.

Just want to see it work? Click Start with nothing set and the run gets ten ranked keywords for the example domain ahrefs.com in the United States, charged like any run. Pick a country or a limit but set no domains and that same sample runs under your settings, with one uncharged note row; a limit above ten is capped at ten. Put your own domains in Domains or pages for your own run.

Unofficial. This actor is not affiliated with, endorsed by, or sponsored by Google. "Google" is a trademark of Google LLC, used here only to describe where search data comes from.

What you get

One row per keyword the domain ranks for:

{
"rowType": "keyword",
"domain": "ahrefs.com",
"targetType": "domain",
"keyword": "backlinks checker",
"position": 1,
"absolutePosition": 1,
"url": "https://ahrefs.com/backlink-checker",
"searchVolume": 90500,
"cpc": 7.17,
"competition": 0,
"competitionLevel": "LOW",
"keywordDifficulty": 82,
"searchIntent": "informational",
"estimatedTraffic": 27512,
"lastUpdated": "2026-07-30T04:18:28.000Z",
"previousCheckAt": "2026-05-15T03:34:38.000Z",
"serpTrend": "same",
"country": "US",
"language": "en",
"previousPosition": null,
"positionChange": null,
"isNew": null,
"previousRunAt": null,
"charged": true
}
FieldWhat it is
rowTypekeyword for a ranked keyword; the overview and summary rows carry their own.
domain, targetTypeThe domain or page you asked about, as it was read, and whether it was read as a whole domain or one page.
keywordA keyword it ranks for.
positionIts organic position on Google, counting organic results only (1 = the top organic result).
absolutePositionIts place counting every element on the results page, ads and boxes included.
urlThe page of that site that ranks for the keyword.
searchVolumeAverage monthly searches over the last 12 months.
cpc, competition, competitionLevelCost per click in USD, advertiser competition from 0 to 1, and LOW / MEDIUM / HIGH.
keywordDifficulty0–100: how hard it is to rank in the top 10 organic results.
searchIntentinformational, navigational, commercial or transactional.
estimatedTrafficMonthly visits this position is estimated to bring — search volume times the click share of the position. An estimate, never a measured count.
lastUpdated, previousCheckAt, serpTrendWhen the source last checked this results page, when it checked it before that, and how the position moved between those two checks: up, down, same or new.
country, languageThe market the keyword was read in.
previousPosition, positionChange, isNew, previousRunAtWhere it ranked in your last run of the same domain and market, how many places it moved (a positive number means it climbed), whether it is new since that run, and when that run was. Empty (null) on your first run.
chargedWhether this row was billed.

A figure the source does not publish comes back null — never invented.

One overview row per domain, uncharged: how many keywords the domain ranks for in total (often far more than you asked for), how they spread over positions 1, 2–3, 4–10, 11–20 and on down to 100, the estimated monthly traffic they bring, and how many of its rankings are new, up or down since the source's check before. With a position or volume filter set, those totals count only the keywords that pass it (totalsMatchYourFilters: true). One summary row last, uncharged: the run's receipt — what was delivered, what was charged, and what stopped the run. Rows with a missReason are uncharged notes saying why something was not delivered.

Settings

SettingFieldDefault
Domains or pagesdomains— up to 100. A bare domain or a homepage link reads the whole domain; a link with a path reads that one page
CountrycountryUS — 94 countries; a country the source does not cover is refused with an uncharged row, never swapped for another
Languagelanguagethe country's main language
Max keywords per domainmaxResultsPerDomain100, up to 5,000
Sort keywords bysortBytraffic (estimated traffic, biggest first); also volume and position
Ranking at or above positionmaxPositionnone — set 1–100, e.g. 10 for page one only
Minimum search volumeminSearchVolumenone

The filters run at the source, so a keyword outside them is never delivered or charged. The sort decides which keywords a limit keeps: traffic gives the keywords that bring the domain the most visits, volume the biggest searches it shows up for, position its best rankings first. Organic Google results only.

Pricing

Pay per event, all-inclusive — no platform-usage charge on top, and no start fee.

EventApify free planBronzeSilverGold and above
Ranked keyword (per keyword delivered)$0.003$0.0025$0.002$0.0015
Domain lookup (once per block of up to 1,000 keywords from one domain)$0.02$0.02$0.02$0.02

100 keywords for one domain is one lookup: $0.17 on Gold, $0.32 on the Apify free plan. 1,000 keywords is still one lookup; 5,000 is five. Ten domains at 100 keywords each are ten lookups.

Never charged: a domain or page with no ranked keywords (no lookup fee either), a keyword your filters leave out, the overview and summary rows, and a request the source refuses or cannot answer.

How often this data changes

Rankings move every day, but the source re-checks the Google results behind each ranking on its own cycle: about every 75 days in our live reads (the middle case; from 74 to 218 days). In one read of a large domain on 2026-10-03, its top 20 keywords had last been checked between 2026-06-17 and 2026-09-02, and their search volumes had been refreshed in mid-September. Each row's lastUpdated says when its result was checked, and serpTrend says how it moved since the check before — so even your first run shows which rankings are climbing.

So the useful pattern is the same domains once a month — a monthly schedule catches most moves. A run more often mostly returns the same positions, and every run reads the source anew and charges for what it delivers. Your own Apify account remembers the positions each domain had, per country and language, and the next run of the same domain fills previousPosition, positionChange and isNew from that memory: a monthly rank tracker for your competitors, and for your own site. Keep the limit, sort and filters the same from run to run — isNew compares against what your last run delivered, so a keyword that was only outside last time's limit would read as new. When the sort or a filter changed, isNew stays empty; previousPosition still comes from your last run.

Set the schedule: save your input as a Task (Actor page → Save as a new task), then add that task to an Apify Schedule (Console → Schedules → Create) with a cron such as 0 7 1 * * for the first of every month.

Limits are hard limits

maxResultsPerDomain and your maximum total charge stop the run exactly where they bind; the run still finishes successfully and the last row says what was delivered and what stopped it. Keywords a request already returned are always delivered.

On the Apify free plan, one domain lookup per account in any 24 hours is included — one domain, up to 1,000 of its keywords; past it the run stops, and that domain's uncharged overview row says when it resets. Paid Apify plans carry no daily allowance.

Steadyfetch keyword tools

You wantActor
The keywords a competitor's domain ranks for, with positionsthis actor
New keyword ideas from a seed, with volume, CPC and difficultyKeyword ideas
A 0–100 difficulty score for a keyword list you already haveKeyword difficulty
Monthly search volume and CPC for a keyword listKeyword search volume & CPC
Autocomplete suggestions across 5 enginesAutocomplete keywords
Rising and Breakout queries with the growth numberBreakout keywords

Feedback & support

Found an issue? Open it on the Issues tab — we usually reply within a couple of hours, always within a day.