Add live search capabilities to your SaaS product by integrating a search API into your backend and exposing it through your own endpoints. This avoids shipping third-party API keys to the client and lets you enforce rate limits, caching, and access control at the application layer. Scavio's single-key multi-platform API simplifies this because one integration covers Google, YouTube, Amazon, Reddit, and Walmart results. This tutorial builds a production-ready search proxy with caching and per-user rate limiting.
Prerequisites
- A running backend service (Python/Flask, Express, or similar)
- A Scavio API key from scavio.dev
- Basic understanding of REST API design
- Redis or an in-memory cache (optional but recommended)
Walkthrough
Step 1: Create the search proxy endpoint
Build a backend endpoint that receives search requests from your frontend and proxies them through Scavio.
from flask import Flask, request, jsonify
import requests, os
app = Flask(__name__)
API_KEY = os.environ['SCAVIO_API_KEY']
@app.route('/api/search', methods=['POST'])
def search():
body = request.json
query = body.get('query', '')
platform = body.get('platform', 'google')
if not query:
return jsonify({'error': 'query required'}), 400
resp = requests.post('https://api.scavio.dev/api/v1/search',
headers={'x-api-key': API_KEY},
json={'platform': platform, 'query': query}, timeout=10)
return jsonify(resp.json()), resp.status_codeStep 2: Add response caching
Cache search results by query+platform key with a TTL to reduce API calls and improve response times for repeated queries.
from functools import lru_cache
import hashlib, time
cache = {}
CACHE_TTL = 300 # 5 minutes
def cached_search(query: str, platform: str) -> dict:
key = hashlib.md5(f'{platform}:{query}'.encode()).hexdigest()
if key in cache and time.time() - cache[key]['ts'] < CACHE_TTL:
return cache[key]['data']
resp = requests.post('https://api.scavio.dev/api/v1/search',
headers={'x-api-key': API_KEY},
json={'platform': platform, 'query': query}, timeout=10)
data = resp.json()
cache[key] = {'data': data, 'ts': time.time()}
return dataStep 3: Add per-user rate limiting
Limit how many searches each user can make per minute to protect your API credit budget.
from collections import defaultdict
rate_limits = defaultdict(list)
MAX_PER_MINUTE = 10
def check_rate_limit(user_id: str) -> bool:
now = time.time()
rate_limits[user_id] = [t for t in rate_limits[user_id] if now - t < 60]
if len(rate_limits[user_id]) >= MAX_PER_MINUTE:
return False
rate_limits[user_id].append(now)
return True
@app.route('/api/search', methods=['POST'])
def search_with_limits():
user_id = request.headers.get('X-User-Id', 'anon')
if not check_rate_limit(user_id):
return jsonify({'error': 'rate limit exceeded'}), 429
body = request.json
data = cached_search(body.get('query', ''), body.get('platform', 'google'))
return jsonify(data)Python Example
from flask import Flask, request, jsonify
import requests, os, time, hashlib
app = Flask(__name__)
API_KEY = os.environ['SCAVIO_API_KEY']
cache = {}
@app.route('/api/search', methods=['POST'])
def search():
q = request.json.get('query', '')
key = hashlib.md5(q.encode()).hexdigest()
if key in cache and time.time() - cache[key]['ts'] < 300:
return jsonify(cache[key]['data'])
resp = requests.post('https://api.scavio.dev/api/v1/search',
headers={'x-api-key': API_KEY}, json={'platform': 'google', 'query': q})
cache[key] = {'data': resp.json(), 'ts': time.time()}
return jsonify(cache[key]['data'])JavaScript Example
import express from 'express';
const app = express();
app.use(express.json());
const cache = new Map();
app.post('/api/search', async (req, res) => {
const {query, platform = 'google'} = req.body;
const key = `${platform}:${query}`;
const cached = cache.get(key);
if (cached && Date.now() - cached.ts < 300000) return res.json(cached.data);
const r = await fetch('https://api.scavio.dev/api/v1/search', {
method: 'POST',
headers: {'x-api-key': process.env.SCAVIO_API_KEY, 'Content-Type': 'application/json'},
body: JSON.stringify({platform, query})
});
const data = await r.json();
cache.set(key, {data, ts: Date.now()});
res.json(data);
});
app.listen(3000);Expected Output
A backend search proxy endpoint that caches results and enforces per-user rate limits, exposing Scavio search through your own SaaS API.