The Problem
SearXNG, the default web search backend for OpenWebUI, is fragile in self-hosted setups. It breaks on rate limits from upstream search engines, returns inconsistent results, and requires its own server to maintain. Many OpenWebUI users disable web search entirely because SearXNG is too unreliable.
The Scavio Solution
Create a custom Function tool in OpenWebUI that calls the Scavio search API directly. Replace the SearXNG dependency with a single Python function that returns reliable, structured results.
Before
OpenWebUI user enables web search. SearXNG returns empty results or 503 errors during peak hours. User disables web search because it's unreliable. Local Llama model reverts to training data for current events questions.
After
Custom Scavio function tool is enabled in OpenWebUI. Web search works reliably on every request. Results are structured and accurate. Local Llama can answer current events questions with live data. No SearXNG maintenance.
Who It Is For
OpenWebUI self-hosters who have given up on SearXNG and want a reliable, drop-in replacement for web search in their local LLM setup.
Key Benefits
- Reliable search versus SearXNG's upstream rate limit issues
- Multi-platform search (Google, Amazon, Reddit, YouTube) in one tool
- No separate SearXNG server to maintain
- API key configured via OpenWebUI Valve settings UI
Python Example
# Paste this into OpenWebUI > Workspace > Functions > New Function (Tool type)
import requests
from pydantic import BaseModel, Field
class Tools:
class Valves(BaseModel):
SCAVIO_API_KEY: str = Field(default="", description="Scavio API key from scavio.dev")
def __init__(self):
self.valves = self.Valves()
def web_search(self, query: str, platform: str = "google") -> str:
"""
Search the web for current information.
:param query: Search query
:param platform: google, amazon, reddit, or youtube
:return: Top 5 search results as formatted text
"""
r = requests.post(
"https://api.scavio.dev/api/v1/search",
json={"query": query, "platform": platform, "num_results": 5},
headers={"x-api-key": self.valves.SCAVIO_API_KEY},
timeout=15
)
r.raise_for_status()
results = r.json().get("organic_results", [])
if not results:
return "No results found."
return "\n\n".join(f"{i+1}. {r.get('title')}\n{r.get('snippet','')}\n{r.get('link')}" for i, r in enumerate(results))JavaScript Example
// Test the search call before deploying to OpenWebUI
async function webSearch(query, platform = 'google') {
const res = await fetch('https://api.scavio.dev/api/v1/search', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'x-api-key': 'your-scavio-api-key' },
body: JSON.stringify({ query, platform, num_results: 5 })
});
const data = await res.json();
return (data.organic_results ?? []).map((r, i) => `${i+1}. ${r.title}\n${r.snippet ?? ''}\n${r.link}`).join('\n\n');
}
console.log(await webSearch('latest AI news'));Platforms Used
Web search with knowledge graph, PAA, and AI overviews
Amazon
Product search with prices, ratings, and reviews
Community, posts & threaded comments from any subreddit
YouTube
Video search with transcripts and metadata