Serper Integration¶
Official Serper API Documentation
Serper provides a fast and cost-effective way to get search results from Google. Use KeyPool to call Serper with your team token and a stable base URL.
KeyPool Endpoint for Serper¶
To interact with Serper via KeyPool, you will use the following base URL:
{YOUR_KEYPOOL_BASE_URL}/v1/serper
Authentication¶
Use your KeyPool team token as a bearer token when making requests to the KeyPool Serper endpoint.
Do not send a personal Serper API key when using KeyPool.
Key Features and Usage¶
KeyPool currently supports Serper's ten JSON POST endpoint families: /search,
/images, /news, /maps, /places, /videos, /shopping, /scholar,
/patents, and /autocomplete. The examples below show the same request
pattern for web and image search.
The proxy does not impose an endpoint allowlist. For any Serper operation
served by google.serper.dev, use the same path under
{YOUR_KEYPOOL_BASE_URL}/v1/serper and send the provider-documented JSON
body; KeyPool injects x-api-key and strips any client-supplied provider key.
The public spec documents only the verified core families. Operations hosted
on another provider host, such as Webpage on scrape.serper.dev, require a
separate routing integration.
1. Web Search¶
Perform a standard Google web search.
Python Example (using requests):
import os
import requests
import json
KEYPOOL_BASE_URL = os.environ.get("KEYPOOL_BASE_URL")
KEYPOOL_TOKEN = os.environ.get("KEYPOOL_TOKEN")
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {KEYPOOL_TOKEN}",
}
payload = {
"q": "latest AI news",
"num": 5, # Number of results
}
response = requests.post(f"{KEYPOOL_BASE_URL}/v1/serper/search", headers=headers, data=json.dumps(payload))
response.raise_for_status() # Raise an exception for HTTP errors
search_results = response.json()
print("Web Search Results:")
for result in search_results.get("organic", []):
print(f"- {result.get('title')} ({result.get('link')})")
TypeScript Example (using fetch):
const KEYPOOL_BASE_URL = process.env.KEYPOOL_BASE_URL;
const KEYPOOL_TOKEN = process.env.KEYPOOL_TOKEN;
async function serperWebSearch() {
const headers = {
"Content-Type": "application/json",
"Authorization": `Bearer ${KEYPOOL_TOKEN}`,
};
const payload = {
q: "latest AI news",
num: 5,
};
const response = await fetch(`${KEYPOOL_BASE_URL}/v1/serper/search`, {
method: "POST",
headers: headers,
body: JSON.stringify(payload),
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const searchResults = await response.json();
console.log("Web Search Results:");
searchResults.organic.forEach((result: any) => {
console.log(`- ${result.title} (${result.link})`);
});
}
serperWebSearch();
2. Image Search¶
Perform a Google image search.
Python Example (using requests):
import os
import requests
import json
KEYPOOL_BASE_URL = os.environ.get("KEYPOOL_BASE_URL")
KEYPOOL_TOKEN = os.environ.get("KEYPOOL_TOKEN")
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {KEYPOOL_TOKEN}",
}
payload = {
"q": "cute puppies",
"num": 3,
}
response = requests.post(f"{KEYPOOL_BASE_URL}/v1/serper/images", headers=headers, data=json.dumps(payload))
response.raise_for_status()
image_results = response.json()
print("Image Search Results:")
for result in image_results.get("images", []):
print(f"- {result.get('title')} ({result.get('imageUrl')})")
TypeScript Example (using fetch):
const KEYPOOL_BASE_URL = process.env.KEYPOOL_BASE_URL;
const KEYPOOL_TOKEN = process.env.KEYPOOL_TOKEN;
async function serperImageSearch() {
const headers = {
"Content-Type": "application/json",
"Authorization": `Bearer ${KEYPOOL_TOKEN}`,
};
const payload = {
q: "cute puppies",
num: 3,
};
const response = await fetch(`${KEYPOOL_BASE_URL}/v1/serper/images`, {
method: "POST",
headers: headers,
body: JSON.stringify(payload),
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const imageResults = await response.json();
console.log("Image Search Results:");
imageResults.images.forEach((result: any) => {
console.log(`- ${result.title} (${result.imageUrl})`);
});
}
serperImageSearch();
Provider quotas and newly published endpoints¶
Serper's official homepage currently advertises 2,500 free queries. Paid plans advertise 50, 100, 200, or 300 queries per second depending on the plan. KeyPool's configured 60 requests/minute per key is an internal routing policy, not a vendor quota.
The first-party Playground also lists /reviews and /lens. They are not in
KeyPool's current public contract yet. Its /webpage operation uses the
separate scrape.serper.dev host and is not routed by this service.
Error Handling¶
KeyPool handles various error conditions gracefully, providing informative responses. Common error scenarios include:
401 Unauthorized: Invalid or missing KeyPool Team Token.403 Forbidden: Your Team Token does not have permission to access the Serper service.429 Quota Exceeded: Your team's rate limit for Serper has been reached.503 No Available Keys: Serper is temporarily unavailable through your KeyPool workspace.502 Upstream Failed: The request to the Serper API failed (e.g., network error, Serper API down).
Interactive API Reference¶
For all Serper endpoints and in-browser testing, see API Reference → Serper.