GuidesSEARCH APIS

Google Search API from JavaScript

Google's Custom Search JSON API sends CORS headers, so fetch() works from the page with no proxy, but Google closed it to new customers and ends it on 1 January 2027; existing customers get 100 free queries a day. For new projects, Serper returns Google results with CORS headers and 2,500 free queries, and SerpApi works through the free cors.dev proxy (no signup, GET and HEAD, about 600 requests a minute per IP) because its key rides in the URL. Fetching google.com/search itself through the proxy returned 429 or a script-only page with no results in our 28 October 2026 test.

Custom Search JSON API works in browsers

Google's Custom Search JSON API sends CORS headers, so you call it with fetch() directly, no proxy needed. On 28 October 2026, GET https://www.googleapis.com/customsearch/v1?key=<invalid>&cx=<invalid>&q=cors with Origin: https://example.com answered 400 with a 743-byte JSON error ("API key not valid. Please pass a valid API key.") and Access-Control-Allow-Origin: https://example.com. The customsearch.googleapis.com host, the /siterestrict variant and the OPTIONS preflight all echoed the origin the same way.

Each request needs an API key (key) and a Programmable Search Engine ID (cx). Results arrive in items, each with title, link and snippet, in JSON that follows the OpenSearch 1.1 specification; errors come back as an error object with code and message.

Custom Search JSON API with fetch(), no proxy
async function googleSearch(query, { key, cx, start = 1 }) {
  const params = new URLSearchParams({ key, cx, q: query, start: String(start) });
  const response = await fetch('https://www.googleapis.com/customsearch/v1?' + params);
  const data = await response.json();

  if (data.error) {
    throw new Error(`Custom Search ${data.error.code}: ${data.error.message}`);
  }

  return (data.items ?? []).map(({ title, link, snippet }) => ({ title, link, snippet }));
}

// Results 11 to 20; start + num can never pass 100
const results = await googleSearch('cors proxy', {
  key: 'YOUR_API_KEY',
  cx: 'YOUR_SEARCH_ENGINE_ID',
  start: 11,
});
console.log(results);

num returns at most 10 results per request and start sets the first result, so start=11 is page 2. A query never yields more than 100 results, and start plus num above 100 is an error.

Custom Search JSON API limits, checked October 2026
ItemValueNote
Free queries100 a dayExisting customers only
Paid queries$5 per 1,000Existing customers only
Daily cap10,000 queriesUpper limit per day
Results per requestUp to 10Set with num
Results per queryUp to 100start plus num above 100 errors
New customersClosedPer Google's overview page
End of service1 January 2027Existing customers must move by then

Closed to new customers, ending 2027

Google's overview page, last updated 18 February 2026 and read 28 October 2026, says: "The Custom Search JSON API is closed to new customers." Existing customers have until 1 January 2027 to move, and the pricing applies only to them until then.

Google calls Vertex AI Search a favorable alternative for searching up to 50 domains, and asks teams that need full web search to contact Google about its full web search solution. Whichever key you use, a key in browser code is readable by every visitor.

The Programmable Search Element widget

The Search Element is Google's embeddable search box and results page. Its markup carries only the engine ID, no API key, and it renders Google's own result UI, which can include ads; Google documents a separate ads-free paid version.

Google's January 2026 update positions it for site search: the free "Sites to search" feature covers up to 50 domains, and engines set to "Search the entire web" or more than 50 domains must move to another solution by 1 January 2027.

  1. Load the script

    Add <script async src="https://cse.google.com/cse.js?cx=YOUR_ENGINE_ID"></script> to the page.

  2. Place the element

    Put <div class="gcse-search"></div> where the box and results go, or split them with gcse-searchbox and gcse-searchresults; gcse-searchbox-only and gcse-searchresults-only also exist.

  3. Configure it

    Set options with data- attributes such as data-autoCompleteMaxCompletions="5" and hook into results through callbacks on window.__gcse.

Scraping google.com/search fails

https://www.google.com/search?q=cors, requested from a server in Germany on 28 October 2026, answered 200 with a page of about 94 KB that holds no results, only scripts and a note to click if the redirect does not happen. Through the free cors.dev proxy it answered either that same script-only page or 429 with a 3,213-byte page saying "Our systems have detected unusual traffic from your computer network", and hl=en&gl=us changed nothing.

The results page is HTML for people, not an API, and a proxy does not turn it into one.

