Many agent setups accumulate search tools over time: Brave for web search, Exa for academic papers, Serper for Google, and custom scrapers for specific sites. Each adds its own API key, rate limit, response format, and billing. Consolidating to a single search API simplifies your agent architecture, reduces failure modes, and often cuts costs. The Scavio API covers Google web, maps, images, shopping, YouTube, Amazon, and TikTok through one endpoint and one API key. This tutorial shows how to migrate a multi-API agent to a single backend.
Prerequisites
- Python 3.9+ installed
- An existing agent with multiple search tools
- A Scavio API key from scavio.dev
- Understanding of your current search tool usage
Walkthrough
Step 1: Audit your current search tool stack
List every search API your agent uses, its purpose, monthly cost, and call volume. This reveals which tools can be consolidated.
# Common multi-API agent stack:
current_stack = [
{'tool': 'Brave Search', 'purpose': 'Web search', 'cost': '$5/1K queries',
'monthly_calls': 2000, 'monthly_cost': 10.0},
{'tool': 'Serper', 'purpose': 'Google SERP', 'cost': '$50/mo Pro',
'monthly_calls': 5000, 'monthly_cost': 50.0},
{'tool': 'Exa', 'purpose': 'Research search', 'cost': '$5/1K',
'monthly_calls': 500, 'monthly_cost': 2.5},
{'tool': 'Custom scraper', 'purpose': 'Amazon prices', 'cost': 'Server + proxy',
'monthly_calls': 1000, 'monthly_cost': 30.0},
]
total_calls = sum(t['monthly_calls'] for t in current_stack)
total_cost = sum(t['monthly_cost'] for t in current_stack)
print(f'Current: {len(current_stack)} APIs, {total_calls:,} calls/mo, ${total_cost:.2f}/mo')
consolidated_cost = total_calls * 0.005
print(f'Consolidated: 1 API, {total_calls:,} calls/mo, ${consolidated_cost:.2f}/mo')
print(f'Savings: ${total_cost - consolidated_cost:.2f}/mo ({((total_cost - consolidated_cost) / total_cost * 100):.0f}%)')Step 2: Build the unified search interface
Create a single function that routes different search types through one API. Web search, maps, shopping, and YouTube all use the same endpoint with different parameters.
import requests, os
API_KEY = os.environ['SCAVIO_API_KEY']
SEARCH_URL = 'https://api.scavio.dev/api/v1/search'
TIKTOK_URL = 'https://api.scavio.dev/api/v1/tiktok'
def unified_search(query: str, search_type: str = 'web', **kwargs) -> dict:
"""Single search function replacing multiple APIs."""
if search_type == 'tiktok':
endpoint = kwargs.get('endpoint', 'search/videos')
resp = requests.post(f'{TIKTOK_URL}/{endpoint}',
headers={'Authorization': f'Bearer {API_KEY}',
'Content-Type': 'application/json'},
json={'keyword': query, 'count': 10, 'cursor': 0})
else:
body = {'query': query, 'country_code': kwargs.get('country', 'us')}
if search_type != 'web':
body['platform'] = search_type
resp = requests.post(SEARCH_URL,
headers={'x-api-key': API_KEY, 'Content-Type': 'application/json'},
json=body)
resp.raise_for_status()
return resp.json()Step 3: Create drop-in replacements for each old tool
Write wrapper functions that match the signatures of your old tools so migration requires minimal code changes.
# Replace Brave Search:
def brave_search_replacement(query: str) -> list:
data = unified_search(query, 'web')
return [{'title': r['title'], 'url': r['link'], 'description': r.get('snippet', '')}
for r in data.get('organic_results', [])]
# Replace Serper:
def serper_replacement(query: str) -> dict:
data = unified_search(query, 'web')
return {'organic': data.get('organic_results', []),
'peopleAlsoAsk': data.get('people_also_ask', [])}
# Replace custom Amazon scraper:
def amazon_search_replacement(query: str) -> list:
data = unified_search(query, 'amazon')
return data.get('products', [])
# Test all replacements:
for name, fn, q in [
('Web', brave_search_replacement, 'best crm 2026'),
('SERP', serper_replacement, 'crm pricing'),
('Amazon', amazon_search_replacement, 'crm software book'),
]:
result = fn(q)
count = len(result) if isinstance(result, list) else len(result.get('organic', []))
print(f'{name}: {count} results')Step 4: Update your agent tool definitions
Replace the old tool definitions with the new unified ones. The agent's tool-calling behavior stays the same -- only the backend changes.
# Before: multiple tool definitions with different auth
# tools = [brave_tool, serper_tool, exa_tool, amazon_scraper]
# After: one tool with type parameter
from langchain.tools import tool
@tool
def search(query: str, search_type: str = 'web') -> str:
"""Search the web, Amazon, YouTube, Maps, or TikTok.
Use search_type: web, amazon, youtube, maps, or tiktok."""
data = unified_search(query, search_type)
if search_type == 'web':
results = data.get('organic_results', [])[:5]
return '\n'.join(f'{r["title"]}: {r["link"]}' for r in results)
elif search_type == 'amazon':
products = data.get('products', [])[:5]
return '\n'.join(f'{p.get("title", "")}: {p.get("price", "")}' for p in products)
return str(data)
# Register single tool instead of four:
# agent = create_agent(llm, tools=[search])Python Example
import os, requests
API_KEY = os.environ['SCAVIO_API_KEY']
def unified_search(query: str, search_type: str = 'web') -> dict:
if search_type == 'tiktok':
resp = requests.post('https://api.scavio.dev/api/v1/tiktok/search/videos',
headers={'Authorization': f'Bearer {API_KEY}', 'Content-Type': 'application/json'},
json={'keyword': query, 'count': 10, 'cursor': 0})
else:
body = {'query': query, 'country_code': 'us'}
if search_type != 'web': body['platform'] = search_type
resp = requests.post('https://api.scavio.dev/api/v1/search',
headers={'x-api-key': API_KEY, 'Content-Type': 'application/json'}, json=body)
return resp.json()
def main():
for stype, query in [('web', 'best crm 2026'), ('amazon', 'crm book'), ('tiktok', 'crm tips')]:
data = unified_search(query, stype)
print(f'{stype}: {query} -> got response')
if __name__ == '__main__':
main()JavaScript Example
const API_KEY = process.env.SCAVIO_API_KEY;
async function unifiedSearch(query, type = 'web') {
if (type === 'tiktok') {
const resp = await fetch('https://api.scavio.dev/api/v1/tiktok/search/videos', {
method: 'POST',
headers: { 'Authorization': `Bearer ${API_KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ keyword: query, count: 10, cursor: 0 })
});
return resp.json();
}
const body = { query, country_code: 'us' };
if (type !== 'web') body.platform = type;
const resp = await fetch('https://api.scavio.dev/api/v1/search', {
method: 'POST',
headers: { 'x-api-key': API_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify(body)
});
return resp.json();
}
async function main() {
for (const [type, q] of [['web', 'best crm'], ['amazon', 'crm book']]) {
const data = await unifiedSearch(q, type);
console.log(`${type}: got response`);
}
}
main().catch(console.error);Expected Output
Current: 4 APIs, 8,500 calls/mo, $92.50/mo
Consolidated: 1 API, 8,500 calls/mo, $42.50/mo
Savings: $50.00/mo (54%)
Web: 10 results
SERP: 10 results
Amazon: 8 results