TL;DR: Google's Custom Search JSON API is closed to new customers and shuts down for existing users on January 1, 2027. If your app or pipeline sends a query and reads Google results as JSON from the whole web, Google Search on Piloterr keeps that pattern: query in, structured SERP out. Most gl / hl / lr filters map 1:1. For SERP-only workloads at volume, the same team ships Autom.dev, a dedicated SERP API with the same parameter style.
Migrating is a few lines of code, not a rewrite.
What is shutting down
Google states on the Custom Search JSON API overview:
- The API is not available for new customers.
- Existing customers can keep using it until January 1, 2027.
- Until then, pricing stays the same: 100 free queries per day, then $5 per 1,000 queries, capped at 10k queries per day.
For searching up to about 50 domains, Google points to Vertex AI Search (also framed as Agent Search in some docs). For results from the entire web, there is no self-serve Google product. Google only offers an interest form.
Source: Google for Developers: Custom Search JSON API.
Pick the right replacement for what you actually search
Custom Search covered several jobs. They do not share one successor.
| What you use Custom Search for | What to use instead |
|---|---|
| A search box on your own site | Google's Programmable Search Element, or a site search product (Algolia, Typesense, Meilisearch) |
| A known set of domains or your own corpus inside Google Cloud | Google Agent Search / Vertex AI Search (Google's "up to ~50 domains" path) |
| Whole-web results as JSON for an app, agent, or pipeline | Google Search on Piloterr, or Autom.dev if you only need SERP |
| AI-generated answers with citations (Google AI Mode) | Google AI Mode, optionally paired with organic search |
| Deep SEO SERP work (ads, AI Overviews, many pages) | Google Search with page pagination, plus Images / Autocomplete endpoints as needed |
| Same query pattern on Bing, Brave, Yahoo, DuckDuckGo (or multi-engine failover) | Autom.dev: Google plus Bing, Brave, Yahoo, DuckDuckGo, Baidu on one SERP stack |
The rest of this guide is for the whole-web JSON case: you currently call customsearch/v1 with "Search the entire web" enabled. Code samples use Piloterr; Autom.dev is the same idea with a different host when SERP is all you need.
Piloterr or Autom.dev?
Autom.dev is our SERP-focused sub-product. Same family as Piloterr, built for teams whose job is search results: SEO rank tracking, agents that only need SERP JSON, multi-engine lookup at volume. Endpoint shape is familiar: https://api.autom.dev/v1/google/search, x-api-key, query / gl / hl / tbs / page. See the Autom Google Search docs. Pricing is SERP-specialized (pay-per-use credits, no CSE-style 10k/day wall).
Pick Piloterr when you stay in the Google family: Google Search, Images, Autocomplete, AI Mode.
Pick Autom.dev when you want Google and other engines (Bing, Brave, Yahoo, DuckDuckGo, Baidu) on one account, or SERP-only volume pricing.
Same team. Same migration pattern from Custom Search. Different surface depending on whether you need Google-only or multi-engine SERP.
What you get with Piloterr Google Search
Same contract you already built around: send a query, get ranked results back as JSON. Compared to Custom Search:
| Custom Search JSON API | Piloterr Google Search | |
|---|---|---|
| Availability | Closed to new customers; ends Jan 1, 2027 | Open |
| Setup | API key + Programmable Search Engine (cx) | One x-api-key |
| Cost model | 100 free/day, then $5 / 1k, hard 10k/day cap | 1 credit per request |
| Daily hard cap | 10k queries | Credit-based plans, no CSE-style 10k/day ceiling |
| Country / language | gl, lr, hl | Same names: gl, hl, lr, plus cr |
| Local results | Country-level | Country + optional city location / uule |
| Site filter | siteSearch / siteSearchFilter | Google operators in query (site:, -site:, …) |
| Date filter | dateRestrict (d7, w1, …) | tbs (qdr:d, qdr:w, qdr:m, qdr:y) |
| Pagination | Limited | page for next result pages |
| Extra payload | Organic items + search meta | Organic results, knowledge graph, related searches, pagination |
| Auth | key query param | x-api-key header |
Docs: Google Search API · API reference. GET and POST are both supported.
How to switch from Custom Search to Piloterr
You still send a query and read JSON. After you remap a handful of fields, the code that consumes titles and links keeps working.
- Create an account at app.piloterr.com and copy your API key.
- Map request parameters and response fields with the tables below.
- Point the HTTP call at
https://api.piloterr.com/v2/google/search.
Request parameter mapping
| Piloterr parameter | What it does | Custom Search equivalent |
|---|---|---|
query | Search string (required). Supports Google operators | q |
gl | Country bias (us, fr, uk, …) | gl |
hl | UI / result language | hl |
lr | Restrict to language(s), e.g. lang_fr | lr |
cr | Restrict to country(ies), e.g. countryFR | Closest: country filters / engine config |
tbs | Recency: qdr:h, qdr:d, qdr:w, qdr:m, qdr:y | dateRestrict |
location / uule | City-level SERP | No direct CSE equivalent |
google_domain | google.com, google.fr, … | Engine locale / domain settings |
page | Result page number | Partial / limited in CSE |
safe | SafeSearch active / off | safe |
x-api-key header | Auth | key |
| Not required | cx (search engine ID) |
Site include/exclude that lived in siteSearch becomes part of the query: site:example.com coffee or -site:pinterest.com coffee.
Response field mapping
| Custom Search | Piloterr Google Search |
|---|---|
items[].title | organic_results[].title |
items[].link | organic_results[].link |
items[].snippet | organic_results[].snippet |
items[].displayLink | organic_results[].domain |
items[].formattedUrl | organic_results[].displayed_link |
searchInformation.totalResults | search_information.total_results |
organic_results[].position, knowledge_graph, related_searches, pagination |
Python: before and after
Before: Custom Search JSON API:
import os
import requests
resp = requests.get(
"https://www.googleapis.com/customsearch/v1",
params={
"key": os.environ["GOOGLE_API_KEY"],
"cx": os.environ["SEARCH_ENGINE_ID"],
"q": "best coffee shops",
"gl": "fr",
"hl": "fr",
"lr": "lang_fr",
"num": 10,
},
timeout=30,
)
for item in resp.json().get("items", []):
print(item["title"], item["link"])
After: Piloterr Google Search:
import os
import requests
resp = requests.post(
"https://api.piloterr.com/v2/google/search",
headers={"x-api-key": os.environ["PILOTERR_API_KEY"]},
json={
"query": "best coffee shops",
"gl": "fr",
"hl": "fr",
"lr": "lang_fr",
},
timeout=30,
)
for result in resp.json().get("organic_results", []):
print(result["position"], result["title"], result["link"])
What actually changed:
- Endpoint URL
- Auth moved from
key(+cx) to thex-api-keyheader q→queryitems→organic_results(field names liketitleandlinkstay familiar)gl/hl/lrkeep the same values
GET works the same way if you prefer query strings over a JSON body.
On Autom.dev the swap is the same idea: drop cx, send query + gl / hl, authenticate with x-api-key, and point at https://api.autom.dev/v1/google/search (library). Response fields stay in the organic_results style.
Beyond Google: Bing, Brave, Yahoo, DuckDuckGo
Custom Search was Google-only. Plenty of pipelines now want a second index for redundancy, geo coverage, or cross-engine SEO. On Autom.dev the same query-in / JSON-out pattern works across engines:
- Bing Search
- Brave Search
- Yahoo Search
- DuckDuckGo Search
- Baidu Search when you need that market
- Or
/v1/search: try Google, then Brave, Bing, DuckDuckGo, Yahoo, Baidu until one returns organic results
On Piloterr, stay Google-side with AI Mode, Images, and Autocomplete on the same API key as Google Search.
Migrate before January 1, 2027
The Custom Search JSON API stops at the start of 2027. Google does not offer a self-serve whole-web JSON replacement. If your code already does "query → JSON results," you can move to Google Search (or Autom.dev for SERP-only / multi-engine) by changing the endpoint, dropping cx, and renaming a few fields.
Need help sizing credits or checking a production query mix? Start from the Google Search docs, compare with Autom.dev pricing, or open a conversation from the site.
FAQ
When does the Google Custom Search JSON API shut down?
Google discontinues it on January 1, 2027. It is already closed to new customers; existing customers can use it until that date.
Is there an official Google search API for the whole web?
Not a self-serve one. Google's documented options cover site / limited-domain search (Agent Search / Vertex AI Search) and enterprise grounding. For whole-web programmatic results, Google points to an interest form.
What is the best Custom Search JSON API alternative?
It depends on the job. Site search → a site search product. Up to ~50 domains in Google Cloud → Agent Search / Vertex AI Search. Whole-web JSON for apps and pipelines → a SERP API such as Piloterr Google Search. High-volume SERP-only (including engines beyond Google) → Autom.dev.
Piloterr or Autom.dev: which one?
Same company. Piloterr covers the Google SERP family (Search, Images, Autocomplete, AI Mode). Autom.dev is the SERP sub-product for Google plus Bing, Brave, Yahoo, DuckDuckGo, and Baidu, with volume pricing. If you only need Google JSON results, either works. If you need other engines or multi-engine failover, use Autom.dev.
Do I still need a Programmable Search Engine (cx)?
No. Piloterr Google Search and Autom.dev only need your API key and a query.
Does Piloterr Google Search support pagination?
Yes. Pass page (1, 2, …). Custom Search was much more constrained here; multi-page SERP jobs are a common reason teams leave CSE early.
How do I filter by date after migration?
Replace dateRestrict with tbs: last day qdr:d, week qdr:w, month qdr:m, year qdr:y. Exact calendar ranges from CSE do not map 1:1; relative windows cover most monitoring use cases.