SERP APIs that return Google results

  • Serper (google.serper.dev): Google results as JSON with CORS headers. The preflight answered 204 with Access-Control-Allow-Origin: * and X-API-KEY allowed, and a bad key got a 403 with CORS headers. 2,500 free queries with no card, then $50 for 50,000 queries down to $0.30 per 1,000; credits last 6 months.
  • SerpApi (serpapi.com): No CORS headers (401 without Access-Control-Allow-Origin, OPTIONS answered 404). The key rides in the api_key query parameter, so https://proxy.cors.dev/ forwards it as-is and returns CORS headers. Free plan 250 searches a month, paid from $25 for 1,000.
  • Brave Search API: Brave's own index, not Google's. No CORS headers, 405 on the preflight, and the key goes in X-Subscription-Token, which the free proxy refuses with 400 header_not_allowed and cors.dev Pro forwards. $5 per 1,000 requests with $5 of free credit a month.
  • Tavily (api.tavily.com): Built for LLM apps, answered with Access-Control-Allow-Origin: *, has a keyless mode and 1,000 free credits a month.
Serper search straight from the browser
async function serperSearch(query, apiKey) {
  const response = await fetch('https://google.serper.dev/search', {
    method: 'POST',
    headers: { 'X-API-KEY': apiKey, 'Content-Type': 'application/json' },
    body: JSON.stringify({ q: query }),
  });
  const data = await response.json();

  if (!response.ok) {
    throw new Error(`Serper ${response.status}: ${data.message}`);
  }

  return data.organic ?? [];
}

const userKey = localStorage.getItem('serper_key');
const organic = await serperSearch('cors proxy', userKey);

for (const { position, title, link } of organic) {
  console.log(position, title, link);
}

Ways to get Google results in browser JavaScript, checked October 2026
OptionResults fromFree allowanceBrowser CORSHow to call it
Custom Search JSON APIGoogle100 queries a day, existing customersYesfetch() directly until 1 January 2027
SerpApiGoogle250 searches a month, 50 an hourNoFree proxy, key in the URL
SerperGoogle2,500 queries, no cardYesPOST directly with X-API-KEY
Brave Search APIBrave's own index$5 credit a monthNocors.dev Pro forwards the token header
google.com/search pageGoogle HTMLNoneNoNot viable, 429 or no results

The free proxy needs no signup, allows GET and HEAD at about 600 requests a minute per IP, and forwards query-string keys as-is. cors.dev Pro costs $5 a month for 500,000 requests, with a 7-day trial of 1,000 requests and no card, and adds POST and credential headers from origins you register.

Google autocomplete suggestions

For typeahead completions instead of result links, https://suggestqueries.google.com/complete/search?client=firefox&q=cors answered 200 with a 258-byte JSON array of 10 suggestions and no CORS header. Through the free proxy the same 258 bytes arrived with CORS headers. Google called it "a non-official, non-published API" in 2015; the Google autocomplete guide covers parameters, encodings and debouncing.

Good questions.

Can I still get a Google Custom Search JSON API key?

No. Google's overview page says the Custom Search JSON API is closed to new customers, and existing customers have until 1 January 2027 to move. For up to 50 domains Google points to Vertex AI Search; for full web search it asks you to contact Google.

Is there a free Google search API for JavaScript?

Not from Google for new projects. Serper gives 2,500 free queries without a card and works with fetch() directly; SerpApi's free plan gives 250 searches a month through https://proxy.cors.dev/. The Programmable Search Element is free for site search across up to 50 domains.

Which Google results API works with fetch() without a proxy?

Serper. Its preflight answered 204 with Access-Control-Allow-Origin: * and allows the X-API-KEY header, so a POST to https://google.serper.dev/search works from the page. Existing Custom Search JSON API customers can also call it directly until 1 January 2027.

Does a CORS proxy hide my Google search API key?

No. A key in browser JavaScript, in the URL or a header, is readable by every visitor, and cors.dev does not change that. Keep your own key on a backend for public products, or let each user bring their own key.

Can I show Google results on my site without an API key?

Yes, with the Programmable Search Element: load https://cse.google.com/cse.js?cx=YOUR_ENGINE_ID and add <div class="gcse-search"></div>. It needs only the engine ID and renders Google's own UI, which can include ads. Since Google's January 2026 update, it targets site search across up to 50 domains.