This article was written with AI assistance and reviewed and tested by me.
If your site search page, CMS plugin, docs portal or chatbot calls https://www.googleapis.com/customsearch/v1, it stops working on 1 January 2027. This post covers what is changing, the realistic options for searching your own site, what each one costs, and a small adapter that lets you keep your existing result parser whatever backend you pick.
Not affiliated with, endorsed by or sponsored by Google. "Google", "Custom Search" and "Programmable Search Engine" are trademarks of Google LLC.
What's happening
- The Custom Search JSON API is closed to new customers, and "existing Custom Search JSON API customers have until January 1, 2027 to transition to an alternative solution" (Google's notice). Until then it costs $5 per 1,000 queries after 100 free queries a day, capped at 10,000 queries a day.
- The Site Restricted variant (
/customsearch/v1/siterestrict) already stopped serving traffic on 8 January 2025. - The Programmable Search Element (the embeddable search box) is not going away for engines that search up to 50 domains ("Sites to search"), and it stays free (announcement, 20 Jan 2026).
So first ask: what does your code use the API for?
You use customsearch/v1 to... |
What to do |
|---|---|
| show a Google search box on your site | Switch to (or keep) the Search Element, up to 50 domains |
| get JSON results from your own site(s) for your own UI, a CMS, an app or a RAG bot | Read on |
| search the whole web (agents, SEO, research) | You need a web search API, or Google's full web search interest form. Out of scope here |
The options for own-site search
1. Programmable Search Element (Google's widget)
What it is: Google's embeddable search box and results page, limited to the sites you list.
Cost: free.
Migration effort: low if you only ever displayed results; you paste the widget code.
Pros: Google's ranking, no infrastructure, no billing.
Cons: no JSON. You can't feed results into your own UI, a backend or a chatbot, and you get Google's look and its limits on customisation.
2. Agent Search (formerly Vertex AI Search)
What it is: Google's recommended replacement. The migration guide has you create a "Site search with AI mode" app in Google Cloud (Enterprise edition on, generative responses off) with a Website Content data store for your URL patterns.
Cost: website search needs Enterprise edition, $4 per 1,000 queries. There is a free trial of 10,000 queries per account per month. Storage for website data is counted as 500 KiB per page, with 10 GiB free; Google's own example puts a 1,000-page site at $2.38 a month (pricing).
Migration effort: medium to high. It is a different API: servingConfigs.search (OAuth / service account) or searchLite (API key), results under results[].document.derivedStructData, paging with offset/nextPageToken. Expect to rewrite the client and the parser, or use the adapter below.
Pros: results come from Google's index of your site, so ranking quality is excellent; optional AI answers and a no-code widget.
Cons: you need a Google Cloud project with billing; past the free trial it is one of the pricier per-query options; new pages appear when Google crawls them.
3. Pagefind (static sites)
What it is: a fully static search library. It indexes your built HTML at deploy time and searches in the visitor's browser. It works with any static site generator (Hugo, Jekyll, MkDocs, Docusaurus, Astro...). Pagefind says a full-text search on a 10,000-page site loads under 300 kB in total, closer to 100 kB for most sites.
Cost: free, MIT licence. No server, no per-query fees.
Migration effort: low for static sites: add one build step and a UI component.
Pros: zero running cost, no API key to protect, the index always matches the deploy, built-in filtering and multilingual support.
Cons: search runs in the browser, so there is no server-side JSON API for a backend or a chatbot (Pagefind has Node and Python indexing libraries, but querying happens client-side). Content that only exists after JavaScript runs must be in the built HTML.
4. Meilisearch (self-hosted or cloud)
What it is: an open-source search engine with a REST API. You push documents (title, URL, text) from your CMS, database or a crawler.
Cost: self-hosting is free; the community edition is MIT-licensed, while some enterprise features are under the Business Source License (licence file). Meilisearch Cloud starts at $20/month with a 14-day free trial (pricing).
Migration effort: medium. You write the indexing job and adapt the query code.
Pros: full control over your data and ranking, keyword plus optional AI (hybrid) search, no per-query fees when self-hosted.
Cons: you run it (updates, backups, keeping the index fresh) or pay for the cloud plan.
5. Typesense and Algolia (briefly)
- Typesense is similar to Meilisearch: open source (GPL-3.0), self-host for free, or use Typesense Cloud, which bills dedicated clusters by memory and vCPU rather than per query.
- Algolia is hosted search with a crawler. Its Free plan includes 10,000 search requests and 5,000 crawls a month with 50,000 records; the pay-as-you-go Grow plan then charges $0.50 per extra 1,000 search requests. Public technical docs and technical blogs can apply for the free DocSearch program.
6. Third-party CSE-compatible APIs
What it is: services that accept the old customsearch/v1 request (q, cx, start, num) and return the same JSON, so your client code keeps working after you change the base URL and the credentials.
Cost: varies; usually pay-per-use.
Migration effort: lowest of all, often a config change.
Pros: no rewrite; your parser, pagination and error handling keep working.
Cons: check what is behind them. Many proxy a web index and ignore cx, so you may get pages from other sites, and new pages appear only when they crawl them. Ranking is not Google's. You add a dependency on a small vendor.
Disclosure: I built one of these, Site Search on Apify. It crawls only the domains you give it, builds a keyword index of your own pages, and uses cx as the index name. Pricing is $1 per 1,000 new or changed pages indexed, $0.10 per 1,000 unchanged pages on re-index and $1.50 per 1,000 searches, plus Apify server time for the always-on endpoint. Its limits: keyword (BM25) ranking with no semantic search, no image search, JavaScript-only pages are not indexed, the first request after an idle minute takes a few seconds, and so far it has been tested on indexes of up to about 160 pages.
A related option: a web search API restricted to your domain, such as the Brave Search API ($5 per 1,000 requests) with site:example.com. It only finds pages that are already in that provider's web index.
Rough cost comparison
List prices on 31 Oct 2026, search queries only (your hosting and time not included):
| Monthly searches | Custom Search (until 1 Jan 2027) | Agent Search, Enterprise | Pagefind | Meilisearch / Typesense self-hosted |
|---|---|---|---|---|
| 3,000 | ~ $0 (inside 100/day free) | $0 within the 10,000-query free trial | $0 | $0 + server |
| 30,000 | ~ $135 | ~ $80 (20,000 x $4/1,000) | $0 | $0 + server |
At low volume Agent Search's free trial is hard to beat. At higher volume, the self-hosted and static options win on price, and you pay in setup and maintenance time instead.
A generic migration: keep your old parser
Most Custom Search clients only read items[].title, items[].link, items[].snippet, searchInformation.totalResults and queries.nextPage. Whatever backend you choose, you can put a small function on your server that maps its results into that shape, so the rest of your code (templates, CMS plugin, chatbot tools) doesn't change.
// Wrap results from any backend into the old customsearch/v1 shape
function toCseResponse({ q, start = 1, num = 10, total, hits }) {
const items = hits.map((h) => ({
kind: "customsearch#result",
title: h.title,
link: h.url,
displayLink: new URL(h.url).hostname,
snippet: h.snippet ?? "",
}));
const res = {
kind: "customsearch#search",
searchInformation: {
totalResults: String(total), // Google sent strings
formattedTotalResults: String(total),
},
queries: { request: [{ searchTerms: q, startIndex: start, count: items.length }] },
};
if (items.length) res.items = items; // Google omitted `items` on zero results
const next = start + num;
if (next <= Math.min(total, 100)) { // and stopped paging after result 100
res.queries.nextPage = [{ searchTerms: q, startIndex: next, count: num }];
}
return res;
}
Here it is with Meilisearch as the backend (Node 18+). Note that start is 1-based, while most engines use a 0-based offset:
async function search(q, start = 1, num = 10) {
const r = await fetch(`${process.env.MEILI_URL}/indexes/pages/search`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.MEILI_KEY}`,
},
body: JSON.stringify({
q, offset: start - 1, limit: num,
attributesToCrop: ["content"], cropLength: 20,
}),
});
if (!r.ok) throw new Error(`search failed: ${r.status}`);
const data = await r.json();
return toCseResponse({
q, start, num,
total: data.estimatedTotalHits,
hits: data.hits.map((h) => ({ title: h.title, url: h.url, snippet: h._formatted?.content })),
});
}
I ran it against a local Meilisearch 1.56 with three test pages:
Timeouts -> https://docs.example.com/timeouts/
total: 2 next: 2
A query with no matches returns totalResults: "0" and no items key, just like Google did. For Agent Search, map results[].document.derivedStructData the same way; for Typesense or Algolia, map their hits. Keep API keys on the server, as you did with the old key.
Checklist before 1 January
-
grep -r "googleapis.com/customsearch"your code, config and env vars (also checkcustomsearch.googleapis.comandsiterestrict). - Decide per call site: widget only (Search Element), own-site JSON (pick an option above), whole web (web search API).
- Move the endpoint and credentials into env vars, and keep keys on the server.
- Run your old test queries against the new backend and compare the top results before you switch traffic.
- Schedule re-indexing (or index on deploy) so new pages show up.
Not affiliated with Google.
Top comments (1)
The shutdown date makes migration planning concrete. The key decision is not just which replacement search product to choose, but which parts of relevance, indexing cadence, analytics, and access control are currently implicit in the old integration and need explicit tests after the move.