From serpapi-pack
Deploys SerpApi search proxies to Vercel, GCP Cloud Run, and Fly.io with TypeScript or Python/Flask endpoints, health checks, and error handling guides.
npx claudepluginhub jeremylongshore/claude-code-plugins-plus-skills --plugin serpapi-packThis skill is limited to using the following tools:
Deploy SerpApi-powered search as a backend API endpoint. Always proxy through your server -- never expose the API key to browsers.
Provides production reference architecture for SerpApi search services with caching, multi-engine abstraction, SERP tracking, and monitoring using TypeScript, Redis, and PostgreSQL.
Deploys Exa search API apps to Vercel Edge, Docker, and Cloud Run with endpoint templates, secret configs, and production bash commands.
Deploys Firecrawl apps to Vercel serverless, Cloud Run containers, and Docker self-hosted setups. Configures secrets and provides Next.js API route example.
Share bugs, ideas, or general feedback.
Deploy SerpApi-powered search as a backend API endpoint. Always proxy through your server -- never expose the API key to browsers.
// api/search.ts
import { getJson } from 'serpapi';
export default async function handler(req: Request) {
const url = new URL(req.url);
const q = url.searchParams.get('q');
if (!q) return new Response('Missing q parameter', { status: 400 });
const engine = url.searchParams.get('engine') || 'google';
const num = parseInt(url.searchParams.get('num') || '5');
const result = await getJson({
engine, q, num,
api_key: process.env.SERPAPI_API_KEY,
});
return Response.json({
results: result.organic_results?.slice(0, num) || [],
answer_box: result.answer_box || null,
total_results: result.search_information?.total_results,
});
}
vercel env add SERPAPI_API_KEY production
vercel --prod
# main.py
from flask import Flask, request, jsonify
import serpapi, os
app = Flask(__name__)
client = serpapi.Client(api_key=os.environ["SERPAPI_API_KEY"])
@app.route("/search")
def search():
q = request.args.get("q")
if not q:
return jsonify({"error": "Missing q parameter"}), 400
result = client.search(engine="google", q=q, num=5)
return jsonify({
"results": result.get("organic_results", [])[:5],
"answer_box": result.get("answer_box"),
})
gcloud run deploy search-api \
--source . --region us-central1 \
--set-secrets=SERPAPI_API_KEY=serpapi-key:latest \
--allow-unauthenticated
app.get('/health', async (req, res) => {
const account = await fetch(
`https://serpapi.com/account.json?api_key=${process.env.SERPAPI_API_KEY}`
).then(r => r.json());
res.json({
status: account.plan_searches_left > 0 ? 'healthy' : 'credits_exhausted',
remaining: account.plan_searches_left,
});
});
| Issue | Cause | Solution |
|---|---|---|
| Cold start slow | First request initializes | Pre-warm with min instances |
| Credits run out | No budget monitoring | Add health check with credit count |
| Key exposed | Frontend calling SerpApi directly | Always proxy through backend |
For webhook-like patterns, see serpapi-webhooks-events.