DataForSEO requires a $50 minimum deposit before you can make a single API call. For startups and side projects, that is a blocker. Scavio provides the same SERP data at $0.005/query with 250 free credits per month and no minimum spend. This tutorial migrates your existing DataForSEO integration to Scavio with minimal code changes.
Prerequisites
- Python 3.8+
- requests library
- A Scavio API key from scavio.dev
- Existing DataForSEO code to migrate
Walkthrough
Step 1: Compare the API interfaces
Map DataForSEO endpoints and parameters to their Scavio equivalents.
import os, requests, json
API_KEY = os.environ['SCAVIO_API_KEY']
SH = {'x-api-key': API_KEY, 'Content-Type': 'application/json'}
# DataForSEO (BEFORE):
# POST https://api.dataforseo.com/v3/serp/google/organic/live
# Auth: Basic base64(login:password)
# Body: [{"keyword": "search api", "location_code": 2840, "language_code": "en"}]
# Cost: $0.002/queue, $0.004/live. $50 minimum deposit.
# Scavio (AFTER):
# POST https://api.scavio.dev/api/v1/search
# Auth: x-api-key header
# Body: {"query": "search api", "country_code": "us"}
# Cost: $0.005/query. No minimum. 250 free/mo.
def scavio_search(keyword, country='us'):
resp = requests.post('https://api.scavio.dev/api/v1/search',
headers=SH, json={'query': keyword, 'country_code': country}, timeout=10)
resp.raise_for_status()
return resp.json()
data = scavio_search('best search api 2026')
print(f'Results: {len(data.get("organic_results", []))}')
print(f'\nPricing comparison:')
print(f' DataForSEO: $0.002-0.004/query, $50 minimum deposit')
print(f' Scavio: $0.005/query, no minimum, 250 free/mo')
print(f' At 1K queries: DataForSEO $50 (minimum) vs Scavio $5')
print(f' At 10K queries: DataForSEO $50 vs Scavio $50')Step 2: Build the migration adapter
Create a drop-in replacement that translates DataForSEO response format to match your existing code.
def dataforseo_to_scavio(keyword, location_code=2840):
"""Drop-in replacement: same output format as DataForSEO."""
# Map location codes to country codes
location_map = {2840: 'us', 2826: 'gb', 2036: 'au', 2124: 'ca', 2276: 'de'}
country = location_map.get(location_code, 'us')
data = scavio_search(keyword, country)
# Convert to DataForSEO response format
items = []
for r in data.get('organic_results', []):
items.append({
'type': 'organic',
'rank_group': r.get('position', 0),
'rank_absolute': r.get('position', 0),
'domain': r.get('displayed_link', '').split('/')[0],
'title': r.get('title', ''),
'url': r.get('link', ''),
'description': r.get('snippet', ''),
'breadcrumb': r.get('displayed_link', ''),
})
# DataForSEO wraps in tasks[0].result[0].items
return {
'tasks': [{
'result': [{
'keyword': keyword,
'items_count': len(items),
'items': items,
}]
}]
}
# Your existing code works unchanged:
response = dataforseo_to_scavio('search api python')
items = response['tasks'][0]['result'][0]['items']
print(f'Migrated response: {len(items)} results')
for item in items[:3]:
print(f' #{item["rank_group"]} {item["domain"]:25} {item["title"][:40]}')Step 3: Validate the migration
Run your existing queries through both APIs and compare results to verify parity.
def validate_migration(keywords):
print(f'Validating migration for {len(keywords)} keywords...\n')
for kw in keywords:
# Call Scavio via the adapter
response = dataforseo_to_scavio(kw)
items = response['tasks'][0]['result'][0]['items']
# Verify structure
checks = {
'has_results': len(items) > 0,
'has_title': all(item.get('title') for item in items),
'has_url': all(item.get('url') for item in items),
'has_domain': all(item.get('domain') for item in items),
'has_rank': all(item.get('rank_group') for item in items),
}
all_pass = all(checks.values())
status = 'PASS' if all_pass else 'FAIL'
print(f' [{status}] {kw[:35]:35} | {len(items)} results')
if not all_pass:
for check, passed in checks.items():
if not passed:
print(f' FAILED: {check}')
print(f'\nMigration complete.')
print(f' Remove DataForSEO dependency and $50/mo minimum.')
print(f' Scavio: $0.005/query, 250 free/mo, no minimum.')
validate_migration(['search api python', 'web scraping api', 'serp data provider'])Python Example
import os, requests
SH = {'x-api-key': os.environ['SCAVIO_API_KEY'], 'Content-Type': 'application/json'}
# Before (DataForSEO): $50 minimum deposit required
# After (Scavio): No minimum, 250 free/mo
def search(keyword):
data = requests.post('https://api.scavio.dev/api/v1/search',
headers=SH, json={'query': keyword, 'country_code': 'us'}, timeout=10).json()
for r in data.get('organic_results', [])[:3]:
print(f'#{r.get("position", 0)} {r.get("title", "")[:50]}')
search('search api python')
print('Cost: $0.005. No minimum.')JavaScript Example
const SH = { 'x-api-key': process.env.SCAVIO_API_KEY, 'Content-Type': 'application/json' };
// Replace DataForSEO ($50 min) with Scavio (no min)
const data = await fetch('https://api.scavio.dev/api/v1/search', {
method: 'POST', headers: SH,
body: JSON.stringify({ query: 'search api python', country_code: 'us' })
}).then(r => r.json());
(data.organic_results || []).slice(0, 3).forEach((r, i) => {
console.log(`#${i+1} ${r.title}`);
});
console.log('Cost: $0.005. No minimum.');Expected Output
Results: 10
Pricing comparison:
DataForSEO: $0.002-0.004/query, $50 minimum deposit
Scavio: $0.005/query, no minimum, 250 free/mo
At 1K queries: DataForSEO $50 (minimum) vs Scavio $5
At 10K queries: DataForSEO $50 vs Scavio $50
Migrated response: 10 results
#1 scavio.dev Best Search API for AI Agents
#2 tavily.com Tavily Search - AI Optimized
Validating migration for 3 keywords...
[PASS] search api python | 10 results
[PASS] web scraping api | 10 results
[PASS] serp data provider | 10 results
Migration complete.