Tutorial

How to Add a Search API to Your SaaS Product

Integrate the Scavio search API into your SaaS backend to power live search features. Python and JS examples with caching and rate limiting.

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.

Python
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_code

Step 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.

Python
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 data

Step 3: Add per-user rate limiting

Limit how many searches each user can make per minute to protect your API credit budget.

Python
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

Python
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

JavaScript
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

JSON
A backend search proxy endpoint that caches results and enforces per-user rate limits, exposing Scavio search through your own SaaS API.

Related Tutorials

Frequently Asked Questions

Most developers complete this tutorial in 15 to 30 minutes. You will need a Scavio API key (free tier works) and a working Python or JavaScript environment.

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). A Scavio API key gives you 500 free credits per month.

Yes. The free tier includes 500 credits per month, which is more than enough to complete this tutorial and prototype a working solution.

Scavio has a native LangChain package (langchain-scavio), an MCP server, and a plain REST API that works with any HTTP client. This tutorial uses the raw REST API, but you can adapt to your framework of choice.

Start Building

Integrate the Scavio search API into your SaaS backend to power live search features. Python and JS examples with caching and rate limiting.