OpenWebUI supports web search through Tavily, SearXNG, and custom endpoints. After Nebius acquired Tavily in February 2026, many users want an alternative. Scavio provides a compatible search endpoint that covers Google, Amazon, YouTube, Walmart, Reddit, and TikTok. This tutorial shows how to configure OpenWebUI to use Scavio for web search grounding, either through the built-in search settings or via a custom function tool.
Prerequisites
- OpenWebUI installed and running
- A Scavio API key from scavio.dev
- Python 3.9+ for the custom function approach
- Admin access to your OpenWebUI instance
Walkthrough
Step 1: Create a Scavio search function for OpenWebUI
OpenWebUI supports custom Python functions as tools. Create a search function that calls the Scavio API and returns formatted results the LLM can use.
# OpenWebUI Function Tool: scavio_search.py
# Add this as a Function in OpenWebUI Admin > Functions
import os
import requests
from typing import Optional
class Tools:
def __init__(self):
self.api_key = os.environ.get('SCAVIO_API_KEY', '')
self.base_url = 'https://api.scavio.dev/api/v1/search'
def search_web(self, query: str, num_results: Optional[int] = 5) -> str:
"""Search the web for current information using Scavio.
Returns titles, snippets, and source URLs.
"""
try:
resp = requests.post(self.base_url,
headers={'x-api-key': self.api_key,
'Content-Type': 'application/json'},
json={'query': query, 'country_code': 'us',
'num_results': num_results or 5},
timeout=10)
resp.raise_for_status()
results = resp.json().get('organic_results', [])
if not results:
return 'No results found.'
return '\n\n'.join(
f'[{i+1}] {r["title"]}\n{r.get("snippet", "")}\nSource: {r["link"]}'
for i, r in enumerate(results)
)
except Exception as e:
return f'Search error: {str(e)}'Step 2: Add platform-specific search tools
Extend the function with tools for Reddit, YouTube, and Amazon search. OpenWebUI will show each as a separate tool the LLM can call.
# Extended Tools class with platform-specific methods
class Tools:
def __init__(self):
self.api_key = os.environ.get('SCAVIO_API_KEY', '')
self.base_url = 'https://api.scavio.dev/api/v1/search'
self.headers = {'x-api-key': self.api_key, 'Content-Type': 'application/json'}
def _search(self, query: str, num: int = 5) -> list:
resp = requests.post(self.base_url, headers=self.headers,
json={'query': query, 'country_code': 'us', 'num_results': num}, timeout=10)
resp.raise_for_status()
return resp.json().get('organic_results', [])
def search_web(self, query: str) -> str:
"""Search the web for current information."""
results = self._search(query)
return '\n\n'.join(f'[{i+1}] {r["title"]}\n{r.get("snippet","")}\nURL: {r["link"]}'
for i, r in enumerate(results)) or 'No results.'
def search_reddit(self, query: str) -> str:
"""Search Reddit for community discussions and opinions."""
results = self._search(f'site:reddit.com {query}')
return '\n\n'.join(f'[{i+1}] {r["title"]}\n{r.get("snippet","")}\nURL: {r["link"]}'
for i, r in enumerate(results)) or 'No Reddit results.'
def search_youtube(self, query: str) -> str:
"""Search YouTube for videos on a topic."""
results = self._search(f'site:youtube.com {query}')
return '\n\n'.join(f'[{i+1}] {r["title"]}\nURL: {r["link"]}'
for i, r in enumerate(results)) or 'No YouTube results.'
def search_amazon(self, query: str) -> str:
"""Search Amazon for product information."""
results = self._search(f'site:amazon.com {query}')
return '\n\n'.join(f'[{i+1}] {r["title"]}\n{r.get("snippet","")}\nURL: {r["link"]}'
for i, r in enumerate(results)) or 'No Amazon results.'Step 3: Configure the environment and deploy
Set the SCAVIO_API_KEY environment variable in your OpenWebUI deployment and add the function through the admin panel.
# Docker deployment: add to your docker-compose.yml or .env
# SCAVIO_API_KEY=your_key_here
# Or set in the OpenWebUI admin panel:
# 1. Go to Admin Panel > Functions
# 2. Click 'Create Function'
# 3. Paste the Tools class code
# 4. Set the function name to 'scavio_search'
# 5. Enable it globally or per-model
# Verify the setup with a test
import os, requests
def verify_openwebui_search():
key = os.environ.get('SCAVIO_API_KEY')
if not key:
print('ERROR: SCAVIO_API_KEY not set')
return False
tools = Tools()
result = tools.search_web('test query 2026')
if 'error' in result.lower():
print(f'ERROR: {result}')
return False
print('OpenWebUI search configured successfully')
print(f'Test result preview: {result[:150]}')
return True
verify_openwebui_search()Step 4: Test multi-platform queries in OpenWebUI
Verify that each platform search works correctly by running test queries. The LLM should automatically choose the right search tool based on the user question.
# Test all search functions
def test_all_tools():
tools = Tools()
tests = [
('search_web', 'latest AI news 2026'),
('search_reddit', 'best mechanical keyboard'),
('search_youtube', 'python tutorial beginners'),
('search_amazon', 'noise cancelling headphones'),
]
for method_name, query in tests:
method = getattr(tools, method_name)
result = method(query)
lines = result.split('\n')
has_results = len(lines) > 1
print(f'[{"PASS" if has_results else "FAIL"}] {method_name}')
print(f' Query: {query}')
print(f' First result: {lines[0][:60]}')
print()
test_all_tools()
print('All tools ready for OpenWebUI')
print('Cost: $0.005 per search (250 free/month)')Python Example
import os, requests
class ScavioOpenWebUI:
def __init__(self):
self.key = os.environ.get('SCAVIO_API_KEY', '')
self.url = 'https://api.scavio.dev/api/v1/search'
self.h = {'x-api-key': self.key, 'Content-Type': 'application/json'}
def search(self, query, num=5):
resp = requests.post(self.url, headers=self.h,
json={'query': query, 'country_code': 'us', 'num_results': num})
return resp.json().get('organic_results', [])
def search_web(self, query):
results = self.search(query)
return '\n'.join(f'[{i+1}] {r["title"]}: {r.get("snippet","")}' for i, r in enumerate(results))
def search_reddit(self, query):
return self.search_web(f'site:reddit.com {query}')
tools = ScavioOpenWebUI()
print(tools.search_web('AI news 2026'))JavaScript Example
const SCAVIO_KEY = process.env.SCAVIO_API_KEY;
async function searchForOpenWebUI(query, platform = 'web') {
const prefixes = { reddit: 'site:reddit.com ', youtube: 'site:youtube.com ', amazon: 'site:amazon.com ' };
const q = (prefixes[platform] || '') + query;
const resp = await fetch('https://api.scavio.dev/api/v1/search', {
method: 'POST',
headers: { 'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({ query: q, country_code: 'us', num_results: 5 })
});
const results = (await resp.json()).organic_results || [];
return results.map((r, i) => `[${i+1}] ${r.title}\n${r.snippet || ''}\n${r.link}`).join('\n\n');
}
searchForOpenWebUI('AI agent tools 2026').then(console.log);Expected Output
[PASS] search_web
Query: latest AI news 2026
First result: [1] AI News: Latest Developments in Artificial
[PASS] search_reddit
Query: best mechanical keyboard
First result: [1] r/MechanicalKeyboards - Best keyboards mid-2
[PASS] search_youtube
Query: python tutorial beginners
First result: [1] Python Tutorial for Beginners - Full Course
[PASS] search_amazon
Query: noise cancelling headphones
First result: [1] Sony WH-1000XM6 Wireless Noise Cancelling
All tools ready for OpenWebUI
Cost: $0.005 per search (250 free/month)