SerpAPI Controlled First Search
Overview
Prove authentication, transport, search status, and schema handling with one bounded query and a redacted receipt.
Prerequisites
- An official SerpAPI client already installed
SERPAPI_KEYloaded from an approved server-side secret store- A harmless query, expected locale, allowance owner, and live-call approval
Tool Discipline
Use Read, Glob, and Grep to inspect local setup, WebFetch to verify current Google Search parameters, Write or Edit for the smoke-test code and redacted receipt, and Bash(python3:*) or Bash(npm:*) only to run the approved check.
Current Contract
Google Search uses engine=google and query parameter q. JSON responses expose search_metadata.status, a search ID, search parameters, and optional result sections. A successful search may legitimately contain no organic results.
Authentication
Pass the private key from SERPAPI_KEY through the official client. Never interpolate it into source, logs, exceptions, fixtures, screenshots, or receipts.
Instructions
- Confirm the query is non-sensitive and set explicit
location,hl, andglvalues when geographic reproducibility matters. - Check Account API for available searches and hourly throughput without spending allowance.
- Preview one request with
engine=google,q, and the minimum necessary parameters. - After approval, execute exactly one search with a finite client timeout.
- Require
search_metadata.status == "Success"; treat missing result sections as optional schema branches. - Extract only the fields required by the caller and preserve the search ID for support correlation.
- Record client version, normalized parameters, status, elapsed time, result counts, and search ID with the key and sensitive query data redacted.
Output
Return the approved request shape, search status, result-section counts, search ID, redacted receipt location, and any schema assumptions that need fixtures.
Error Handling
| Condition | Response |
|---|---|
| HTTP 400 | Correct the engine-specific parameters; do not retry unchanged. |
| HTTP 401 or 403 | Stop and repair authorization without printing the key. |
| HTTP 429 | Inspect Account API before deciding whether to wait or increase allowance. |
| HTTP 5xx or timeout | Retry a bounded number of times with jitter and preserve the search ID if present. |
Success with no organic results | Inspect other documented sections and the engine-specific _state; do not label it an API failure. |
Example
import os
import serpapi
client = serpapi.Client(api_key=os.environ["SERPAPI_KEY"], timeout=15)
result = client.search({
"engine": "google",
"q": "coffee",
"location": "Austin, Texas, United States",
"hl": "en",
"gl": "us",
})
assert result["search_metadata"]["status"] == "Success"
print({
"search_id": result["search_metadata"]["id"],
"organic_count": len(result.get("organic_results", [])),
})
Resources
Next Steps
Capture a sanitized response fixture and move subsequent parser work into the local-development workflow.