The Problem
Search API outages are rare but catastrophic for applications that depend on web data. A single provider going down for 30 minutes can mean 30 minutes of degraded service, failed agent responses, or broken user-facing features. Most teams only discover they need failover after their first outage, at which point they scramble to integrate a backup provider under pressure. Proactive failover design takes minimal effort but is rarely prioritized until it is too late.
The Scavio Solution
Build a provider-agnostic search layer with automatic failover before you need it. Define a primary and secondary provider with compatible query interfaces. Route all search calls through the failover layer. When the primary provider returns errors or exceeds latency thresholds, the layer automatically switches to the secondary. Add health checks to restore primary routing once it recovers.
Before
Before: An application used a single search API. During a 2-hour outage, all search-dependent features failed. The team spent the next sprint integrating a backup provider, diverting resources from the product roadmap. Total cost of the outage: $15,000 in lost revenue and engineering time.
After
After: A failover layer routes through Scavio (primary) and a backup provider (secondary). During the next provider outage, failover triggered automatically and zero user-facing features degraded. The standby provider costs $5/mo in keepalive traffic. The failover layer took 2 hours to build.
Who It Is For
SRE teams and engineering leads building resilient search infrastructure. Anyone who has experienced a search API outage and never wants it to happen again.
Key Benefits
- Zero-downtime search with automatic provider failover
- 2 hours to build, prevents $15K+ outage costs
- Standby provider costs $5-30/mo for keepalive health checks
- Health-check-based recovery automatically restores primary routing
- Provider-agnostic interface means adding a third provider takes 10 minutes
Python Example
import requests
import time
from typing import Optional
class SearchFailover:
def __init__(self, providers: list):
self.providers = providers
self.health = {p["name"]: True for p in providers}
self.last_check = {}
def search(self, query: str, platform: str = "google") -> Optional[dict]:
for provider in self.providers:
if not self.health.get(provider["name"], True):
if time.time() - self.last_check.get(provider["name"], 0) < 60:
continue # Skip unhealthy provider for 60s
try:
r = requests.post(
provider["url"],
headers={provider["header"]: provider["key"]},
json={"platform": platform, "query": query},
timeout=5,
)
if r.status_code == 200:
self.health[provider["name"]] = True
return {"provider": provider["name"], "data": r.json()}
self.health[provider["name"]] = False
self.last_check[provider["name"]] = time.time()
except Exception:
self.health[provider["name"]] = False
self.last_check[provider["name"]] = time.time()
return None
failover = SearchFailover([
{"name": "scavio", "url": "https://api.scavio.dev/api/v1/search", "header": "x-api-key", "key": "your_scavio_key"},
{"name": "backup", "url": "https://api.backup.dev/search", "header": "x-api-key", "key": "your_backup_key"},
])
result = failover.search("latest ai news 2026")
if result:
print(f"Provider: {result["provider"]}, Results: {len(result["data"].get("organic", []))}")JavaScript Example
class SearchFailover {
constructor(providers) {
this.providers = providers;
this.health = Object.fromEntries(providers.map(p => [p.name, true]));
this.lastCheck = {};
}
async search(query, platform = "google") {
for (const provider of this.providers) {
if (!this.health[provider.name] && Date.now() - (this.lastCheck[provider.name] || 0) < 60000) continue;
try {
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 5000);
const res = await fetch(provider.url, {
method: "POST",
headers: { [provider.header]: provider.key, "content-type": "application/json" },
body: JSON.stringify({ platform, query }),
signal: controller.signal,
});
clearTimeout(timeout);
if (res.ok) { this.health[provider.name] = true; return { provider: provider.name, data: await res.json() }; }
this.health[provider.name] = false;
this.lastCheck[provider.name] = Date.now();
} catch (e) { this.health[provider.name] = false; this.lastCheck[provider.name] = Date.now(); }
}
return null;
}
}
const failover = new SearchFailover([
{ name: "scavio", url: "https://api.scavio.dev/api/v1/search", header: "x-api-key", key: "your_scavio_key" },
{ name: "backup", url: "https://api.backup.dev/search", header: "x-api-key", key: "your_backup_key" },
]);
const result = await failover.search("latest ai news 2026");
if (result) console.log(`Provider: ${result.provider}, Results: ${(result.data.organic || []).length}`);Platforms Used
Web search with knowledge graph, PAA, and AI overviews
YouTube
Video search with transcripts and metadata
Amazon
Product search with prices, ratings, and reviews
Community, posts & threaded comments from any subreddit