Google Custom Search JSON API alternative:
Google has closed the Custom Search JSON API to new customers and is shutting it down for everyone on January 1, 2027. Semscraper collects the real Google results page, rendered in a browser, up to 10 pages per keyword, about 100 results depending on the query, pay as you go with prepaid credits and no subscription.
- The real Google SERP, not a reduced index
- Up to 10 pages per keyword
- 1,000 one-page searches for €0.30
- 1,000 free SERPs
- No credit card
What Google announced,
According to Google's documentation (developers.google.com/custom-search/v1/overview and the Programmable Search Engine help center), read on October 10, 2026.
Since January 20, 2026
New Programmable Search Engines are limited to 50 chosen domains: the "Search the entire web" option is no longer offered. Existing engines that use it keep it until January 1, 2027.
Closed to new customers
A new project can no longer enable the Custom Search JSON API. For searching up to 50 domains, Google points to Vertex AI Search; full web search has to be requested from Google.
January 1, 2027
End of the Custom Search JSON API for existing customers. Any application still calling it must have migrated.
Where Semscraper
Semscraper is not a drop-in clone of Custom Search: it is an API that collects the Google page as a searcher sees it. It replaces some uses well, not all of them.
Yes: tracking Google
Rank tracking, competitive monitoring, SERP research, AI Overviews: you get the real results of google.com, google.fr or any other country, city and device included.
Yes: feeding tools and agents
Datasets, enrichment, agents and RAG pipelines that need what Google actually shows. Processing is asynchronous: expect about twenty seconds of collection per search, not an instant answer.
No: your own site search
A search box that must answer in a fraction of a second over your own pages calls for a site search engine, or for Vertex AI Search, which Google offers for up to 50 domains.
Custom Search JSON API vs Semscraper:
| Topic | Custom Search JSON API | Semscraper |
|---|---|---|
| Where results come from | Your Programmable Search Engine. Even set to the entire web, Google states it only covers part of its index and emphasizes your own sites. | The real Google results page, rendered in a real browser. |
| Content | A list of web results, without Google Search features (Oneboxes, universal search). | Every block on the page: organic results, ads, local pack, People Also Ask, AI Overviews with their sources, and more. |
| Number of results | 10 per request, 100 at most when paginating (start + num cannot exceed 100). | Up to 10 Google pages in a single call, about 100 results depending on the query. |
| Country, language, city, device | gl boosts results from a country, hl sets the interface language, lr and cr filter documents. | Google version (country and language), city or GPS coordinates, desktop or mobile. |
| How it works | Synchronous: the answer comes back in the call. | Asynchronous: you create searches (up to 1,000 per call), then fetch results by ID or receive them on a callback URL. About twenty seconds of collection in median for one page, about fifty for 10, plus the wait in your account's queue (measured on 12 million SERPs, 5.3 million one-page and 260,000 ten-page, September 12 to October 10, 2026). |
| Price | 100 free queries per day, then $5 per 1,000, up to 10,000 per day. | €0.30 per 1,000 one-page searches, €2.10 per 1,000 ten-page searches. No subscription, no daily cap, and your balance never expires. |
| Searching specific domains | Yes, it is now the only mode for new engines (50 domains). | No saved list of domains: the site: operator in the keyword restricts a search to one domain. |
| Image search | Yes (searchType=image). | No. Only the Images block, when Google shows it on the results page, is returned. |
Adapting
The parameters are not interchangeable: here is how to adapt your calls. Google operators go through unchanged in the keyword.
| Custom Search | Semscraper |
|---|---|
q | keyword |
gl | location, the Google version, which is not a country code: gl=us becomes location=en (google.com), gl=fr becomes location=fr (google.fr) |
hl | language, which forms a valid pair with location: en/en, fr/fr, de/de... |
num, start | depth, from 1 to 10 Google pages, all returned by the same call |
siteSearch | site:example.com in the keyword |
exactTerms | Quotes in the keyword |
excludeTerms | -word in the keyword |
fileType | filetype:pdf in the keyword |
lr, cr | No direct equivalent: choose the Google version and language |
searchType=image | No equivalent |
key, cx | A single API key, sent in the Authorization: Bearer header |
Migrating a call,
The same need in Python: the top 10 organic results for a query on google.com. The main difference is the two-step flow, create then fetch.
import requests
r = requests.get("https://www.googleapis.com/customsearch/v1", params={
"key": "GOOGLE_API_KEY",
"cx": "SEARCH_ENGINE_ID",
"q": "running shoes",
"gl": "us",
"hl": "en",
"num": 10,
})
for item in r.json().get("items", []):
print(item["link"], item["title"], item["snippet"])
import time
import requests
API = "https://api.semscraper.com/v1/serp"
HEADERS = {"Authorization": "Bearer API_KEY"}
# 1. create the search (up to 1,000 keywords per call)
r = requests.post(API, headers=HEADERS, timeout=60, json=[{
"search_engine": "google_search",
"keyword": "running shoes",
"location": "en",
"language": "en",
"device": "desktop",
"depth": 1,
}])
r.raise_for_status()
ids = [row["id"] for row in r.json()["data"]]
# 2. fetch the results once ready (about 20 s of collection for a depth-1 search,
# plus queue time), 10 minutes at most
deadline = time.time() + 600
while ids and time.time() < deadline:
time.sleep(10)
r = requests.get(API, headers=HEADERS, timeout=60,
params={"ids": ",".join(ids[:100]), "output": "json"}) # 100 IDs per call
r.raise_for_status()
for row in r.json()["data"]:
if row["status"] != "done":
continue
ids.remove(row["id"])
for block in row["results"]:
if block["type"] == "organic":
for item in block["items"]:
print(item["url"], item["title"], item["description"])
if ids:
print("Still pending, fetch them later by ID:", ids)
The link field becomes url, snippet becomes description. Each result also carries its rank within its block (rank_type), its rank on the page (rank_serp), its Google page and its pixel position. For thousands of keywords: create them in batches of 1,000, fetch results in batches of 100 IDs, or receive them on a callback URL. See the Bulk SERP API.
Switch over
A migration takes some preparation: allow a few days of testing before you turn the old API off.
1. Test
Run your representative queries with the 1,000 free SERPs you get at sign-up.
2. Adapt
Parameters (gl becomes location), the move to asynchronous calls, and response fields (link becomes url, snippet becomes description).
3. Compare
Relevance, result coverage, turnaround and consumption, on a sample of your real queries.
4. Switch
Move your application to Semscraper once the results are validated, well before January 1, 2027.
What it costs,
Public prices: Google checked on October 10, 2026, Semscraper at the standard rate, before top-up discounts.
| Need | Custom Search JSON API | Semscraper |
|---|---|---|
| 1,000 keywords, 1 page (about 10 results) | $5 (1,000 paid queries, outside the daily free quota) | €0.30 |
| 1,000 keywords, 10 pages (about 100 results) | $50 (10 paid queries per keyword, outside the daily free quota) | €2.10 |
| More than 10,000 queries a day | Not possible: capped at 10,000 per day | No daily cap |
If the day's 100 free queries have not been used yet, count $4.50 and $49.50. The Custom Search JSON API is no longer available to new customers: these prices only apply to existing accounts, until January 1, 2027. Semscraper detailed pricing.
Frequently asked questions
When does the Custom Search JSON API shut down?
Does Semscraper return the same results as Custom Search?
Can I restrict searches to my domains?
Is the answer instant?
What does Semscraper cost after migrating?
Go further
How to scrape Google in 2026
Collecting Google results at scale has never been this demanding: 100 results per page are gone, AI Overviews load late, and SERPs change from city to city. Here are the options and the pitfalls.
Read the guide →Geolocated SERPs: Google results as seen from a city
Two people typing the same search in two different cities don't see the same page. To measure local SEO, you need to collect the SERP from the right location.
Read the guide →SerpApi alternative: the honest comparison
SerpApi is one of the best-known SERP APIs. If you are looking for an alternative for Google Search and Google Maps, here is what sets the two services apart, including where SerpApi does better.
Read the guide →Test your queries before the deadline
1,000 free SERPs, no credit card required.