Most teams check a domain’s Google rankings the slow way: scraping result pages, or pasting keywords into a tool one at a time and copying positions into a spreadsheet. Both methods fall apart once the keyword list grows. A scraper means proxies, captcha solving, and a parser, you patch every time Google reshuffles a SERP. Manual checks don’t scale beyond a few dozen terms and go stale within days. The Ranked Keywords endpoint of DataForSEO Labs API works as a bulk Google keyword rank checker: it returns every keyword a domain already ranks for, positions included, in a single request, and this guide shows how.
Why check rankings by domain, not one keyword at a time
The trick is to stop thinking in keywords and start thinking in domains. Instead of asking “where does this site rank for keyword X,” you ask “what does this site rank for, and where.” One request to the Ranked Keywords endpoint returns the whole set: every keyword a target ranks for, each with its SERP position. That single call can stand in for thousands of one-keyword lookups.
That works because DataForSEO Labs runs entirely in Live mode. You don’t set a task, poll for it, and fetch the result separately. You send one request and get structured JSON back in the same response. The numbers come from our keyword database of 4.8+ billion keywords, so positions are pulled from an existing index rather than a fresh crawl you’d have to wait for.
For a product team, that’s the difference between shipping a rank-tracking feature and running a collection layer. You get search data at a scale your own crawlers couldn’t keep up with, and nobody has to maintain a scraper. It all runs through a single endpoint.
The Ranked Keywords endpoint: your solution for bulk rank checking
The Ranked Keywords endpoint is the core of bulk rank checking in the DataForSEO Labs API. You point it at a target (a domain, subdomain, or URL), and it returns the keywords that target ranks for, along with their positions and search volumes. The data refreshes weekly, and you can send up to 2,000 calls a minute, with up to 30 running at once. That’s enough headroom to pull rankings for a large portfolio of domains in one batch.
The snippet below is the smallest request that works. It pulls the keywords an example domain ranks for in the United States, keeps only organic positions, and caps the response at 1,000 items. Start here, then wrap it in a loop once you’re running it across many domains.
# Auth is HTTP Basic with your base64-encoded "login:password" from the dashboard.
# Swap in your own credentials before running.
curl --location --request POST "https://api.dataforseo.com/v3/dataforseo_labs/google/ranked_keywords/live" \
--header "Authorization: Basic $(printf 'login:password' | base64)" \
--header "Content-Type: application/json" \
--data-raw '[
{
"target": "yourdomain.com",
"location_code": 2840,
"language_code": "en",
"filters": [
["ranked_serp_element.serp_item.type", "=", "organic"]
],
"limit": 1000
}
]'
Endpoint used: api.dataforseo.com/v3/dataforseo_labs/google/ranked_keywords/live. See the Ranked Keywords documentation for the full parameter list.
Here’s what comes back, with the deeper metric objects collapsed so the ranking fields stay readable. Each item carries the keyword, its search volume, and a ranked_serp_element holding the position. The rank_absolute field displays the real position on the page, and the rank_group field shows the position among the SERP results of the same type.
{
"version": "0.1.20240801",
"status_code": 20000,
"status_message": "Ok.",
"tasks": [
{
"id": "...",
"status_code": 20000,
"result": [
{
"target": "yourdomain.com",
"location_code": 2840,
"language_code": "en",
"total_count": 4213,
"items_count": 1000,
"items": [
{
"keyword_data": {
"keyword": "keyword research api",
"keyword_info": {
"search_volume": 1900,
"cpc": 7.42,
"competition": 0.21
// ... additional keyword_info fields ...
}
},
"ranked_serp_element": {
"serp_item": {
"type": "organic",
"rank_group": 3,
"rank_absolute": 3,
"domain": "yourdomain.com",
"relative_url": "/apis/keyword-data-api",
"etv": 412.5
// ... title, url, and other serp_item fields ...
}
}
}
// ... 999 more items ...
]
}
]
}
]
}
Notice that the total_count reads 4,213 while the items_count is 1,000. The domain ranks for far more than a single response hands back, which is where filtering and pagination come in.
Filtering and sorting the results to return only the rankings you need
A raw ranked-keywords pull can run large, and the DataForSEO Labs API bills per task plus per item returned. So ask for less. Filter the set down to the rankings that matter before they reach your application, which sharpens the data and helps keep costs in line with what you use.
You can filter on the same fields from the response. Set a floor on keyword_data.keyword_info.search_volume to drop near-zero-traffic terms. Restrict ranked_serp_element.serp_item.type to "organic" to exclude paid placements. To page through the rest of that 4,213-keyword set, pair limit with offset, and sort by rank so the positions you care about land first. Our guide on getting the keywords a domain or URL ranks for is worth a look while you’re tuning these parameters. Once the current snapshot is under control, the next question is usually movement over time.
Monitoring changes in rankings over time
Checking rankings once tells you where a domain stands today. Checking them on a schedule tells you whether the work is paying off. That’s a different set of endpoints. Ranked Keywords gives you the live picture; for trend lines, DataForSEO Labs API keeps historical records you can query directly.
The Historical Rank Overview endpoint returns a domain’s ranking distribution and estimated traffic volume month by month, with history going back to 2020-10-01. For the current organic-and-paid snapshot in one call, use Domain Rank Overview. And when you need traffic estimates across a whole portfolio, Bulk Traffic Estimation covers up to 1,000 domains in one request. Between them, you can store current and historical ranking data inside your product without standing up a separate monitoring pipeline. A few habits keep these bulk pulls clean.
Common mistakes when checking rankings in bulk
A handful of failure modes show up again and again in bulk rank checking. These are the ones that trip most teams, and how to avoid them.
1. Passing the wrong target format. Leading https:// or www. can skew the match. Specify the bare domain (or the exact page URL) in the target field so positions map to what you expect.
2. Expecting real-time positions. Ranked Keywords reads from a weekly-updated database, not a live crawl. Treat the response as a rankings snapshot rather than a minute-by-minute position check, and plan refreshes around the weekly update cycle.
3. Ignoring the update cadence. Re-pulling the same target every hour wastes calls and returns the same data. Check the Status endpoint for the latest update time and schedule around it.
4. Forgetting to exclude paid results. If you only want organic positions, filter on ranked_serp_element.serp_item.type or specify "item_types": ["organic"] before sending a request. Otherwise, paid items can inflate the count and muddy your reporting.
5. Leaving limit and offset at defaults. When the total_count exceeds items_count, you’re only seeing the first 100 results. Paginate to capture the full ranked set.
Steer clear of those five, and your bulk pulls stay accurate and predictable. Because you only pay for the items you pull, the cost scales with what you keep rather than running away from you.
Conclusion
Checking Google rankings in bulk comes down to one shift: query by domain, not by keyword, and let a keyword database do the work your scrapers shouldn’t have to. The Ranked Keywords endpoint returns every position a domain holds in a single Live request and filters that set to only what matters. The historical endpoints turn those snapshots into trend lines, all from DataForSEO Labs API, with no collection layer to maintain.
Try for free and run the Ranked Keywords endpoint against your own domain in the playground before you wire it into your product. Our pricing is pay-as-you-go, so you only pay for the rankings you pull.