Google Custom Search API Replacement (Drop-in JSON)
Pricing
from $1.20 / 1,000 search answereds
Google Custom Search API Replacement (Drop-in JSON)
Drop-in replacement for Google's Custom Search JSON API, which shuts down Jan 1, 2027. Same parameters, same customsearch#search JSON, Google-style errors. Live web address or batch runs, plus optional Markdown of every result page for LLMs and AI agents.
Pricing
from $1.20 / 1,000 search answereds
Rating
0.0
(0)
Developer
mohamed senator
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
12 hours ago
Last modified
Categories
Share
Google's Custom Search JSON API (customsearch/v1) is closed to new customers and shuts down on January 1, 2027. This actor answers in exactly the same JSON format, with the same parameters, so you can switch by changing the web address and the key. Your code that reads items[].title, items[].link and items[].snippet keeps working.
It also does something Google's API never did: add markdown=true and each result comes with the clean text of its page, ready for LLMs, RAG pipelines and AI agents.
Not affiliated with or endorsed by Google. Results come from public Google Search pages.

Why use it
- Drop-in: same
q,num,start,gl,hl,lr,cr,safe,dateRestrict,siteSearch,exactTerms,excludeTerms,orTerms,fileType, and the samecustomsearch#searchJSON, includingqueries.nextPage,searchInformation,htmlTitleandhtmlSnippet. - Two ways in: a live web address that works like Google's endpoint, or normal actor runs for lists of searches, schedules and integrations.
- Built for AI agents: optional Markdown of every result page, and it works with Apify's MCP server, LangChain and any HTTP client.
- Cheaper than Google's $5 per 1,000: see pricing below.
Use cases
- Migrating off Google's Custom Search JSON API before January 1, 2027, without rewriting the code that reads the JSON.
- Search tool for AI agents and RAG: one call returns results plus the Markdown text of each page.
- SEO and rank checks: run lists of searches per country and language on a schedule.
- Research and monitoring: track who ranks for a topic, a brand or a site with
siteSearchanddateRestrict.
Speed and price at a glance

From a live test on October 18, 2026. 88 of 90 test searches were answered; the other 2 returned a 503 error and were not charged.

