Google Custom Search API Alternative: A Migration Guide Before the January 1, 2027 Shutdown
Google Custom Search JSON API shuts down on Jan 1, 2027. Parameter map, 59 live calls, and the bill at $5 vs $0.694 per 1,000 queries.

Google closed the Custom Search JSON API to new customers, and existing customers lose access on January 1, 2027. Our web tool costs $0.694 per 1,000 calls, about 14% of the $5 Google price. At 10,000 queries per day, the monthly bill drops from $1,485 to $208.20. Fix two things first. Our site parameter returned zero results in 2 of 3 tries, so put site: in the query. A copied Google start or cx returns a 422 error, and Google ignores it.
This is a migration guide. It is for developers who still call customsearch/v1, or who used the Bing Web Search API before it closed. It answers three questions.
Where do you move before the deadline, what code do you change, and what will it cost each month? For the other providers, we used only public documentation, pricing pages and forum posts. We opened and saved each page on November 8, 2026, between 00:14 and 00:40 Singapore time. We did not sign up for or call any other provider. Every number for our side comes from a live call on the same day.
We already have a comparison of six search APIs for AI agents. We also have a guide on which search tool to use at each task stage. This article does not repeat that ranking. It covers one job only: moving out of Google Custom Search and Bing Web Search with the least risk.

The short answer: pick a Google Custom Search API alternative by use case
People use the Custom Search JSON API for three different jobs. Some run site search on their own website. Some search the whole web for a product, a monitor or a dataset.
Some give it to an AI agent as a search tool. Google only offers a replacement for the first job. The table below lists where each group can go, the price per 1,000 calls, and what you must change. Prices are public list prices or our catalog prices, read on November 8, 2026.
| What you use it for | Where you can move | Per 1,000 calls | What you change |
|---|---|---|---|
| Site search on your own site, up to 50 domains, with a search box | Google Programmable Search Element (free edition shows Google ads) | $0 | Replace JSON calls with the embed code |
| Site search on your own site, with JSON and ranking control | Google Agent Search Enterprise (formerly Vertex AI Search) | $4.00 | New data store, new app, new auth, about 14 console steps |
| Whole-web search for a product, monitor or dataset | EveryInfra web tool | $0.694 | Rename parameters, start becomes page |
| Whole-web search with Bing results | EveryInfra bing/search | $0.556 | No count or offset, first page only |
| Whole-web search with country and language hints | EveryInfra web/search | $1.389 | gl becomes country, hl becomes language |
| Full result pages with ads, knowledge panels and more | SerpAPI, Serper, Bright Data | $0.30 to $25.00 | New parameters and a new response shape |
| Agent search with page text in the answer | Tavily, Firecrawl, or our web plus read | $1.50 to $8.00 | Change to a tool call |
One detail in this table is easy to miss. Google's own replacement, Agent Search, covers website search for at most 50 domains. The Programmable Search Engine blog post from January 20, 2026 tells whole-web users to contact Google about a separate full-web product. That product has no public price and no self-service sign-up. So if you use the JSON API to search the whole web, Google gives you nothing you can switch on today. You must look at other providers.
Shutdown timeline: what Google and Microsoft closed
The two large public web search APIs closed within about eighteen months. Microsoft's lifecycle announcement says the Bing Search APIs retired on August 11, 2025. All existing instances went offline and new sign-ups stopped.
Microsoft points customers to Grounding with Bing Search inside Azure AI Agents. Google moved in several steps. The Site Restricted JSON API stopped on January 8, 2025. On January 20, 2026, new search engines lost the option to search the entire web.
The screenshot below shows the pricing section of the Google developer page. We opened it on November 8, 2026, at 00:2x Singapore time, with the page language set to English. The footer says the page was last updated on February 18, 2026. The teal box holds the four facts behind every price in this article. The price applies only to existing customers, and the first 100 queries per day are free. Extra queries cost $5 per 1,000, and the daily limit is 10,000.

