Appearance
Rate Limits & Pricing Fresh
Rate Limits
DataForSEO enforces limits on how many requests you can make and how many tasks you can submit per batch. These are per-account limits.
Request Rate Limits
| Limit Type | Default | Notes |
|---|---|---|
| Requests per second | ~10 | Across all endpoints combined |
| Requests per minute | ~300 | Soft limit — may vary by plan |
| Max tasks per batch | 100 | Per single tasks_post request |
| Max keywords per volume request | 1,000 | Keywords Data API |
| Max seeds for Labs | 5 | Per keywords_for_keywords request |
If you hit rate limits, you'll get HTTP 429. Add a 1-second delay between batch posts and exponential backoff on retries.
Checking Your Current Limits
python
import os
import requests
from requests.auth import HTTPBasicAuth
auth = HTTPBasicAuth(
os.environ["DATAFORSEO_LOGIN"],
os.environ["DATAFORSEO_PASSWORD"]
)
response = requests.get(
"https://api.dataforseo.com/v3/appendix/user_data",
auth=auth
)
data = response.json()
user_data = data["tasks"][0]["result"][0]
print(f"Account login: {user_data.get('login')}")
print(f"API key status: {user_data.get('api_key_status')}")
print(f"Available credits: {user_data.get('money', {}).get('balance')}")
print(f"Rate limit (RPS): {user_data.get('limits', {}).get('requests_per_second')}")Pricing Model
DataForSEO uses a pay-per-use credit model. You buy credits and spend them per task. Prices below are approximate and may vary by plan tier.
SERP API Pricing
| Endpoint Type | Cost per Task | Notes |
|---|---|---|
| Organic — Task-based | ~$0.0025 | Per keyword, depth 10 |
| Organic — Live | ~$0.003 | Per keyword |
| Organic — Live Advanced | ~$0.005 | Includes more data |
| Google Maps — Live | ~$0.003 | Per local pack query |
| Local Finder — Live | ~$0.003 | Per query |
| AI Mode — Task-based | ~$0.01 | AI results cost more |
| AI Overview | ~$0.005 | Per query |
| News, Images, Shopping | ~$0.003 | Per query |
Backlinks API Pricing
| Endpoint | Cost | Notes |
|---|---|---|
| Domain Summary | ~$0.01 | Per domain |
| Referring Domains | ~$0.005–$0.05 | Scales with result count |
| Backlinks (raw list) | ~$0.01–$0.10 | Scales with result count |
| Anchors | ~$0.005 | Per request |
| Bulk metrics | ~$0.002/domain | For bulk domain checks |
Keywords Data API Pricing
| Endpoint | Cost | Notes |
|---|---|---|
| Search Volume (per keyword) | ~$0.0005 | Cheapest data in the API |
| Keywords for Site | ~$0.01 | Per domain |
| Google Trends | ~$0.001 | Per keyword |
Labs API Pricing
| Endpoint | Cost | Notes |
|---|---|---|
| Keywords for Keywords | ~$0.005 | Per request (up to 5 seeds) |
| Related Keywords | ~$0.005 | Per seed keyword |
| Ranked Keywords | ~$0.01 | Per domain |
| Competitors Domain | ~$0.01 | Per domain |
| Domain Rank Overview | ~$0.01 | Per domain |
On-Page API Pricing
| Endpoint | Cost | Notes |
|---|---|---|
| Crawl task (per page) | ~$0.004 | Per page crawled |
| With JavaScript enabled | ~$0.006 | Per page — JS costs more |
| With spell check | Additional | Avoid unless needed |
Business Data API Pricing
| Endpoint | Cost | Notes |
|---|---|---|
| GMB Info | ~$0.01 | Per business |
| Reviews | ~$0.005–$0.02 | Scales with review count |
| Yelp/TripAdvisor | ~$0.01 | Per request |
Task-Based vs. Live — Cost Comparison
For most endpoints, the task-based pattern is significantly cheaper than Live. The tradeoff is 30–120 seconds of wait time.
| Pattern | Typical Cost | Wait | Use When |
|---|---|---|---|
| Task-based | $0.0015–$0.003/task | 30–120 sec | Bulk work, scheduled jobs |
| Live | $0.003–$0.010/task | Immediate | Single queries, dashboards |
Rule: If you're running more than 5 queries, use task-based. The cost difference compounds fast.
Cost Optimization Tips
1. Batch Keywords
Keywords Data and SERP both support batches. Always fill a batch before posting.
python
# Instead of 100 individual requests:
for keyword in keywords:
requests.post(endpoint, json=[{"keyword": keyword}]) # 100 requests
# Batch them:
requests.post(endpoint, json=[{"keyword": kw} for kw in keywords]) # 1 request2. Use Task-Based for Bulk Work
Anything more than a few queries should use the task-based pattern. The cost difference is approximately 2–3x.
3. Limit depth to What You Need
For rank tracking, depth: 10 is usually enough to see if you're in the top 10. depth: 100 is needed only if you're tracking positions 11–100.
python
# For "are we in the top 10?" — use depth 10
{"keyword": kw, "depth": 10} # ~$0.0015
# For "what's our exact position in top 100?" — use depth 100
{"keyword": kw, "depth": 100} # ~$0.00254. Skip JavaScript Unless Needed
On-Page API charges more when JavaScript rendering is enabled. Only use it for SPAs or React/Next.js sites where content is client-rendered.
python
{
"target": url,
"enable_javascript": False, # saves ~50% per page
"check_spell": False, # saves additional cost
"store_raw_html": False # saves storage cost
}5. Deduplicate Before Posting
Don't post the same keyword twice. Deduplicate your keyword list before building the payload.
python
keywords = list(set(keywords)) # remove duplicates before posting6. Cache Results
SERP data doesn't change minute to minute. Cache results and set appropriate refresh intervals:
| Data Type | Suggested Refresh |
|---|---|
| Rank positions | Weekly |
| Search volume | Monthly |
| Backlink profile | Weekly |
| On-page audit | Monthly |
| Competitor analysis | Monthly |
| Local pack | Daily (if tracking closely) |
7. Monitor Spend Per Run
Log cost from each API response and alert when a single run exceeds a threshold:
python
data = requests.post(endpoint, auth=auth, json=payload).json()
cost = data.get("cost", 0)
print(f"This request cost: ${cost:.4f}")
COST_ALERT_THRESHOLD = 1.00 # alert if single request costs more than $1
if cost > COST_ALERT_THRESHOLD:
print(f"WARNING: High cost request — ${cost:.4f}")8. Use Bulk Endpoints for Domain Metrics
Instead of making one request per domain when comparing competitors, use bulk endpoints:
python
# Instead of 10 individual domain summary requests:
for domain in domains:
requests.post(".../domain_pages_summary/live", json=[{"target": domain}])
# Use bulk endpoints where available:
requests.post(".../backlinks/bulk_ranks/live", json=[{"targets": domains}])Estimated Monthly Costs by Use Case
| Use Case | Tasks/Month | Approx. Cost |
|---|---|---|
| 50 keywords, weekly rank tracking | 200 SERP tasks | ~$0.50/mo |
| 500 keywords, weekly rank tracking | 2,000 SERP tasks | ~$5/mo |
| Monthly backlink audit (5 clients) | 50 domain summaries + 500 referring domains | ~$5/mo |
| Monthly on-page audit (100 pages) | 100 page crawls | ~$0.40/mo |
| Keyword research (500 seeds) | 1 volume request + 5 Labs requests | ~$0.53 |
| Full SEO audit (1 client) | SERP + backlinks + on-page + keywords | ~$3–$8 |