Migrate from Serper.dev
Map Serper.dev requests and responses to SerpHubAPI — same POST + JSON style, plus Bing and Yandex.
If you use Serper.dev, the move is short: both APIs take a POST with a JSON body and the same core parameters. The main changes are the URL, the header name, and choosing the vertical with type instead of a separate path.
Quick switch
Before (Serper.dev):
curl -X POST https://google.serper.dev/search \
-H "X-API-KEY: $SERPER_KEY" \
-H "Content-Type: application/json" \
-d '{"q": "coffee", "gl": "us", "hl": "en", "num": 10, "page": 2, "tbs": "qdr:w"}'
After (SerpHubAPI):
curl -X POST https://api.serphubapi.com/v1/search \
-H "X-API-Key: $SERPHUBAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"q": "coffee", "engine": "google", "gl": "us", "hl": "en", "num": 10, "page": 2, "time_range": "week"}'
In Python:
import os, httpx
# before: httpx.post("https://google.serper.dev/search", headers={"X-API-KEY": key}, json=body)
r = httpx.post(
"https://api.serphubapi.com/v1/search",
headers={"X-API-Key": os.environ["SERPHUBAPI_API_KEY"]},
json={"q": "coffee", "engine": "google", "gl": "us", "hl": "en", "num": 10},
)
organic = r.json()["results"].get("organic", [])
Endpoint mapping
| Serper.dev | SerpHubAPI |
|---|---|
POST google.serper.dev/search | POST /v1/search with type=web |
POST google.serper.dev/news | type=news |
POST google.serper.dev/images | type=images |
POST google.serper.dev/videos | type=videos |
POST google.serper.dev/shopping | type=shopping |
POST google.serper.dev/maps / /places | type=maps |
POST google.serper.dev/scholar | type=scholar |
POST google.serper.dev/autocomplete | type=autocomplete |
POST scrape.serper.dev | POST /v1/fetch, or include_content on search |
| — | engine=bing / engine=yandex (web) |
All on base URL https://api.serphubapi.com.
Parameter mapping
| Serper.dev | SerpHubAPI | Notes |
|---|---|---|
X-API-KEY header | X-API-Key header (or Authorization: Bearer) | Header names are case-insensitive, so only the value changes |
q | q | Same |
gl | gl | Same |
hl | hl | Same |
num | num | 1–100, same price for any value |
page | page | Same, 1-based |
tbs=qdr:d | time_range=day | |
tbs=qdr:w | time_range=week | |
tbs=qdr:m | time_range=month | |
tbs=qdr:y | time_range=year | |
tbs=qdr:h, custom date ranges | — | Not supported |
location | — | Not supported; use gl / hl |
autocorrect | — | Not supported |
| — | engine | auto (default), google, bing, yandex |
| — | mode | live (default) or cache_first (half price, free on cache hit) |
| — | include_content | Fetch top N pages as Markdown in the same call |
| — | format | json or markdown |
Response mapping
| Serper.dev | SerpHubAPI |
|---|---|
searchParameters | params |
credits | meta.credits_charged (10 = one live search) |
organic | results.organic |
news | results.news |
images[].imageUrl / thumbnailUrl | results.images[].image / thumbnail |
videos | results.videos |
shopping[].source | results.shopping[].merchant |
places[].title / ratingCount | results.places[].name / reviews |
peopleAlsoAsk | results.people_also_ask |
relatedSearches[].query | results.related_searches[] (plain strings) |
knowledgeGraph | results.knowledge_graph |
suggestions[].value | results.suggestions[] (plain strings) |
| — | meta.id — call ID, look up again for 30 days via GET /v1/searches/{id} |
Field names are snake_case throughout.
Structural differences
| Serper.dev | SerpHubAPI | |
|---|---|---|
| Engines | Google, Bing, Yandex (engine=auto chooses and fails over) | |
| Choosing a vertical | Separate path per vertical | One endpoint, type parameter |
| Response shape | Per-vertical keys, camelCase | One unified structure, snake_case |
| Call ID and archive | — | meta.id, 30-day archive at /v1/searches/{id} |
| Page content | Separate scrape endpoint | include_content in the search call, or /v1/fetch |
| LLM-ready output | JSON | JSON or Markdown (format=markdown) |
| Billing | Prepaid credit packs | Prepaid credits; paid balance never expires; failed calls, empty results and cache hits are free |
| Errors | HTTP status + message | {"error": {"code", "message"}} with stable codes — see Errors |
Checklist
- Create a key at /dashboard/keys.
- Change the base URL to
https://api.serphubapi.com/v1/searchand settypeinstead of the path. - Translate
tbstotime_range. - Rename camelCase response fields to their snake_case equivalents under
results. - Read cost from
meta.credits_chargedinstead ofcredits. - Run a few queries side by side, then switch traffic.