| Date | What happened | Source |
|---|---|---|
| 2025-01-08 | Google stopped the Custom Search Site Restricted JSON API | developers.google.com |
| 2025-08-11 | Microsoft retired the Bing Search APIs and took instances offline | learn.microsoft.com |
| 2026-01-20 | New engines limited to 50 domains; JSON API closed to new customers | Programmable Search Engine blog |
| April 2026 | Vertex AI Search renamed Agent Search, under Gemini Enterprise Agent Platform | Google Cloud rename table |
| Around 2026-09-09 | Google published, then removed, docs for a partner-only Web Search Service API | Search Engine Journal |
| 2026-10-16 | A Google community manager reposted the shutdown notice with the same deadline | Programmable Search community |
| 2027-01-01 | JSON API shuts down; old engines lose "Search the entire web" | developers.google.com |
The timeline shows a pattern. The 2027 deadline is not the first time Google reduced its search APIs: the Site Restricted JSON API closed in January 2025. So even a move to Google Agent Search needs room for the next change. Wrap every search call in one function of your own. Then a future provider change touches one file.
Is there a Google search API in November 2026?
The most common forum question is simple: is there a Google search API at all? As of November 8, 2026, a normal developer cannot get one. There is no whole-web Google search API that you can switch on yourself. We opened each official page from Google and Microsoft and listed the result below.
| Official option | What it searches | Who can use it | Price | Status on 2026-11-08 |
|---|---|---|---|---|
| Custom Search JSON API | Whole web or chosen sites | Existing customers only | $5 per 1,000, 100 per day free | Shuts down 2027-01-01 |
| Programmable Search Element | Up to 50 domains | Anyone | Free, with ads | Still offered as an embedded search box |
| Agent Search Enterprise | Website search, up to 50 domains | Google Cloud customers | $4.00 per 1,000, 10,000 free trial queries per month | Still offered, needs a data store |
| Full-web search product | Whole web | By application | Not public | Only an interest form |
| Web Search Service API | Whole web | Partners with a signed agreement | Not public | Docs page returns 404 |
| Grounding with Bing Search | Whole web | Paid Azure subscription | $14 per 1,000 | Only inside Azure AI Foundry, no raw results |
The last two rows need more detail. Search Engine Journal reported on September 11, 2026 that Google had published documentation for a Web Search Service API. Each request needed a partner client ID and the end user's IP address. Search Engine Roundtable reported on September 28, 2026 that the documentation was gone. We requested the old documentation URL with curl on November 8 and got a 404. So it is not an option you can put in a migration plan today.
On the Microsoft side, the Grounding with Bing pricing page lists $14 per 1,000 transactions. The same page says the output cannot be used directly in other applications. The how-to documentation adds that developers and end users cannot see the raw search results. You get a model answer with citations, not a page of JSON results. That is a different product from the old Bing Web Search API. Teams that need result data cannot use it as a drop-in replacement.
Google search API pricing compared with the alternatives
Price is the first thing a migration team checks. The table below compares the Google price, the Google and Microsoft replacements, and five third-party search APIs. The unit is 1,000 searches with 10 results each.
Third-party prices come from each pricing page, read on November 8, 2026, between 00:16 and 00:20 Singapore time. For credit-based plans, we used each provider's own statement of credits per search, and we show the arithmetic below. Our prices come from the price_usd field in the search tool catalog and the data capability catalog. We checked them against billing.charged_usd in every live response.
| Service | Entry paid tier | Lowest tier on page | Free quota | Source |
|---|---|---|---|---|
| Google Custom Search JSON API | $5.00 | $5.00 | 100 per day | overview |
| Google Agent Search Enterprise | $4.00 | $4.00 | 10,000 per month trial | Agent Search pricing |
| Grounding with Bing Search | $14.00 | $14.00 | None | Bing pricing page |
| SerpAPI | $25.00 | $3.75 | 250 per month | serpapi.com/pricing |
| Serper | $1.00 | $0.30 | 2,500 one time | serper.dev |
| Tavily | $8.00 | $5.00 | 1,000 credits per month | Tavily docs |
| Firecrawl | $7.60 | $1.50 | 1,000 credits per month | firecrawl.dev/pricing |
| Bright Data SERP API | $1.50 | $1.30 | 5,000 per month | brightdata.com |
EveryInfra web | $0.694 | $0.694 | $1 trial credit | catalog |
EveryInfra bing/search | $0.556 | $0.556 | Same | catalog |
EveryInfra web/search | $1.389 | $1.389 | Same | catalog |
Here is the arithmetic. The SerpAPI Starter plan is $25 per month for 1,000 searches, so the entry price is $25 per 1,000. Its lowest tier, Cloud 1M, is $3,750 for 1,000,000 searches, which is $3.75 per 1,000. The Serper Starter pack is $50 for 50,000 credits, and the page itself says $1.00 per 1,000. Its largest pack says $0.30 per 1,000, and all Serper credits expire after 6 months. Tavily's docs say a basic search costs 1 credit, at $0.008 pay as you go or $0.005 on the Growth plan.
Firecrawl's billing page says a search costs 2 credits per 10 results. The Hobby plan is $19 per month for 5,000 credits, which is 2,500 searches, or $7.60 per 1,000. The Scale plan is $749 per month for 1,000,000 credits, or 500,000 searches at $1.50 per 1,000. The Bright Data SERP API is $1.5 per 1,000 on pay as you go. Its Scale plan is $499 per month with 380,000 requests included and $1.3 per 1,000 after that.
The chart makes one point. For the most basic unit, one search with 10 results, the Google price of $5 sits in the upper middle. Many options cost less. But the chart shows entry tiers only.
At high volume, Serper reaches $0.30 per 1,000, which is lower than our $0.694. The SerpAPI $25 buys a full structured result page with ads, knowledge panels and local packs. That is a different product from an API that returns only titles, links and snippets. Decide which fields you need first, and compare prices second.
Monthly bill: the 100 free queries and the 10,000 daily cap
The Google price has two limits: 100 free queries per day and 10,000 queries per day at most. These two limits make the real monthly bill very different at different volumes. We used 30-day months and five daily volumes.
| Queries per day | Queries per month | Google Custom Search | Agent Search Enterprise | EveryInfra `web` | EveryInfra `bing/search` |
|---|---|---|---|---|---|
| 100 | 3,000 | $0 (all free) | $0 (inside trial) | $2.08 | $1.67 |
| 1,000 | 30,000 | $135.00 | $80.00 | $20.82 | $16.68 |
| 3,000 | 90,000 | $435.00 | $320.00 | $62.46 | $50.04 |
| 10,000 | 300,000 | $1,485.00 | $1,160.00 | $208.20 | $166.80 |
| 30,000 | 900,000 | Over the daily cap, not possible | $3,560.00 | $624.60 | $500.40 |
The formulas are simple. The Google bill is (daily queries − 100) × 30 × $0.005, and it stops at 10,000 per day. The Agent Search bill is (monthly queries − 10,000) × $0.004, and it covers website search on up to 50 domains, not the whole web. Our two columns are monthly calls times the catalog price. We have no monthly free quota. New accounts get a $1 trial credit that is valid for 24 hours after you claim it.
The chart shows three things. First, below 100 queries per day Google is free and we cost $2.08 per month. In that band, Google is cheaper until the shutdown. If that is your volume, there is no rush, but test a new API before the end of December. Second, above a few hundred queries per day, the gap grows by a factor of 7.2, which is $5 divided by $0.694. At 10,000 per day, the difference is $1,276.80 per month.
Third, the Google limit of 10,000 per day is a hard cap. To go higher, teams opened more projects. We have no daily cap.
Our limit is per minute. The pricing page says each account gets 60 calls per minute by default, shared by all keys on the account. That is up to 86,400 calls per day. For more, you can buy a 30-day rate package, or reach a higher top-up tier.
Here is an example for a typical US SaaS team. Say your product runs 2,000 searches on a weekday and 500 on a weekend day. A 30-day month with 22 weekdays and 8 weekend days then has 48,000 searches. On Google, after the daily free 100, the bill is (1,900 × 22 + 400 × 8) × $0.005 = $225.00. On our web tool, the same month costs 48,000 × $0.000694 = $33.31.
Parameter map: Custom Search JSON API parameters in the new API
Parameters take the most work in a migration. The Google cse.list reference lists more than 30 query parameters. We mapped the 22 that people really use to the three EveryInfra entry points. The "Checked" column names the live call that tested the row. Rows we did not test say "not tested" and follow the catalog description.
| Google parameter | What it does (Google docs) | `web` tool | `web/search` | `bing/search` | Checked |
|---|---|---|---|---|---|
key | API key in the URL | Authorization: Bearer header | Same | Same | 401 live |
cx | Search engine ID | None; returns 422 | None | None | 422 live |
q | Query | q | keyword | keyword | Live |
num | 1 to 10 results | num, 1 to 10 | Fixed, up to 10 | limit | Live |
start | First result index, start+num ≤ 100 | page (starts at 1) | None | None, first page only | 422 and paging live |
gl | User country, boosts local results | location (name or 2-letter code) | country | country | Live |
hl | Interface language | None | language | language (with country) | Live |
cr | Only documents from a country | None; location is close | None | None | Not tested |
lr | Only documents in a language | None | language is close | language is close | Not tested |
siteSearch | Include or exclude a site | site, or site: in q | site: in keyword | site: in keyword | Live |
siteSearchFilter | i include, e exclude | -site: in q | Same | Same | Not tested |
dateRestrict | Last N days, weeks, months, years | after, before (dates) | None | None | Live |
sort=date | Sort by date | None | None | None | — |
exactTerms | Phrase that must appear | Quotes in q | Same | Same | Live |
excludeTerms | Word that must not appear | -word in q | Same | Same | Live |
orTerms | At least one of these | OR in q | Same | Same | Not tested |
fileType | File extension | filetype:pdf in q | Same | Same | Live |
safe | SafeSearch | None | None | None | — |
searchType=image | Image search | None; use the media tool | None | None | Not tested |
filter | Duplicate content filter | None | None | None | — |
c2coff | Simplified and Traditional Chinese | None | None | None | — |
linkSite, lowRange, highRange, rights | Link, number range, license filters | None | None | None | — |
Two notes on this table. First, cx stands for a whole search engine setup: site lists, exclusions, boosts, synonyms and promoted results. You set all of that in the Google control panel, not in the request.
Our web tool has no "search engine" object. You put the site limit in each request with site: and exclusions with -site:. Boosts and promotions have no match. If your engine has dozens of site rules, turn them into a query template in your code.
Second, our web tool has no language parameter. Google uses hl for interface language and lr for document language. On our side, only web/search and bing/search take language. With the web tool, the query language decides the result language. That works in most cases. Multi-language monitors should use web/search.
Live test 1: Google parameters on the `web` tool
The parameter map comes from documentation. This section comes from live calls. On November 8, 2026, from 00:20 to 00:32 Singapore time, we sent the most common Google patterns to the web tool. We also copied the Google start and cx, and the Bing count, without changes. Each row is one raw response. The time is the end-to-end time measured on the client.
| Time (SGT) | Google pattern | What we sent | Result | Time | Charged |
|---|---|---|---|---|---|
| 00:20:27 | No key | No Authorization header | 401, "Missing API key" | 165 ms | $0 |
| 00:20:30 | start=11 | "start": 11 | 422, allowed lists 7 parameters | 211 ms | $0 |
| 00:20:34 | cx, gl | "cx": "…", "gl": "us" | 422, flags cx first | 111 ms | $0 |
| 00:20:42 | siteSearch=developers.google.com | "site": "developers.google.com" | 200, 0 results, refunded | 1,281 ms | $0 |
| 00:20:51 | gl=sg | "location": "sg" | 10 results, all about Singapore hawker centres | 1,591 ms | $0.000694 |
| 00:20:59 | dateRestrict=m1 | "after": "2026-10-09" | 10 results, all dated after October 9 | 2,437 ms | $0.000694 |
| 00:21:09 | start=11 | "page": 2 | 10 results, none repeated from page 1 | 1,924 ms | $0.000694 |
| 00:21:18 | start=101 (Google errors) | "page": 11 | 10 results, only 2 still on topic | 4,285 ms | $0.000694 |
| 00:21:29 | num=5 | "num": 5 | 5 results | 2,376 ms | $0.000694 |
| 00:21:38 | exactTerms + excludeTerms | "\"programmable search engine\" -reddit" | 7 results, all contain the phrase, none from reddit | 2,889 ms | $0.000694 |
| 00:21:48 | fileType=pdf | filetype:pdf in q | 7 results, all PDFs | 4,533 ms | $0.000694 |
| 00:30:42 | siteSearch in the query | site:developers.google.com in q | 10 results, all from that domain | 1,271 ms | $0.000694 |
| 00:32:05 | siteSearch=en.wikipedia.org | "site": "en.wikipedia.org" | 9 results, all from that domain | 2,313 ms | $0.000694 |
The table gives four findings.
First, the site parameter is not reliable. This is the most important finding to report honestly. For developers.google.com, the site parameter returned 0 results. The same domain written as site:developers.google.com inside the query returned 10 results, all official Custom Search documentation pages. For en.wikipedia.org, both forms returned 9 results. For docs.python.org with "asyncio timeout", both forms returned 0 results at 00:30:26 and 00:30:34 Singapore time, and both were refunded.
So our advice is direct. Move the Google siteSearch value into the query as site:, and do not depend on the site parameter. During the parallel run, test the domains you limit to most often. The same docs.python.org query with site: on bing/search returned 503 after 17.3 seconds, so we have no Bing result for site limits. In every call that returned results, no other domain appeared.
Second, paging has no 100-result limit, but results after 100 are of little use. The Google docs say the JSON API never returns more than 100 results, and start plus num above 100 is an error. Our page 11, which covers results 101 to 110, still returned 10 results and was charged.
Only 2 of the 10 were still about "custom search json api shutdown". The rest were changelogs from many technical sites. If your old code splits keywords to work around the 100-result limit, you can keep it. But do not expect useful results at position 200.
Third, date filters take calendar dates. Google dateRestrict=m1 means the last month. Our after takes a real date, so compute today minus 30 days in your code, as the example below shows.
In this call, 6 of 10 results were google.com/goto redirect links that need one more request to resolve. The page 11 call in live test 1 also had 6 redirect links in 10. The 12 normal web queries in live test 2 returned 114 results with no redirect links. So only call sites with date filters or deep pages need a redirect step before you store URLs.
Fourth, copied parameters are blocked, not silently ignored. Both start and cx returned 422. The allowed field listed seven names: after, before, location, num, page, q, site.
The next_steps field said to remove the parameter and confirmed that nothing was charged. This helps a migration. Google often ignores a misspelled parameter, so old code can carry parameters that never worked.
One example is daterestrict in lower case for dateRestrict. After the move, such a parameter returns 422 on the first call. It looks like a new API error, but it is an old code problem. The response gives param, allowed and next_steps, so you can fix each one in a single pass.
No one-to-one parameter: what to do with hl, safe, searchType and sort
Some rows in the parameter map say "None". These rows block migrations most often, so this section gives a replacement for each. Each suggestion is based on our 12 queries and 13 parameter tests, not on a guess from documentation.
Start with hl. Google uses hl for the interface language, which changes ranking a little. lr limits results to one language.
Our web tool has only location, which is a country. In live test 2, the Spanish query "receta paella valenciana" with es returned 8 results, and 7 were Spanish pages. The Mexican query "precio del dolar hoy mexico" with mx returned 10 Spanish pages. A Chinese query about food in Singapore with sg returned 10 Chinese pages, with simplified and traditional script mixed.
In most cases, the query language plus the country is enough. If you must set the language, use web/search. It has a language parameter and costs $0.001389 per call, twice the web tool. Use it for the few call sites that need a fixed language. The mixed Chinese scripts are what Google c2coff controls, and we have no switch for that.
Next is safe. Google safe=active filters adult content. None of our three entry points has this switch.
If your product serves children or schools, or needs strict brand safety, add a filter on your side. The simplest filter is a domain blocklist that you apply to each url after the call. A stricter option is to send titles and snippets to the moderation model you already use. Add this filter during the parallel run, not after the switch.
Then searchType=image. Google adds one parameter to search images. We keep images and video in a separate media tool, with q, kind and num, at $0.000694 per call. The response shape differs from the web tool. So for image call sites, change the parsing code too, not only the parameter names. We did not test the media tool for this article, so we report its parameters only.
Last is sort=date. Google date sorting works only on engines with structured data, and many teams found that it never worked for them. We have no sort parameter. Narrow the window with after and before, then sort on your side by the date field.
In live test 1, all 10 results from the after call had a date. But dates are raw strings, such as "Oct 19, 2026" or "5 days ago", so convert them first. For recent news, the news tool or google_news/search is a better fit. In our three tries, google_news/search returned 503 each time, so we have no result data for it.
Live test 2: 12 queries on three entry points, and how much the results overlap
The parameters map. The next question is whether the results look alike. We picked 12 queries. They cover developer docs, consumer products, Singapore housing, Spanish queries from Spain and Mexico, a Chinese query and a UK topic.
Between 00:22 and 00:30 Singapore time, we sent each query to the web tool, web/search and bing/search. That is 36 calls, all HTTP 200. We counted overlap by URL after we removed the protocol, www. and the trailing slash. We did not count redirect links. Counts are unique URLs per query.
| Query | Country | `web` unique URLs | `web/search` unique URLs | `bing/search` unique URLs | `web` and `web/search` | `web` and `bing/search` | In all three |
|---|---|---|---|---|---|---|---|
| google custom search api alternative | us | 10 | 10 | 10 | 10 | 1 | 1 |
| python requests timeout retry | us | 9 | 9 | 10 | 4 | 3 | 1 |
| best running shoes 2026 | us | 9 | 9 | 3 | 7 | 1 | 1 |
| hdb resale flat prices 2026 | sg | 9 | 10 | 7 | 8 | 3 | 3 |
| free weather api | us | 10 | 10 | 9 | 10 | 4 | 4 |
| kubernetes ingress nginx retirement | us | 10 | 10 | 10 | 7 | 5 | 3 |
| receta paella valenciana | es | 8 | 9 | 10 | 7 | 2 | 2 |
| precio del dolar hoy mexico | mx | 10 | 6 | 10 | 6 | 3 | 2 |
| Singapore food tips (Chinese query) | sg | 10 | 10 | 8 | 10 | 1 | 1 |
| openai agents sdk mcp tools | us | 9 | 10 | 6 | 6 | 2 | 2 |
| site search for university website | gb | 10 | 10 | 10 | 10 | 3 | 3 |
| bing search api retirement | us | 10 | 10 | 10 | 10 | 1 | 1 |
| Total | — | 114 | 113 | 103 | 95 | 29 | 24 |
Across 12 calls, the web tool returned 114 results. 95 of them also appeared in web/search, an overlap of 83%. Only 29 appeared in bing/search, which is 25%.
Only 24 URLs appeared in all three. The union of all three was 204 different URLs. So the first two entry points are close, and bing/search ranks the web in its own way. For "bing search api retirement", the web tool and web/search returned the same 10 URLs, and bing/search shared only 1 of them.
Some calls returned fewer than 10 results: bing/search returned 3 for "best running shoes 2026", and web/search returned 6 for the Mexico query. Each call was still charged, because only zero results get a refund. So the real cost per result is higher on rare queries.
These numbers help a migration in two ways. First, no new provider will match your old Google results exactly. In the parallel run, ask whether the results are good enough for your product, not what the overlap rate is.
Second, some products must not miss sources, such as a brand monitor. Those products can call both web and bing/search. Together they covered 188 different URLs on 12 queries, about 65% more than one entry point alone. The cost is $0.000694 plus $0.000556 per query.
The UK row is worth a look for British readers. "site search for university website" with gb returned 10 results on every entry point. The web tool and web/search returned the same 10. Only 3 of them were also in bing/search. If your own job is site search on one university or company website, the free Google embed may still be the right choice. The section on other providers explains when.
Each entry point has its own strengths in the fields it returns. The table below shows field coverage across the 12 queries.
| Entry point | Raw results | With snippet | With date | With sub-links | Price per call |
|---|---|---|---|---|---|
web tool | 114 | 110 (96.5%) | 46 (40.4%) | 0 | $0.000694 |
web/search | 114 | 105 (92.1%) | 40 (35.1%) | 7 (6.1%) | $0.001389 |
bing/search | 103 | 101 (98.1%) | 55 (53.4%) | 0 | $0.000556 |
Dates are raw strings on all three entry points.
Some read "Oct 19, 2026" and some read "5 days ago", so convert them before you store them. Google items has no standard date field. Dates hide in pagemap metatags, and many results lack them. So after the move, you get dates on more results than before.
Response fields: items[] becomes results[]
You also need to change the code that reads the response. The Google response shape follows OpenSearch 1.1. Results sit in an items array.
Each item has title, htmlTitle, link, displayLink, snippet, htmlSnippet, formattedUrl and pagemap. The outer object has searchInformation.totalResults and queries.nextPage. Our three entry points list their fields in response_fields in the catalog. We checked each field against our live responses.
| Google field | `web` tool | `web/search` | `bing/search` | Note |
|---|---|---|---|---|
items[].title | results[].title | results[].title | results[].title | Plain text, no bold markup |
items[].link | url | url | url | A few are redirect links, see live test 1 |
items[].displayLink | None; read the host from url | None | displayed_url | Breadcrumb style on bing/search |
items[].snippet | snippet | text | text | About 100 to 400 characters |
items[].pagemap | None | image_url (some) | None | Get structured data another way |
| No match | published | published_at | date_text | Publish date, raw string |
| No match | None | sub_links, rank | rank | Site links and position |
searchInformation.totalResults | None | None | None | No total estimate |
queries.nextPage | Add 1 to page yourself | None | None | — |
| No match | billing.charged_usd | billing.charged_usd | billing.charged_usd | Amount charged for this call |
The most common trap is totalResults. Much old code uses it to check for results or to count pages. After the move, that field is gone, so check whether results is empty. The second trap is htmlSnippet. Some site search pages put it straight into HTML to show bold matches. After the move, you add the highlight yourself.
How to change the code: one Python function, before and after
Here is typical old code. It calls customsearch/v1 with requests and collects the first 30 results.
import requests
def google_cse(q, pages=3):
out = []
for i in range(pages):
r = requests.get("https://www.googleapis.com/customsearch/v1", params={
"key": GOOGLE_KEY, "cx": CX, "q": q, "num": 10,
"start": 1 + i * 10, "gl": "us", "dateRestrict": "m1",
}, timeout=30)
items = r.json().get("items", [])
out += [{"title": x["title"], "url": x["link"], "snippet": x.get("snippet", "")} for x in items]
if not items:
break
return outThe EveryInfra web tool needs four changes. Change the URL and the method from GET to POST. Move the key from the URL to a header. Rename the parameters: start becomes page, gl becomes location, and dateRestrict=m1 becomes an after date. Rename the fields: items becomes results and link becomes url. Delete cx.
import os, datetime, requests
def everyinfra_web(q, pages=3):
after = (datetime.date.today() - datetime.timedelta(days=30)).isoformat()
out = []
for page in range(1, pages + 1):
r = requests.post("https://api.everyinfra.com/api/v1/search",
headers={"Authorization": f"Bearer {os.environ['EVERYINFRA_API_KEY']}"},
json={"tool": "web", "params": {"q": q, "num": 10, "page": page,
"location": "us", "after": after}},
timeout=60)
r.raise_for_status()
rows = r.json().get("results", [])
out += [{"title": x["title"], "url": x["url"], "snippet": x.get("snippet", "")} for x in rows]
if not rows: # empty pages are not charged; stop here
break
return outYou can also try one call with curl first. The request body is the same.
curl -s https://api.everyinfra.com/api/v1/search \
-H "Authorization: Bearer $EVERYINFRA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"tool":"web","params":{"q":"custom search json api shutdown","num":10,"page":2}}'Two behaviors differ from Google, and your code must handle them. The first is 422 for an unknown parameter, as live test 1 shows. Treat a 422 as "fix the parameter", not "retry". The second is 429. Each account gets 60 calls per minute by default. Above that, you get 429 with retry_after, so batch jobs must back off.
Bing search API alternative: moving from Bing Web Search v7
The Bing Web Search API went offline on August 11, 2025. Many teams that still look for a Bing replacement moved to a stopgap at the time. Now they want to compare prices again. Our bing/search capability searches with Bing syntax and returns the first page, about 10 web results. The catalog price is $0.000556 per call, which is $0.556 per 1,000. The table maps the Bing v7 query parameters to ours.
| Bing v7 parameter | What it does | `bing/search` | Note |
|---|---|---|---|
q | Query, with operators such as site: | keyword | Up to 2,048 characters |
count | Results per call, default 10, max 50 | limit | Sending count returns 422 |
offset | Results to skip, for paging | None | First page only |
mkt | Market, such as en-US | country + language | Split into two parameters |
setLang | Interface language | language | Works only together with country |
cc | Country code | country | — |
freshness | Day, Week, Month or a date range | None | Use after on the web tool |
safeSearch | Off, Moderate, Strict | None | — |
responseFilter | Only web pages, news and so on | None | Use google_news/search for news |
The parameter that Bing users get wrong most often is count. At 00:20:38 Singapore time, we sent count: 20, as a Bing user would. The 422 response listed four allowed names: keyword, country, language and limit. The result count is limit.
The same response has a did_you_mean hint. It is based on spelling, and at the time of writing it said country, which is wrong for a Bing user. So rename parameters from the allowed list. At 00:31:15 we sent limit: 5 and got 5 results in 4.46 seconds, charged $0.000556.
Latency: end-to-end time on the three entry points
Google returns searchInformation.searchTime, which is the search time inside its servers. We measured end-to-end time on the client, from request to full response, sent from Singapore over the public internet. That number matters more for your users. On 12 queries, the web tool had a median of 1.75 seconds, a minimum of 1.27 and a maximum of 2.72. web/search had a median of 2.16 seconds. bing/search had a median of 4.54 seconds and a slowest call of 9.25 seconds.
For site search where a user waits, the 1 to 3 seconds of the web tool are close to the Google experience. The 4 to 9 seconds of bing/search do not suit a user-facing path. Use it for background jobs. Also, one of our four temporary errors was a bing/search call that returned 503 after 17.3 seconds. Background jobs need a timeout of 60 seconds or more, plus retries.
Failures, empty results and errors: what costs money
The Google docs do not say whether failed requests cost money. They say only that billing is per query. The SerpAPI pricing page says only successful searches count, and cached, errored and failed searches do not. It also says a response with 100 results and an empty result set both count as 1 search. Our rule is that failures and empty results cost nothing.
This article made 59 live calls. 48 were charged, for a total of $0.039858. Here are the other 11 calls, each with a raw response.
| Time (SGT) | Entry point | Case | HTTP | Charged | What the response says |
|---|---|---|---|---|---|
| 00:20:27 | web | No key | 401 | $0 | "Nothing was charged" |
| 00:20:30 | web | Copied Google start | 422 | $0 | Lists 7 allowed parameters |
| 00:20:34 | web | Copied Google cx | 422 | $0 | Same |
| 00:20:38 | bing/search | Copied Bing count | 422 | $0 | did_you_mean says country (should be limit) |
| 00:20:42 | web | site parameter, 0 results | 200 | $0 | empty_result_refunded |
| 00:22:00 | google_news/search | Temporarily unavailable, try 1 | 503 | $0 | retry_after: 60, failure 1 of 3 |
| 00:30:26 | web | site parameter, 0 results | 200 | $0 | empty_result_refunded |
| 00:30:34 | web | site: in query, 0 results | 200 | $0 | empty_result_refunded |
| 00:30:51 | bing/search | Temporarily unavailable, 17.3 s | 503 | $0 | request_failed_refunded |
| 00:31:26 | google_news/search | Temporarily unavailable, try 2 (9 min 26 s later) | 503 | $0 | Failure 2 of 3 |
| 00:32:24 | google_news/search | Temporarily unavailable, try 3 (58 s later, no time_window) | 503 | $0 | Still says failure 2 of 3 |
The google_news/search 503 response says retryable: true, retry_after: 60 and max_retries: 2. Its next_steps says nothing was charged. Our three tries were 9 minutes 26 seconds and 58 seconds apart, and the third try had no time_window. All three returned 503, so the service was down for that period. We have no result data for it, and for news queries we give the parameters only. Batch jobs can follow retry_after and stop at max_retries.
The empty-result refund matters during a migration. In the parallel run, you send a batch of old queries as they are. Some may return nothing on the new API, like the site parameter calls above. Those calls cost nothing. You pay only for calls that return results.

