Overview
This pipeline serves as the search layer for an agents-as-a-service platform, handling multi-tenant search requests with per-tenant credit tracking and rate limiting. Each tenant's agent submits search requests through this pipeline, which routes them to Scavio, tracks credit usage per tenant, and enforces per-tenant quotas. Platform operators use this to offer search-grounded agents to their customers without exposing raw API keys.
Trigger
On-demand per incoming search request
Schedule
On-demand per incoming search request
Workflow Steps
Receive search request with tenant ID
Accept the incoming search request and extract the tenant identifier and query parameters.
Check tenant credit balance
Verify the tenant has sufficient credits remaining in their allocation before executing the search.
Execute search via Scavio
Forward the search request to the appropriate Scavio endpoint (Google, Reddit, etc.).
Debit tenant credits
Deduct the appropriate number of credits from the tenant's balance and log the transaction.
Return results to agent
Send the structured search results back to the requesting agent with usage metadata.
Python Implementation
import requests
import json
from pathlib import Path
from datetime import datetime
API_KEY = "your_scavio_api_key"
# Simulated tenant credit ledger
CREDIT_LEDGER_PATH = Path("tenant_credits.json")
def load_ledger() -> dict:
if CREDIT_LEDGER_PATH.exists():
return json.loads(CREDIT_LEDGER_PATH.read_text())
return {}
def save_ledger(ledger: dict):
CREDIT_LEDGER_PATH.write_text(json.dumps(ledger, indent=2))
def execute_search(tenant_id: str, platform: str, query: str) -> dict:
ledger = load_ledger()
tenant = ledger.get(tenant_id, {"credits": 100, "used": 0})
if tenant["credits"] - tenant["used"] <= 0:
return {"error": "insufficient_credits", "tenant_id": tenant_id}
res = requests.post(
"https://api.scavio.dev/api/v1/search",
headers={"x-api-key": API_KEY},
json={"platform": platform, "query": query},
timeout=15,
)
res.raise_for_status()
data = res.json()
# Debit credits
tenant["used"] += 1
tenant["last_query"] = datetime.utcnow().isoformat()
ledger[tenant_id] = tenant
save_ledger(ledger)
return {
"tenant_id": tenant_id,
"credits_remaining": tenant["credits"] - tenant["used"],
"results": data.get("organic", [])[:5],
"query": query,
"platform": platform,
}
def run():
# Simulate multi-tenant requests
requests_batch = [
{"tenant_id": "tenant_001", "platform": "google", "query": "best CRM software 2026"},
{"tenant_id": "tenant_002", "platform": "reddit", "query": "search API recommendation"},
{"tenant_id": "tenant_001", "platform": "google", "query": "AI agent frameworks comparison"},
]
for req in requests_batch:
result = execute_search(req["tenant_id"], req["platform"], req["query"])
if "error" in result:
print(f" DENIED {req['tenant_id']}: {result['error']}")
else:
print(f" OK {req['tenant_id']}: {len(result['results'])} results, {result['credits_remaining']} credits left")
if __name__ == "__main__":
run()JavaScript Implementation
const API_KEY = "your_scavio_api_key";
// In-memory tenant ledger (use a database in production)
const ledger = {
tenant_001: { credits: 100, used: 0 },
tenant_002: { credits: 50, used: 0 },
};
async function executeSearch(tenantId, platform, query) {
const tenant = ledger[tenantId];
if (!tenant || tenant.credits - tenant.used <= 0) return { error: "insufficient_credits" };
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, query }),
});
if (!res.ok) throw new Error(`scavio ${res.status}`);
tenant.used += 1;
const data = await res.json();
return { tenantId, remaining: tenant.credits - tenant.used, results: (data.organic ?? []).length };
}
const batch = [
{ tenant: "tenant_001", platform: "google", query: "best CRM 2026" },
{ tenant: "tenant_002", platform: "reddit", query: "search API recommendation" },
];
for (const req of batch) {
const result = await executeSearch(req.tenant, req.platform, req.query);
if (result.error) console.log(`DENIED ${req.tenant}: ${result.error}`);
else console.log(`OK ${req.tenant}: ${result.results} results, ${result.remaining} credits left`);
}Platforms Used
Web search with knowledge graph, PAA, and AI overviews
Community, posts & threaded comments from any subreddit