The Problem
OpenWebUI ships with a web search toggle, but the default search backends (SearXNG, Tavily) return inconsistent results or fail silently when self-hosted instances hit rate limits. Users see 'I could not find information' errors mid-conversation. The search tool appears to work in test prompts but breaks under real multi-user load because the underlying SearXNG instance has no SLA and Tavily's free tier caps at 1,000 queries/month.
The Scavio Solution
Replace the default search backend in OpenWebUI with Scavio's API via a custom function tool or RAG pipeline. Scavio returns structured JSON with organic results, AI Overviews, and Knowledge Graph data on every call. The endpoint handles rate limiting, retries, and anti-bot mitigation server-side, so OpenWebUI gets clean results regardless of concurrent user count. Configure a fallback chain: Scavio primary, SearXNG secondary.
Before
Before the switch, OpenWebUI search failed 15-25% of the time during peak hours. Users lost trust in the search toggle and stopped using it, defaulting to copying queries into a separate browser tab.
After
After switching to Scavio, search failures dropped below 1%. Users rely on the search toggle for real-time questions, and the admin no longer maintains a SearXNG Docker instance.
Who It Is For
OpenWebUI self-hosters who need reliable web search grounding. Teams running OpenWebUI for internal knowledge work who cannot tolerate intermittent search failures.
Key Benefits
- Sub-1% failure rate replaces 15-25% failure with SearXNG
- Structured JSON response maps directly to OpenWebUI context format
- No SearXNG Docker instance to maintain or debug
- Free 250 queries/month covers personal use, $30/month covers teams
- AI Overview extraction gives OpenWebUI richer grounding context
Python Example
import requests
API_KEY = "your_scavio_api_key"
SEARXNG_URL = "http://localhost:8888/search" # fallback
def openwebui_search(query: str) -> list[dict]:
"""Primary: Scavio. Fallback: SearXNG."""
try:
res = requests.post(
"https://api.scavio.dev/api/v1/search",
headers={"x-api-key": API_KEY},
json={"platform": "google", "query": query, "ai_overview": True},
timeout=10,
)
res.raise_for_status()
data = res.json()
results = []
if data.get("ai_overview"):
results.append({"title": "AI Overview", "snippet": data["ai_overview"]["text"], "link": ""})
for r in data.get("organic", [])[:5]:
results.append({"title": r.get("title", ""), "snippet": r.get("snippet", ""), "link": r.get("link", "")})
return results
except Exception:
# Fallback to SearXNG
res = requests.get(SEARXNG_URL, params={"q": query, "format": "json"}, timeout=10)
return [{"title": r["title"], "snippet": r.get("content", ""), "link": r["url"]} for r in res.json().get("results", [])[:5]]
results = openwebui_search("latest openwebui release 2026")
for r in results:
print(f"{r["title"]}: {r["snippet"][:80]}")JavaScript Example
const API_KEY = "your_scavio_api_key";
async function openwebuiSearch(query) {
try {
const res = await fetch("https://api.scavio.dev/api/v1/search", {
method: "POST",
headers: { "x-api-key": API_KEY, "content-type": "application/json" },
body: JSON.stringify({ platform: "google", query, ai_overview: true }),
});
if (!res.ok) throw new Error(`scavio ${res.status}`);
const data = await res.json();
const results = [];
if (data.ai_overview) results.push({ title: "AI Overview", snippet: data.ai_overview.text, link: "" });
for (const r of (data.organic ?? []).slice(0, 5)) results.push({ title: r.title ?? "", snippet: r.snippet ?? "", link: r.link ?? "" });
return results;
} catch {
const res = await fetch(`http://localhost:8888/search?q=${encodeURIComponent(query)}&format=json`);
const data = await res.json();
return (data.results ?? []).slice(0, 5).map((r) => ({ title: r.title, snippet: r.content ?? "", link: r.url }));
}
}
const results = await openwebuiSearch("latest openwebui release 2026");
results.forEach((r) => console.log(`${r.title}: ${r.snippet.slice(0, 80)}`));Platforms Used
Web search with knowledge graph, PAA, and AI overviews