Competitor Domain Keywords & Traffic
Pricing
from $0.51 / 1,000 keyword rows
Competitor Domain Keywords & Traffic
Competitor keywords and domain traffic by country: the domain keywords a site ranks for on Google (ranked keywords with position, search volume, CPC, keyword difficulty, estimated traffic and search intent), or an organic traffic estimate. Up to 1,000 domains per run. Not affiliated with Google.
Pricing
from $0.51 / 1,000 keyword rows
Rating
0.0
(0)
Developer
Data Pulse
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Get the Google keywords a domain ranks for, or an estimate of its organic search traffic, for up to 1,000 domains per run.
The Actor has two modes:
- Ranked keywords: one row per domain and keyword, with the Google position, monthly search volume, CPC, estimated traffic from that keyword and search intent.
- Traffic overview: one row per domain, with estimated organic traffic, the number of ranking keywords, and estimated paid traffic and paid keywords. Optionally with the number of keywords per position range.
Typical uses are competitor research, finding keywords a competitor gets traffic from, sizing a list of domains by search traffic, and tracking a few domains over time.
What the traffic numbers mean
Traffic is an estimate of organic search traffic from Google, not total site traffic. For every keyword a domain ranks for, the monthly search volume is multiplied by the expected click-through rate for its position, and the results are added up. Direct visits, social, email, referrals and other search engines are not included. Use the numbers to compare domains and spot trends, not as exact visit counts.
Input
| Field | Default | Notes |
|---|---|---|
domains | example | Up to 1,000 domains or URLs. https://, www. and paths are removed, duplicates are dropped, invalid entries are listed in the summary and not charged. Subdomains are kept as given. Without this field the Actor runs a small example (hubspot.com, up to 20 keywords). |
mode | rankedKeywords | rankedKeywords or trafficOverview. |
location | United States | Country name, two-letter code, location code, or Worldwide for all countries. Leaving the field out means the United States; an empty value stops the run with a message. |
language | en | Language code or name, or all for every language. |
maxKeywordsPerDomain | 100 | Ranked keywords: the keywords that bring the most estimated traffic come first. Up to 10,000. The input form starts at 20, so a first run with the three example domains returns up to 60 rows and costs at most $0.18 ($0.051 for the rows, $0.075 for the three domain lookups and $0.05 for the run). Leave the field out of an API call to get 100. |
minSearchVolume | 0 | Ranked keywords: skip keywords with fewer monthly searches. |
maxPosition | 100 | Ranked keywords: skip keywords where the domain ranks lower than this. 10 means first page only. |
includePositionDistribution | false | Traffic overview: add keyword counts per position range and new/up/down/lost counts. Slower, one lookup per domain, and $0.027 extra per domain (see Pricing). |
useCache | true | Reuse results for the same domain and settings from earlier runs. |
cacheTtlDays | 7 | Maximum age of cached results. The ranking data is updated about once a week. |
includeNoDataRows | false | Traffic overview: also output a free row for domains without data. |
pushSummaryToDataset | false | Append the run summary to the dataset. |
With "location": "Worldwide" (also accepted as global or all) the ranked keywords come from all covered countries in one run. They are not merged into one figure: each row is one keyword in one country, and its location and locationCode name that country, so the same keyword can appear once per country with that country's search volume. The rows with the highest estimated traffic come first. The language you set is still applied; with "language": "all" keywords in every language are included and each row names its language. The run summary shows Worldwide. In traffic overview mode, a worldwide estimate covers all available locations; how the location data is combined is not documented in detail. A domain usually ranks for more keywords worldwide than in one country, so maxKeywordsPerDomain and the maximum charge per run matter more here.
Example:
{"mode": "rankedKeywords","domains": ["hubspot.com", "mailchimp.com", "notion.so"],"location": "United States","language": "en","maxKeywordsPerDomain": 100,"maxPosition": 10}
The filters are applied before the data is fetched, so you only pay for rows that pass them.
Supported countries and languages
Ranking data is available for the countries that the data source tracks on Google, including every country in the table below, plus Hong Kong and Taiwan. Regions and cities are not supported, and neither are Russia and Belarus. A country can be given by name, two-letter code or location code, and the language by code or name. A location or language without data stops the run as invalid input without a charge. Some examples:
| Country | location | Location code | Typical language |
|---|---|---|---|
| United States | us | 2840 | en |
| United Kingdom | uk | 2826 | en |
| India | in | 2356 | en or hi |
| Germany | de | 2276 | de |
| France | fr | 2250 | fr |
| Brazil | br | 2076 | pt |
| Spain | es | 2724 | es |
| Mexico | mx | 2484 | es |
| Indonesia | Indonesia | 2360 | id |
| Japan | jp | 2392 | ja |
Competitor keywords of a German site, German keywords only:
{"mode": "rankedKeywords","domains": ["zalando.de"],"location": "Germany","language": "de","maxKeywordsPerDomain": 100}
Set "location": "Worldwide" to get the keywords a domain ranks for in all covered countries in one run, and add "language": "all" to include every language. In Worldwide mode the same keyword can appear several times, once per country (and per language with all): each row names its country in location and locationCode and its language in language and languageCode, while the run summary says Worldwide. See Input above for details.
Output
Ranked keywords, one row per domain and keyword:
{"domain": "mailchimp.com","keyword": "mailchimp","position": 1,"isNewRanking": false,"searchVolume": 368000,"cpc": 2.68,"competitionLevel": "MEDIUM","keywordDifficulty": 45,"etv": 211692.97,"intent": "navigational","secondaryIntents": "informational","location": "United States","locationCode": 2840,"language": "English","languageCode": "en","source": "live","fetchedAt": "2026-10-21T21:22:47.782Z"}
position is the position among organic results. etv is the estimated monthly traffic the domain gets from this keyword. intent is informational, navigational, commercial or transactional, and null when the keyword has no intent data. cpc is in USD and null when there is no ad data.
Traffic overview, one row per domain:
{"domain": "hubspot.com","organicEtv": 497381.26,"organicKeywords": 298693,"paidEtv": 6363.78,"paidKeywords": 17,"organicPos1": 5441,"organicPos2_3": 8028,"organicPos4_10": 36987,"organicPos11_20": 68394,"organicTop3": 13469,"organicTop10": 50456,"estimatedOrganicTrafficCost": 6654008.09,"newKeywords": 138855,"upKeywords": 74290,"downKeywords": 71188,"lostKeywords": 151706,"hasPositionDistribution": true,"location": "United States","hasData": true}
The position range fields (organicPos1 to organicPos91_100, organicTop3, organicTop10), estimatedOrganicTrafficCost and the new/up/down/lost counts are only filled when includePositionDistribution is on, otherwise they are null. estimatedOrganicTrafficCost is what the organic traffic would cost as Google Ads clicks, in USD.
The dataset has two table views, Ranked keywords and Traffic overview.
Run summary
Every run saves a SUMMARY record in the default key-value store: valid, invalid and duplicate domains (with the reason each invalid entry was rejected), domains without data, rows delivered, cache hits, charged events, rate-limit waits and the run status (succeeded, failed or invalid_input). If the input has nothing the Actor can use (no valid domains, every domain rejected by the data source, an unknown location or language, or a maximum charge per run too low for one domain), the run ends as succeeded with an empty dataset, nothing is charged, and the status message says what was wrong and how to fix it.
Pricing
Pay per event:
- $0.00085 per keyword row in ranked keywords mode ($0.85 per 1,000 rows).
- $0.025 per domain looked up in ranked keywords mode, once per domain, also when the domain has no ranked keywords. Domains answered from the cache, invalid domains and failed lookups do not pay it.
- $0.0045 per domain in traffic overview mode ($4.50 per 1,000 domains).
- $0.027 per domain for the position distribution, on top of the $0.0045, only when
includePositionDistributionis on and position data is returned for that domain. - $0.05 once per run, only when the run fetches new data. A run answered fully from the cache does not pay it.
These are the prices on the Apify free plan. On paid plans the row and domain prices are lower, down to $0.00051 per keyword row, $0.00315 per domain overview and $0.0198 per position distribution on Gold and higher. The domain lookup and the run start cost the same on every plan.
Invalid domains and rows removed by your filters are not charged. In ranked keywords mode, every domain looked up live pays the $0.025 domain lookup, also when it returns no rows (for example a small or new domain, or a domain whose keywords are all removed by your filters); keyword rows are charged only for the rows returned. In traffic overview mode there is no domain lookup fee: domains without data are free, and a domain that comes back without position data is charged only the $0.0045. Rows from the cache are charged like fresh rows.
Examples:
- 1 domain with 1,000 keywords: $0.85 plus $0.025 plus $0.05, $0.925 in total.
- 3 domains with 100 keywords each: 300 rows for $0.255, plus $0.075 for the domain lookups and $0.05, $0.38 in total.
- 10 domains with 1,000 keywords each: 10,000 rows for $8.50, plus $0.25 and $0.05, $8.80 in total.
- Traffic overview for 100 domains: $0.45 plus $0.05, $0.50 in total.
- Traffic overview with position distribution for 100 domains: $0.45 plus $2.70 plus $0.05, $3.20 in total.
If you set a maximum charge per run, the Actor requests only as much data as that limit can pay for and stops cleanly when it is reached. The skipped domains are listed in the summary.
Apify free plan limit
Users on the Apify free plan get up to 20 rows per run. The Actor looks up the first 20 domains of the list and names the rest under freePlanLimit.skipped in the run summary. In ranked keywords mode the 20 keyword rows are taken from those domains in the order you list them, and in traffic overview mode each domain is one row. The run still finishes as succeeded, and its status message says that the free plan limit was reached.
This limit was set by the developer of this Actor, not by Apify. The keyword and traffic data is paid per request, and runs by free plan users bring the developer no revenue. Any paid Apify plan removes the limit, and nothing else about the run changes.
Run time and limits
Small runs finish in a few seconds. Very large runs (hundreds of domains with thousands of keywords each) take longer, because requests to the data source are rate limited. The Actor spaces its requests, waits and retries when a rate limit is hit, and records the waiting time in the summary.
If a run is restarted or migrated, domains that were already delivered are not fetched or charged again.
Notes
- Data covers Google organic results. Keywords outside the top 100 are not included.
- Small or new domains often have no data. They are listed in the summary. In ranked keywords mode such a domain still pays the $0.025 domain lookup when it is looked up live, but no keyword rows. In traffic overview mode it is not charged.
- Use the domain the site actually serves. For example, if a company moved to a new domain, the old one may show far fewer keywords.
- Subdomains are treated as separate targets:
blog.example.comreturns only that subdomain.
API
curl -X POST "https://api.apify.com/v2/acts/datapulsehq~domain-keywords-traffic/run-sync-get-dataset-items?token=YOUR_TOKEN" \-H "Content-Type: application/json" \-d '{"mode": "trafficOverview", "domains": ["hubspot.com", "mailchimp.com"]}'
This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by Google.