SERP APIs charge in four fundamentally different ways: per-search (SerpAPI), credit packs with expiry (Serper.dev), per-credit flat rate (Scavio), and queue-vs-live tiers (DataForSEO). The billing model you pick determines whether your cost scales linearly with usage or penalizes you for idle months. This tutorial builds a cost calculator that takes your monthly query volume, latency tolerance, and platform needs, then outputs the cheapest option with exact dollar amounts.
Prerequisites
- Python 3.8+ or Node.js 18+
- Basic understanding of SERP API pricing tiers
- Your estimated monthly query volume
Walkthrough
Step 1: Define pricing models as structured data
Encode each API's pricing tiers, per-query costs, and constraints into a data structure your calculator can evaluate.
import json
PRICING_MODELS = {
'scavio': {
'model': 'per_credit',
'per_query': 0.005,
'plans': [
{'name': 'Free', 'monthly': 0, 'credits': 250},
{'name': 'Project', 'monthly': 30, 'credits': 7000},
{'name': 'Bootstrap', 'monthly': 100, 'credits': 28000},
{'name': 'Startup', 'monthly': 250, 'credits': 85000},
{'name': 'Growth', 'monthly': 500, 'credits': 200000},
],
'overage': 0.005,
'platforms': ['google', 'amazon', 'youtube', 'walmart', 'reddit', 'tiktok'],
},
'dataforseo': {
'model': 'queue_tiers',
'tiers': [
{'name': 'Standard Queue', 'per_query': 0.0006, 'latency_min': 5},
{'name': 'Priority Queue', 'per_query': 0.0012, 'latency_min': 1},
{'name': 'Live', 'per_query': 0.002, 'latency_min': 0},
],
'min_deposit': 50,
'platforms': ['google'],
},
'serper': {
'model': 'credit_packs',
'packs': [
{'credits': 50000, 'price': 50, 'per_query': 0.001},
{'credits': 500000, 'price': 375, 'per_query': 0.00075},
],
'expiry_months': 6,
'platforms': ['google'],
},
'serpapi': {
'model': 'subscription',
'plans': [
{'name': 'Free', 'monthly': 0, 'searches': 100},
{'name': 'Starter', 'monthly': 25, 'searches': 1000},
{'name': 'Business', 'monthly': 275, 'searches': 30000},
],
'platforms': ['google', 'bing', 'yahoo', 'baidu'],
},
}Step 2: Build the cost calculation engine
For each API, calculate the monthly cost at a given query volume. Handle plan selection, overage, pack sizing, and queue tier optimization.
def calculate_cost(api_name, monthly_queries, need_realtime=True):
api = PRICING_MODELS[api_name]
model = api['model']
if model == 'per_credit':
best_cost = float('inf')
best_plan = None
for plan in api['plans']:
if monthly_queries <= plan['credits']:
cost = plan['monthly']
else:
cost = plan['monthly'] + (monthly_queries - plan['credits']) * api['overage']
if cost < best_cost:
best_cost = cost
best_plan = plan['name']
return {'api': api_name, 'plan': best_plan, 'monthly_cost': round(best_cost, 2)}
elif model == 'queue_tiers':
tier = api['tiers'][0] if not need_realtime else api['tiers'][-1]
cost = max(monthly_queries * tier['per_query'], api['min_deposit'])
return {'api': api_name, 'plan': tier['name'], 'monthly_cost': round(cost, 2)}
elif model == 'credit_packs':
best_pack = api['packs'][0]
for pack in api['packs']:
if monthly_queries * api['expiry_months'] <= pack['credits']:
best_pack = pack
break
monthly_cost = best_pack['price'] / api['expiry_months']
return {'api': api_name, 'plan': f"{best_pack['credits']:,} pack", 'monthly_cost': round(monthly_cost, 2)}
elif model == 'subscription':
best_plan = api['plans'][-1]
for plan in api['plans']:
if monthly_queries <= plan['searches']:
best_plan = plan
break
return {'api': api_name, 'plan': best_plan['name'], 'monthly_cost': best_plan['monthly']}Step 3: Compare all APIs and rank by cost
Run the calculator across all APIs for your volume and output a ranked comparison.
def compare_all(monthly_queries, need_realtime=True):
results = []
for api_name in PRICING_MODELS:
result = calculate_cost(api_name, monthly_queries, need_realtime)
result['per_query'] = round(result['monthly_cost'] / max(monthly_queries, 1), 5)
results.append(result)
results.sort(key=lambda x: x['monthly_cost'])
print(f'Cost comparison for {monthly_queries:,} queries/month (realtime={need_realtime}):')
for i, r in enumerate(results):
marker = ' << CHEAPEST' if i == 0 else ''
print(f" {r['api']:12} | {r['plan']:20} | ${r['monthly_cost']:>8.2f}/mo{marker}")
return results
compare_all(5000, need_realtime=True)
compare_all(50000, need_realtime=False)Step 4: Validate with a live API test call
Run a test query against the Scavio API to confirm one credit equals one request regardless of platform.
import os, requests
API_KEY = os.environ['SCAVIO_API_KEY']
def test_pricing():
for platform in ['google', 'amazon', 'youtube']:
body = {'query': 'test', 'platform': platform, 'country_code': 'us'}
if platform == 'amazon': body['marketplace'] = 'US'
resp = requests.post('https://api.scavio.dev/api/v1/search',
headers={'x-api-key': API_KEY, 'Content-Type': 'application/json'}, json=body)
print(f'{platform}: {resp.status_code}, {len(resp.json().get("organic_results", resp.json().get("products", [])))} results')
print('Total: 3 credits ($0.015)')
test_pricing()Python Example
import os, requests
API_KEY = os.environ['SCAVIO_API_KEY']
H = {'x-api-key': API_KEY, 'Content-Type': 'application/json'}
PRICING = {
'scavio': lambda q: min(p['mo'] + max(0, q - p['cr']) * 0.005
for p in [{'mo': 0, 'cr': 250}, {'mo': 30, 'cr': 7000}, {'mo': 100, 'cr': 28000}]),
'dataforseo_queue': lambda q: max(q * 0.0006, 50),
'serper': lambda q: 50 / 6 if q * 6 <= 50000 else 375 / 6,
'serpapi': lambda q: 0 if q <= 100 else 25 if q <= 1000 else 275,
}
def compare(queries):
costs = {k: round(v(queries), 2) for k, v in PRICING.items()}
for k, v in sorted(costs.items(), key=lambda x: x[1]):
print(f'{k:20}: ${v:.2f}/mo')
compare(5000)
compare(50000)JavaScript Example
const PRICING = {
scavio: (q) => Math.min(
...[{ mo: 0, cr: 250 }, { mo: 30, cr: 7000 }, { mo: 100, cr: 28000 }]
.map(p => p.mo + Math.max(0, q - p.cr) * 0.005)
),
dataforseo_queue: (q) => Math.max(q * 0.0006, 50),
serper: (q) => q * 6 <= 50000 ? 50 / 6 : 375 / 6,
serpapi: (q) => q <= 100 ? 0 : q <= 1000 ? 25 : 275,
};
function compare(queries) {
console.log(`--- ${queries.toLocaleString()} queries/mo ---`);
Object.entries(PRICING)
.map(([k, v]) => ({ api: k, cost: Math.round(v(queries) * 100) / 100 }))
.sort((a, b) => a.cost - b.cost)
.forEach(c => console.log(` ${c.api.padEnd(20)} $${c.cost.toFixed(2)}/mo`));
}
compare(5000);
compare(50000);Expected Output
Cost comparison for 5,000 queries/month (realtime=True):
serper | 50,000 pack | $8.33/mo << CHEAPEST
scavio | Project | $30.00/mo
dataforseo | Live | $50.00/mo
serpapi | Business | $275.00/mo
Cost comparison for 50,000 queries/month (realtime=False):
dataforseo | Standard Queue | $50.00/mo << CHEAPEST
serper | 500,000 pack | $62.50/mo
scavio | Growth | $500.00/mo
serpapi | Business | $275.00/mo