Apify Store prices on October 19, 2026. Platform cost is for the Free and Starter plans and is lower on bigger plans.
Switch in one minute
Before (Google):
GET https://www.googleapis.com/customsearch/v1?key=GOOGLE_API_KEY&cx=ENGINE_ID&q=coffee
After (this actor):
GET https://s3nafps--google-custom-search-api.apify.actor/customsearch/v1?token=APIFY_TOKEN&q=coffee
key becomes your Apify API token (token= or an Authorization: Bearer header). cx is accepted and ignored, so old URLs don't break.
curl
curl "https://s3nafps--google-custom-search-api.apify.actor/customsearch/v1?q=best+espresso+machine&num=5&gl=us" \-H "Authorization: Bearer $APIFY_TOKEN"
Python
import os, requestsr = requests.get("https://s3nafps--google-custom-search-api.apify.actor/customsearch/v1",params={"q": "best espresso machine", "num": 5, "gl": "us"},headers={"Authorization": f"Bearer {os.environ['APIFY_TOKEN']}"},timeout=60,)for item in r.json().get("items", []):print(item["title"], item["link"])
JavaScript
const url = new URL('https://s3nafps--google-custom-search-api.apify.actor/customsearch/v1');url.search = new URLSearchParams({ q: 'best espresso machine', num: '5' });const res = await fetch(url, { headers: { Authorization: `Bearer ${process.env.APIFY_TOKEN}` } });const data = await res.json();console.log(data.items?.map((i) => i.link));
LangChain tool for an AI agent
import os, requestsfrom langchain_core.tools import tool@tooldef google_search(query: str) -> str:"""Search Google and return the top results with page text."""r = requests.get("https://s3nafps--google-custom-search-api.apify.actor/customsearch/v1",params={"q": query, "num": 5, "markdown": "true", "markdownMaxChars": 4000},headers={"Authorization": f"Bearer {os.environ['APIFY_TOKEN']}"},timeout=90,)items = r.json().get("items", [])return "\n\n".join(f"# {i['title']}\n{i['link']}\n{i.get('markdown', i['snippet'])}" for i in items)
Normal runs (lists of searches)
Start the actor with a list of searches. Each search becomes one dataset row in Google's format, plus searchQuery:
{"queries": ["best coffee grinder 2026", "how to make cold brew"],"num": 10,"gl": "us","markdown": false}
Per-search settings work too: {"queries": [{"q": "kaffee", "gl": "de", "hl": "de"}]}. Runs stop cleanly at your maximum cost per run.
Parameters
| Parameter | Supported | Notes |
|---|---|---|
q | Yes | Required |
num | Yes | 1 to 10 (default 10) |
start | Yes | 1 to 91, up to 100 results per query |
gl, hl, lr, cr | Yes | Country and language |
safe | Yes | active or off |
dateRestrict | Yes | d5, w2, m6, y1... |
siteSearch, siteSearchFilter | Yes | Include (i) or exclude (e) one site |
exactTerms, excludeTerms, orTerms, fileType | Yes | Added to the search the way Google does |
cx, key | Accepted, ignored | |
markdown, markdownMaxChars | Extra | Page text as Markdown (default 20,000 characters per page) |
searchType=image, sort, rights, image filters | Not yet | Returns a 400 error in Google's format |
Errors use Google's shape (error.code, error.message, error.errors[], error.status). If Google doesn't answer after a few quick retries (at most about 20 seconds) you get a 503 with a Retry-After: 1 header and are not charged the search fee, so it is safe to retry right away. In normal runs, searches that got a 503 are retried once automatically at the end of the run.
Pricing
Pay per event, plus Apify's own platform costs:
| Event | Price |
|---|---|
| Search answered (even with zero results) | $1.50 per 1,000 ($0.0015 each; Silver $0.0013, Gold and above $0.0012) |
| Page converted to Markdown | $1 per 1,000 ($0.001 each; Silver $0.0009, Gold and above $0.0008) |
Apify's platform costs are mostly the Google search proxy. In our October 20, 2026 test they came to about $2.90 per 1,000 searches on the Free and Starter plans (less on larger plans). Total: about $4.40 per 1,000 searches, below Google's $5. Failed searches (503) are not charged the search fee.
FAQ
How fast is it? Most searches answer in a few seconds (see the speed test above). If Google's proxy stalls, the actor starts a second try in parallel after 5 seconds and gives up after about 20 seconds with a 503, so a request never hangs. Set your client timeout to 30 seconds, or 45 with Markdown, and retry on 503. For big lists, normal runs do 5 searches at a time.
What happens when a search fails? You get Google's error format with HTTP 503 and you are not charged. Retrying usually succeeds, because each try goes out through a different proxy IP.
Why is totalResults only a few hundred? It is Google's own count, and Google now shows small estimates for most searches. The number is passed on as Google gives it.
Are the results the same as the old API? The old API searched a "Programmable Search Engine" you set up. This actor returns google.com results, which are usually fuller. To limit results to one site, use siteSearch.
What is in pagemap? pagemap.metatags (title, description, author, publish date) is filled when markdown=true, because it needs the page itself.
Why is the web address slow on the first call? After a quiet spell Apify starts the actor again, which adds a few seconds. Apify bills compute while it stays awake, so for occasional batches normal runs are cheaper.
Can AI agents use it through MCP? Yes. Add the actor to Apify's MCP server and agents can call it as a tool.
Related Actors
- Website to Markdown for LLMs & RAG: turn whole websites into clean Markdown.
- Google Trends Scraper: Bulk Compare 100+ Keywords: compare hundreds of keywords on one Google Trends scale.
- YouTube Transcripts for AI: bulk YouTube transcripts from videos, channels and search as text, Markdown and RAG chunks.
Found a bug or need a parameter? Open an issue on the actor's Issues tab. If it saves you time, a review on the Store helps others find it.