The Problem
Developers building search-powered prototypes burn through a single provider's free tier in days. Switching providers means rewriting API calls and parsing logic. Most free tiers are too small for proper testing: Tavily gives 1K/month, Brave gives $5 credit, Scavio gives 250 credits. No single free tier is enough for development.
The Scavio Solution
Stack free tiers across providers with a rotation wrapper. Scavio's 250 free credits/month, Tavily's 1K free queries/month, and Brave's $5 monthly credit combine to give 2K+ free searches for prototyping. The wrapper tries each provider in order and normalizes responses into a common schema.
Before
Developer uses Tavily free tier. Runs out in 3 days of active development. Switches to Brave, rewrites parsing code. Runs out again. Development stalls.
After
Rotation wrapper stacks 3 free tiers. 2K+ free searches per month. Common response schema. Development continues without interruption.
Who It Is For
Developers in the prototyping phase who want to maximize free search API usage before committing to a paid plan.
Key Benefits
- 2K+ free searches/month across stacked providers
- Normalized response schema across providers
- Automatic fallback when one tier is exhausted
- Zero cost during prototyping phase
- Easy migration to paid tier when ready
Python Example
import requests, os, json
from pathlib import Path
SCAVIO_KEY = os.environ.get("SCAVIO_API_KEY", "")
USAGE_FILE = Path("free_tier_usage.json")
def load_usage() -> dict:
if USAGE_FILE.exists():
return json.loads(USAGE_FILE.read_text())
return {"scavio": 0, "scavio_limit": 250}
def save_usage(usage: dict):
USAGE_FILE.write_text(json.dumps(usage))
def scavio_free(query: str) -> dict:
resp = requests.post(
"https://api.scavio.dev/api/v1/search",
headers={"x-api-key": SCAVIO_KEY, "Content-Type": "application/json"},
json={"query": query, "country_code": "us"},
timeout=10,
)
if resp.status_code == 200:
data = resp.json()
return {"provider": "scavio", "results": data.get("organic_results", [])}
return None
def rotate_search(query: str) -> dict:
usage = load_usage()
# Try Scavio first (250 free/month)
if usage["scavio"] < usage["scavio_limit"] and SCAVIO_KEY:
result = scavio_free(query)
if result:
usage["scavio"] += 1
save_usage(usage)
return result
return {"provider": "exhausted", "results": []}
result = rotate_search("fastapi deployment best practices")
print(f"Provider: {result['provider']}, Results: {len(result['results'])}")JavaScript Example
const H = {'x-api-key': process.env.SCAVIO_API_KEY, 'Content-Type': 'application/json'};
const fs = await import('fs');
function loadUsage() {
try { return JSON.parse(fs.readFileSync('free_tier_usage.json','utf8')); } catch { return {scavio:0, scavioLimit:250}; }
}
function saveUsage(u) { fs.writeFileSync('free_tier_usage.json', JSON.stringify(u)); }
async function scavioFree(query) {
const r = await fetch('https://api.scavio.dev/api/v1/search', {method:'POST', headers:H, body:JSON.stringify({query, country_code:'us'})});
if (r.ok) { const d = await r.json(); return {provider:'scavio', results:d.organic_results||[]}; }
return null;
}
async function rotateSearch(query) {
const usage = loadUsage();
if (usage.scavio < usage.scavioLimit) {
const r = await scavioFree(query);
if (r) { usage.scavio++; saveUsage(usage); return r; }
}
return {provider:'exhausted', results:[]};
}
const r = await rotateSearch('fastapi deployment best practices');
console.log('Provider: '+r.provider+', Results: '+r.results.length);Platforms Used
Web search with knowledge graph, PAA, and AI overviews