Connect it to an AI agent: MCP setup and one round trip
Many teams used the Custom Search JSON API as a search tool for an agent, not for a web page. Our remote MCP address is https://api.everyinfra.com/mcp. On November 8, 2026, at 00:2x Singapore time, a tools/list call without a key returned 12 tools. The search tool is everyinfra_search. It takes tool and params, the same as the REST request body. For clients that support remote MCP, such as Claude Code or Cursor, the setup looks like this:
{
"mcpServers": {
"everyinfra": {
"type": "http",
"url": "https://api.everyinfra.com/mcp",
"headers": { "Authorization": "Bearer ${EVERYINFRA_API_KEY}" }
}
}
}At 00:31:56 Singapore time, we called everyinfra_search through MCP with {"tool": "web", "params": {"q": "custom search json api discontinued january 1 2027", "num": 5}}. After 2.35 seconds, it returned 5 results. The first was the Google overview page for the Custom Search JSON API.
Its snippet said existing customers have until January 1, 2027, and its date was Feb 18, 2026. That matches the "last updated 2026-02-18" footer we saw on the page itself. The call cost $0.000694, the same as REST. The model gets the same JSON as REST, with billing.charged_usd, so the agent can track its own spend.
If you used a Google search wrapper class in a framework such as LangChain, the simplest move is a small tool function of your own. Use the everyinfra_web function above and register it as a framework tool. Then a future provider change touches only that function. The MCP 2026-07-28 specification removed the initialization handshake and made the protocol stateless. Remote servers are easier to connect than a year ago. Our MCP page shows the setup for each client.
When another provider fits better
You do not have to move to us. In the cases below, another option fits better, and we say so plainly.
| Your situation | Better fit | Why |
|---|---|---|
| Search only your own 50 or fewer domains, in a web page | Programmable Search Element | Free and still offered by Google; we have no embeddable search box |
| Site search with your own ranking rules or generated answers | Google Agent Search Enterprise | It builds an index, boosts and controls ranking; we return open-web results only |
| Millions of calls per month, titles, links and snippets only | Serper Ultimate pack | Public price of $0.30 per 1,000, below our $0.694; credits expire after 6 months |
| Full result pages: ads, knowledge panels, local packs, shopping | SerpAPI, Bright Data SERP API | Full structured JSON for the page; SerpAPI lists dozens of engines |
| Agent search with page text in one call | Tavily | Each result carries relevant page text; we need web plus read |
| Crawl a whole site into Markdown | Firecrawl | Crawling is its core product; our crawl tool takes up to 20 pages per call |
| Results and a contract from Google itself | Apply for the Google full-web product | Only Google can offer it; price not public |
One SerpAPI point deserves its own note. Its pricing page lists a "US Legal Shield" on higher plans, with legal cover up to $2 million for scraping and parsing search results. If your legal team needs that, we do not offer it. On Serper credit expiry, our Serper alternative article shows the math. At 1,000 calls per month, the real price on the smallest pack is $8.33 per 1,000.
What we cannot do
This section lists our limits for the people who make the decision. Our web tool is not an official Google API. Its ranking may differ from google.com, and we do not promise Google rank positions. Rank trackers and SEO reports need exact positions and full result pages. They should use a result-page service such as SerpAPI, or test a batch of terms on our web/search, which has a rank field.
We have no searchType=image match. Images and video use the media tool with different parameters. We have no SafeSearch switch, so products for children or schools need their own filter. Our web tool has no language parameter. We have no daily cap like Google's 10,000, but the default limit is 60 calls per minute, so bursts wait in line. We do not offer a free embedded search box with ads, so you build the site search interface yourself.
Two more limits matter for a migration. First, we charge a prepaid balance per call. There is no end-of-month cloud invoice and no committed-use discount contract. Teams that need invoices and company payments should check that their finance process accepts prepaid credit.
Second, we have no SLA document for your procurement file. In this article, google_news/search failed three times and bing/search failed once, and the tables show each case. For high-availability call sites, connect two entry points and fail over. If both fail, you pay nothing.
What to watch after the switch
The switch is not the end. For the first two weeks, check three numbers each day. You can compute all three from the responses, with no extra monitoring system.
| Number | Where it comes from | Normal value | First thing to check if it rises |
|---|---|---|---|
| Empty-result rate | results is empty | 0 of 12 normal queries in our test | Call sites that use the site parameter |
| 422 count | HTTP status and param | Close to 0 after day two | Old scripts with Google parameter names |
| Daily total charged | Sum of billing.charged_usd | Calls × catalog price | Loops and paging with no stop condition |
The empty-result rate needs care. In this article, 3 of 6 site-limited queries were empty, and that is why live test 1 says to put site: in the query. Empty results cost nothing, so the bill does not grow, but your users notice "no results" before your finance team does.
For 422 errors, log the param field and sort by count. On day one, they tend to come from rarely used features, such as a month-end report script.
For the daily total charged, add up billing.charged_usd from each response and compare it with your estimate. The web tool costs $0.000694 per call, bing/search $0.000556 and web/search $0.001389. If the real total is clearly higher, look for a loop that repeats the same query, or paging with no stop condition. Google stopped you at 10,000 per day. We do not, so always set a maximum page count.
Migration checklist: six steps
Here is the work as a checklist. Each step has one action and the reason for it. In this order, you can finish the switch by mid-December and keep two weeks of buffer.
- Inventory: search your code for
customsearch/v1andcx=. List each call site, its parameters and its daily volume. - Map parameters: rename them with the parameter map above. Flag call sites that use
safe,searchType=imageorsort, because they have no direct match. - Run both for one week: send the same real queries to the old and new APIs. Compare URL overlap, empty results and latency.
- Switch: make the new API the main path. Keep the old key as a fallback until late December.
- Watch errors: look at 422 (missed renames), empty results (
siteusage) and 429 (over the per-minute limit). - Clean up: delete the old
cxand Google key before December 31, 2026. Then January errors do not look like a new problem.
Step 3 is the step teams skip most often, and it matters most. Our own test shows that results from different entry points overlap less than people expect, as live test 2 shows. Neither side is wrong. Search services rank differently. The goal of the parallel run is not "the same as Google".
The goal is "good enough for our product". Say your product checks the top 10 results for bad news about a brand. Then run 50 real brand names and read the results by hand. If your product looks up official websites, check that the first result is the official site. Write the pass criteria before the run, not after you see results.
The parallel run itself costs money, but not much. The table assumes 500 real queries per day for 7 days, which is 3,500 calls on each side.
| Side of the parallel run | Calculation | Cost for 7 days |
|---|---|---|
EveryInfra web tool | 3,500 × $0.000694 | $2.43 |
EveryInfra bing/search (optional) | 3,500 × $0.000556 | $1.95 |
| Google Custom Search | (500 − 100) × 7 × $0.005 | $14.00 |
| Total | — | $18.38 |
The full parallel run costs less than $20, which is far less than one production incident. Empty results and failures cost nothing, so you can add rare queries and site-limited queries at no extra cost.
Recent changes, October to November 2026
Search APIs changed quickly in the last month. These items affect a migration directly. Each row says what the change means for you.
| Date | Change | What it means for you |
|---|---|---|
| 2026-10-16 | A Google community manager reposted the January shutdown notice in the help forum | No sign of a delay; plan for January 1 |
| 2026-10-23 | Firecrawl published a Google Search JSON API alternative article with prices read that day | Third parties compete for these users; check each pricing page yourself |
| 2026-10-27 | Another existing project reported a 403 "project has no access" in the help forum | Existing customers can lose access early; do not wait for the last week of December |
| 2026-11-03 | SerpAPI released serpapi-mcp v2.1.0 with updated engine parameters; v2.2.0 on November 4 added an extract tool | Result-page services now add page reading, so the line between product types moves |
| 2026-11-06 | AddSearch published a site search migration guide with three groups: up to 50 domains, more than 50, and JSON API | Site search users and whole-web users need different answers |
The October 27 item needs attention. The thread title is "Custom Search JSON API 403: project has no access despite enabled API and configured engine". The poster says the console shows the API as enabled and the engine is set up, but requests return 403. Similar threads go back to February, such as this one from February 21. So "existing customers keep access until January 1" may not hold for every project. If your product depends on search, start the parallel run now.
Get started: three steps to switch
First, sign up in the quickstart and get an API key. New accounts that star both everyinfra/everyinfra-agent-plugins and everyinfra/seo-skills on GitHub can claim a $1 trial credit in the console. That covers about 1,440 web searches and is valid for 24 hours after you claim it. Second, run the curl command above with your most common query, and check results and billing.charged_usd. Third, replace the old call with the Python function above, or add the MCP setup to your agent.
The web search product page has the full tool reference. You can try every data capability online in the marketplace, and prices are on the pricing page. For country and language search, see the web/search capability page. For Bing, see bing/search. For news, see google_news/search. Platform overviews are on the Web search, Bing and Google News pages.
FAQ
Is there a Google search API?
Yes, but a new developer can no longer switch on a whole-web search API from Google. The Custom Search JSON API is closed to new customers and shuts down on January 1, 2027. Agent Search covers 50 domains at most. The full-web product needs an application, and its price is not public. This question comes from the Google autocomplete phrases "is there a google search api" and "does google have a search api".
How does Google search API pricing work, and is any of it free?
From Google's own page: existing customers get 100 free queries per day. After that, they pay $5 per 1,000, with at most 10,000 per day, until January 1, 2027. At the full 10,000 per day, a month costs $1,485. Agent Search Enterprise costs $4.00 per 1,000, with 10,000 free trial queries per month. The Programmable Search Element embed is free but shows ads. There is no permanently free whole-web JSON search API from Google.
This question comes from the autocomplete phrases "google search api pricing", "google custom search api pricing" and "is google search api free".
What is the cheapest whole-web search for 60,000 queries a month after Custom Search closes?
A Reddit thread in r/googlecloud asks this exact question. The poster ran 40,000 queries per month, soon 60,000, on the whole web, and wanted a price close to $5 per 1,000. With the prices in this article, 60,000 calls per month cost $41.64 on our web tool and $33.36 on bing/search. A Serper Starter pack is $50 for 50,000 calls within 6 months. The SerpAPI Searcher plan is $725 per month for 100,000 searches. The right choice depends on whether you need full result pages.
What are the Bing search API alternatives?
Microsoft points to Grounding with Bing Search, at $14 per 1,000, only inside Azure AI Foundry and without raw results. For raw results, use a result-page service (SerpAPI and Bright Data both support Bing), or our bing/search at $0.556 per 1,000. This question comes from the autocomplete phrases "bing search api alternative" and "bing search api replacement".
Why does the Custom Search API return 403 "This project does not have the access"?
This is the standard error for projects created after January 20, 2026. A Google community manager confirmed it in this help forum thread. On October 27, an existing project reported the same error. A new project has no way to get access, so it must move to another API. This question comes from the related Google search "This project does not have the access to Custom Search JSON API".
References
- Custom Search JSON API overview (closed to new customers, Jan 1, 2027 deadline, $5 per 1,000, 100 free per day, 10,000 per day cap), Google for Developers, updated 2026-02-18, read on November 8, 2026.
- Method: cse.list (q, num, start, gl, hl, cr, lr, siteSearch, dateRestrict, safe, searchType), Google for Developers, read on November 8, 2026.
- Search response shape (items, searchInformation, queries.nextPage), Google for Developers, read on November 8, 2026.
- Custom Search JSON API: Introduction (key, cx, OpenSearch 1.1), Google for Developers, read on November 8, 2026.
- Using REST to invoke the API (request URL, 100 results per query maximum), Google for Developers, read on November 8, 2026.
- Custom Search Site Restricted JSON API (stopped on January 8, 2025), Google for Developers, read on November 8, 2026.
- site: search operator, Google Search Central, read on November 8, 2026.
- Custom Search JSON API endpoint, Google, read on November 8, 2026.
- Updates to our Web Search Products (new engines limited to 50 domains), Programmable Search Engine Blog, 2026-01-20, read on November 8, 2026.
- Update sites in your search engine (changes from January 20, 2026), Programmable Search Engine Help, read on November 8, 2026.
- Community thread: Updates to our web search products, Programmable Search Engine Community, new reply on 2026-10-16, read on November 8, 2026.
- Community thread: Custom Search JSON API 403, project has no access, Programmable Search Engine Community, 2026-10-27, read on November 8, 2026.
- Community thread: 403 This project does not have the access to Custom Search JSON API, Programmable Search Engine Community, read on November 8, 2026.
- Community thread: Custom Search API full web search solution (community manager reply), Programmable Search Engine Community, reply on 2026-03-03, read on November 8, 2026.
- Migrate from Custom Search JSON API, Google Cloud, read on November 8, 2026.
- Vertex AI product name changes (Vertex AI Search becomes Agent Search), Google Cloud, read on November 8, 2026.
- Agent Search pricing (Standard $1.50 and Enterprise $4.00 per 1,000, 10,000 trial queries per month), Google Cloud, read on November 8, 2026.
- Google Documents Partner-Only API For Full Web Search Results, Search Engine Journal, 2026-09-11, read on November 8, 2026.
- Google Web Search Service API Documentation Removed, Search Engine Roundtable, 2026-09-28, read on November 8, 2026.
- Google documents a partner-only Web Search Service API as Custom Search shutdown nears, SEO Forum, read on November 8, 2026.
- Bing Search API retirement (August 11, 2025), Microsoft Learn, read on November 8, 2026.
- Bing Web Search API v7 query parameters (q, count, offset, mkt, setLang, freshness), Microsoft Learn, read on November 8, 2026.
- Grounding with Bing Search (answers for agents, no raw results), Microsoft Learn, read on November 8, 2026.
- Grounding with Bing Search pricing ($14 per 1,000), Microsoft, read on November 8, 2026.
- SerpApi Pricing, SerpApi, read on November 8, 2026.
- SerpApi Google Search API documentation, SerpApi, read on November 8, 2026.
- serpapi-mcp releases (v2.1.0, v2.2.0), GitHub, 2026-11-03 / 2026-11-04, read on November 8, 2026.
- Serper home page (pricing, 2,500 free queries, 6-month credit validity), Serper, read on November 8, 2026.
- Tavily Pricing, Tavily, read on November 8, 2026.
- Tavily API Credits (basic search is 1 credit), Tavily Docs, read on November 8, 2026.
- tavily-mcp releases, GitHub, read on November 8, 2026.
- Firecrawl Pricing, Firecrawl, read on November 8, 2026.
- Firecrawl Billing (search is 2 credits per 10 results), Firecrawl Docs, read on November 8, 2026.
- firecrawl-mcp-server releases (v3.36.1), GitHub, 2026-11-03, read on November 8, 2026.
- Google Search JSON API alternative, Firecrawl Blog, 2026-10-23, read on November 8, 2026.
- Bright Data SERP API pricing, Bright Data, read on November 8, 2026.
- Bright Data SERP API introduction, Bright Data Docs, read on November 8, 2026.
- google-api-python-client releases (v2.201.0), GitHub, 2026-09-30, read on November 8, 2026.
- OpenSearch 1.1 draft 6 (the spec behind the Custom Search response), GitHub, read on November 8, 2026.
- MCP specification 2026-07-28 changelog, Model Context Protocol, 2026-07-28, read on November 8, 2026.
- Migrating Off Google Programmable Search Before the 2027 Deadline, AddSearch, 2026-11-06, read on November 8, 2026.
- Google Custom Search API is closing. Need affordable Open Web Search alternative for 60k req/month, Reddit r/googlecloud, read on November 8, 2026.
- Is Google's Custom Search API being discontinued? (new keys returned 403 on January 20, 2026), Reddit r/googlecloud, read on November 8, 2026.
- Google quietly announced that Programmable Search won't allow new engines to search the entire web, Hacker News, read on November 8, 2026.
- Google Search for Discourse AI (deprecation notice, March 2026), Discourse Meta, read on November 8, 2026.
- EveryInfra search tool catalog (web tool parameters and price), EveryInfra, read at 00:14:49 SGT, read on November 8, 2026.
- EveryInfra data capability catalog (web/search, bing/search, google_news/search), EveryInfra, read at 00:14:49 SGT, read on November 8, 2026.
- EveryInfra remote MCP endpoint (everyinfra_search), EveryInfra, read on November 8, 2026.
Reference BL-113