Overview
Google CSE is closed to new signups and the 'search entire web' feature ends January 1, 2027. Teams still on CSE need to migrate before that deadline. This workflow audits your existing CSE integration, maps CSE parameters to Scavio API fields, runs parallel queries to verify result parity, and switches over with zero downtime. The API format is close enough that most CSE parsing code works with minimal changes.
Trigger
One-time migration, triggered manually when migration is scheduled.
Schedule
One-time
Workflow Steps
Audit Existing CSE Usage
Catalog every CSE query in your codebase: endpoints, parameters, result fields consumed, and daily call volume.
Map CSE Parameters to Scavio API
Map CSE cx, q, num, start, gl, lr to Scavio query, country_code, and pagination fields.
Parallel Test Queries
Run 50 sample queries against both CSE and Scavio in parallel. Compare result overlap and field coverage.
Update Response Parsing
Adjust JSON parsing from CSE items[] format to Scavio organic_results[] format. Most fields map directly.
Switch Traffic and Monitor
Route production traffic to Scavio. Keep CSE as a fallback for 48 hours, then decommission.
Python Implementation
import requests, os, json
API_KEY = os.environ["SCAVIO_API_KEY"]
H = {"x-api-key": API_KEY, "Content-Type": "application/json"}
# Map a CSE query to Scavio format
def cse_to_scavio(cse_params: dict) -> dict:
return {
"query": cse_params.get("q", ""),
"country_code": cse_params.get("gl", "us"),
}
# Run a Scavio search with the mapped params
def search_scavio(params: dict) -> dict:
resp = requests.post(
"https://api.scavio.dev/api/v1/search",
headers=H,
json=params,
timeout=15,
)
resp.raise_for_status()
return resp.json()
# Migrate a batch of CSE queries
def migration_test(cse_queries: list) -> list:
results = []
for cse_q in cse_queries:
scavio_params = cse_to_scavio(cse_q)
data = search_scavio(scavio_params)
organic = data.get("organic_results", [])
results.append({
"query": cse_q["q"],
"scavio_count": len(organic),
"has_knowledge_graph": "knowledge_graph" in data,
"has_ai_overview": "ai_overview" in data,
"top_result": organic[0].get("title", "") if organic else "N/A",
})
return results
test_queries = [
{"q": "best crm software 2026", "gl": "us"},
{"q": "kubernetes monitoring tools", "gl": "us"},
{"q": "react server components guide", "gl": "us"},
]
report = migration_test(test_queries)
for r in report:
print(f"{r['query']}: {r['scavio_count']} results, KG={r['has_knowledge_graph']}, AIO={r['has_ai_overview']}")JavaScript Implementation
const H = {'x-api-key': process.env.SCAVIO_API_KEY, 'Content-Type': 'application/json'};
function cseToScavio(cseParams) {
return {query: cseParams.q || '', country_code: cseParams.gl || 'us'};
}
async function searchScavio(params) {
const r = await fetch('https://api.scavio.dev/api/v1/search', {method:'POST', headers:H, body:JSON.stringify(params)});
return r.json();
}
async function migrationTest(cseQueries) {
const results = [];
for (const cse of cseQueries) {
const params = cseToScavio(cse);
const data = await searchScavio(params);
const organic = data.organic_results || [];
results.push({query:cse.q, scavioCount:organic.length, hasKg:'knowledge_graph' in data, hasAio:'ai_overview' in data, topResult:organic[0]?.title || 'N/A'});
}
return results;
}
const testQueries = [
{q:'best crm software 2026', gl:'us'},
{q:'kubernetes monitoring tools', gl:'us'},
{q:'react server components guide', gl:'us'},
];
const report = await migrationTest(testQueries);
for (const r of report) console.log(r.query+': '+r.scavioCount+' results, KG='+r.hasKg+', AIO='+r.hasAio);Platforms Used
Web search with knowledge graph, PAA, and AI overviews