Google CSE Shutdown 2027: Developer Migration Guide
Google CSE ends whole-web search January 2027. Migration options, pricing comparison, and code examples for switching to commercial search APIs.
Google Custom Search Engine (CSE) will stop supporting "Search the entire web" on January 1, 2027. After that date, CSE will only return results from domains you explicitly whitelist. If your application relies on CSE for general web search, you need to migrate before the cutoff or your search will silently return incomplete results.
What exactly changes
Google CSE has two modes: site-restricted search (only whitelisted domains) and whole-web search (returns results from anywhere on the internet). The whole-web mode is what most developers use as a programmatic Google search. Starting January 1, 2027, the whole-web mode disappears entirely. CSE becomes a site search tool only.
Google also closed CSE to new signups in early 2026. If you do not already have a CSE key, you cannot get one. Existing keys continue to work for site-restricted search after the cutoff, but the general web search capability is gone.
Who is affected
- AI agents using CSE for web grounding
- RAG pipelines that query Google for real-time context
- Internal tools that search the web via CSE API
- n8n/Make/Zapier workflows using the CSE HTTP endpoint
- Any application passing siteSearch=* or omitting siteSearch entirely
If you only use CSE to search your own site (e.g., docs search or intranet search), you are not affected. The site-restricted mode continues to work.
Migration options compared
- Scavio: $0.005/credit, 250 free/mo, $30/mo for 7K credits. Multi-platform (Google, Bing, YouTube, Reddit, TikTok)
- SerpAPI: $25/mo for 1K searches, $75/mo for 5K. Google-focused, many SERP features parsed
- Brave Search API: $5/1K queries. Web search only, free tier discontinued in 2026
- Exa: $5/1K requests, 1K free/mo. Semantic search, good for RAG but not a drop-in Google replacement
Step-by-step migration
The core change is replacing the CSE HTTP call with a search API call. Here is a before-and-after comparison.
Before: Google CSE
import requests
def google_cse_search(query):
resp = requests.get(
"https://www.googleapis.com/customsearch/v1",
params={
"key": "YOUR_CSE_API_KEY",
"cx": "YOUR_CSE_ID",
"q": query,
},
)
data = resp.json()
return [
{"title": item["title"], "link": item["link"], "snippet": item["snippet"]}
for item in data.get("items", [])
]After: Scavio API
import requests, os
def web_search(query, num_results=10):
resp = requests.post(
"https://api.scavio.dev/api/v1/search",
headers={"x-api-key": os.environ["SCAVIO_API_KEY"]},
json={"query": query, "num_results": num_results},
)
results = resp.json().get("organic_results", [])
return [
{"title": r["title"], "link": r["link"], "snippet": r["snippet"]}
for r in results
]Handling the response format difference
CSE returns results under items with fields liketitle, link, and snippet. Scavio returns results under organic_results with the same field names. If your codebase references CSE-specific fields like pagemap or cacheId, you will need to remove or replace those references.
# Adapter function: drop-in replacement for existing CSE consumers
def search_adapter(query, num_results=10):
"""Returns results in the same format as Google CSE items[]."""
resp = requests.post(
"https://api.scavio.dev/api/v1/search",
headers={"x-api-key": os.environ["SCAVIO_API_KEY"]},
json={"query": query, "num_results": num_results},
)
results = resp.json().get("organic_results", [])
# Map to CSE-compatible format
return {
"items": [
{
"title": r.get("title", ""),
"link": r.get("link", ""),
"snippet": r.get("snippet", ""),
"displayLink": r.get("link", "").split("/")[2] if r.get("link") else "",
}
for r in results
]
}Migration checklist
- Audit all code referencing googleapis.com/customsearch
- Replace API calls with your chosen alternative
- Update response parsing (items to organic_results or equivalent)
- Remove CSE-specific fields (pagemap, cacheId, searchInformation)
- Test with queries that rely on whole-web results
- Update rate limit handling (CSE allows 100/day free, alternatives differ)
- Set up monitoring to catch any missed CSE calls before January 2027
What about Google Programmable Search Element (the widget)?
The JavaScript widget for embedding search on websites is also affected. After January 2027, it will only search your whitelisted sites. If you use the widget for general web search on a portal or dashboard, you need a frontend alternative. Most search APIs can be called from a backend endpoint and rendered in your own UI.
Timeline recommendation
Do not wait until December 2026. Migrate now while you have time to test both systems in parallel. Run CSE and your replacement side by side for a month, compare result quality, then cut over. The January deadline is a hard cutoff with no extension announced.