<!-- twin of https://specstream.ai/google-custom-search-api-javascript -->
# Google Custom Search API in JavaScript: the call that still answers

Compared on Nov 10, 2026. The page: https://specstream.ai/google-custom-search-api-javascript

Google ends the Custom Search JSON API on January 1, 2027, and it is closed to new customers. A new project gets no key, and Node.js code that calls it stops on that day.

SpecStream answers the same call. In `googleapis` 189.0.0 or `@googleapis/customsearch` 12.0.1, set `rootUrl` to `https://api.specstream.ai/` and pass a SpecStream key as `key`. Both clients ran `cse.list` against it on November 10, 2026 and got 10 items.

Searches cost $5 per 1,000, the rate Google charges, with no cap of 10,000 a day. SpecStream scores 97.9 F-score on all 1,000 SimpleQA Verified questions, shown on the [benchmarks](https://specstream.ai/benchmarks?utm_source=alternatives&utm_campaign=google-custom-search-api-javascript) page.

[Get an API key](https://specstream.ai/signup?src=alternatives-google-custom-search-api-javascript&utm_source=alternatives-md&utm_campaign=google-custom-search-api-javascript&returnTo=%2Fworkspace%2Fsearch%3Froute%3Dgoogle) New accounts get $10 of credit, no card. It covers 2,000 searches.

## The Custom Search call from Node.js: SpecStream, Google and Vertex AI Search

| | SpecStream | Google Custom Search JSON API | Vertex AI Search |
|---|---|---|---|
| The call | `GET https://api.specstream.ai/customsearch/v1` with `key`, `q`, `num` and `start`. Any `cx` is accepted | `GET https://www.googleapis.com/customsearch/v1` with `q`, an API key and `cx`, the ID of a Programmable Search Engine you configured | `POST https://discoveryengine.googleapis.com/v1/{servingConfig}:search`, with its own request and reply |
| Google's client library | `googleapis` 189.0.0 and `@googleapis/customsearch` 12.0.1 with `rootUrl: "https://api.specstream.ai/"`. Both ran `cse.list` on November 10, 2026 and returned 10 items | The same client, on Google's address and a Google key, for existing customers until January 1, 2027 | Not the Custom Search client: the call is a `POST` to `discoveryengine.googleapis.com`, so the `cse.list` code is rewritten |
| Open to new customers | Yes. A key takes a minute and comes with $10 of credit, no card | No. Closed to new customers, and discontinued on January 1, 2027 | Yes, with a free trial of 10,000 queries per account a month |
| What it searches | The whole live web at the moment of the call. `siteSearch` keeps a search to one site | The Programmable Search Engine you configured | Up to 50 domains. For full web search, Google asks you to contact it |
| Price per 1,000 | $5 per 1,000 searches of up to 10 results, with no daily cap | $5 per 1,000 queries after 100 free queries a day, up to 10,000 a day, for existing customers | $1.50 per 1,000 queries on Search Standard Edition, $4.00 on Search Enterprise Edition |
| What your code reads | Google's JSON: `items` with `title`, `link`, `snippet`, `displayLink`, `htmlTitle`, `htmlSnippet` and `formattedUrl`, `searchInformation.totalResults` and `queries.nextPage` | An `items` array with the URL, title and text snippets of each result, in JSON | Search Enterprise Edition adds generated answers, at $4.00 per 1,000 queries |
| Results a call | `num` from 1 to 10, as on Google, and `start` for the next page | 1 to 10 results a call, and never more than 100 for a query | Billed per query: any API call to Enterprise Search counts as one |
| A busy or failed call | A busy call answers `429` in Google's error form with `Retry-After`, and is not charged | Its terms say you may be charged for each successful request | A request is any API call, direct or through an integration or the console |

## Why Node.js code that called Custom Search moves to SpecStream

### googleapis: the same call with one changed option

This is code that calls Google today, with `googleapis` 189.0.0:

```
import { google } from "googleapis";

const customsearch = google.customsearch({ version: "v1" });

const res = await customsearch.cse.list({
  q: "web data api",
  cx: process.env.GOOGLE_CSE_ID,
  key: process.env.GOOGLE_API_KEY,
});
console.log(res.data.items.length, res.data.items[0].title);
```

And the same code on SpecStream. `rootUrl` on `google.customsearch` is set to `https://api.specstream.ai/` and the key is a SpecStream key. `cse.list`, its parameters and the code that reads `res.data.items` stay as they were. This is the call that ran on November 10, 2026 and printed 10 items.

```
import { google } from "googleapis";

const customsearch = google.customsearch({
  version: "v1",
  rootUrl: "https://api.specstream.ai/", // the one changed option
});

const res = await customsearch.cse.list({
  q: "web data api",
  cx: process.env.GOOGLE_CSE_ID, // any value is accepted
  key: process.env.SPECSTREAM_API_KEY,
});
console.log(res.data.items.length, res.data.items[0].title);
```

With `@googleapis/customsearch` 12.0.1 the option is the same, `rootUrl` on `customsearch({ version: "v1", rootUrl })`. It ran the same day and returned 10 items.

```
import { customsearch } from "@googleapis/customsearch";

const client = customsearch({ version: "v1", rootUrl: "https://api.specstream.ai/" });
const res = await client.cse.list({ q: "web data api", cx: "any", key: process.env.SPECSTREAM_API_KEY });
for (const item of res.data.items ?? []) console.log(item.title, item.link);
```

### The same call with fetch, no package to install

`fetch` is built into Node.js 18 and newer. The reply is Google's JSON: `items` with `title`, `link` and `snippet`, `searchInformation.totalResults` and `queries.nextPage`. A search that finds nothing has no `items`, as on Google, so the loop reads `data.items ?? []`.

```
const params = new URLSearchParams({
  key: process.env.SPECSTREAM_API_KEY,
  cx: "any",
  q: "open source vector databases",
  num: "10",
});

const reply = await fetch(`https://api.specstream.ai/customsearch/v1?${params}`);
if (reply.status === 429) {
  console.log("busy, retry after", reply.headers.get("Retry-After"), "s");
} else {
  const data = await reply.json();
  if (!reply.ok) throw new Error(data.error.message);
  console.log(data.searchInformation.totalResults, "results");
  for (const item of data.items ?? []) {
    console.log(item.title, item.link, item.snippet);
  }
}
```

An error comes back in Google's shape, `{"error": {"code", "message", "errors", "status"}}`, so code that reads `error.message` keeps working.

### Paging with start and queries.nextPage

`start` is 1-based, as on Google. Each reply carries `queries.nextPage` while more results exist, so the loop stops when it is gone. Each page of up to 10 results is one search at $0.005.

```
const URL_BASE = "https://api.specstream.ai/customsearch/v1";

async function search(q, pages = 3) {
  let start = 1;
  const found = [];
  for (let i = 0; i < pages; i++) {
    const params = new URLSearchParams({ key: process.env.SPECSTREAM_API_KEY, cx: "any", q, num: "10", start: String(start) });
    const data = await (await fetch(`${URL_BASE}?${params}`)).json();
    found.push(...(data.items ?? []));
    const next = data.queries?.nextPage;
    if (!next) break;
    start = next[0].startIndex;
  }
  return found;
}

for (const item of await search("open source vector databases")) console.log(item.link);
```

### The parameters your code already sends

The route honours nine parameters as Google does: `q`, `num`, `start`, `hq`, `exactTerms`, `orTerms`, `excludeTerms`, `siteSearch` and `siteSearchFilter`. `fileType`, `dateRestrict`, `lowRange` and `highRange` are accepted and not applied, so code that sends them still gets results. Any `cx` is accepted. Every parameter and every field is listed in the [migration guide](https://specstream.ai/migrate/google-custom-search?utm_source=alternatives&utm_campaign=google-custom-search-api-javascript).

### $5 per 1,000 searches and the best published scores

A call of up to 10 results is $0.005, with no cap of 10,000 a day, and a busy call that answers `429` is not charged. SpecStream scores 97.9 F-score on all 1,000 SimpleQA Verified questions (978 correct) and 64.0 item F1 and 43.4 row F1 on all 200 WideSearch tasks. On production on November 9, 2026, the median search took 0.82 s at 1 search a second and 1.07 s at 20 a second.

### What is kept from a search

On a key with zero retention, only the charge's account, key, request ID, price and time: no request text and no answer after the reply. Set `"zero_retention": true` when you create the key, or later on the same key.

### The same key reads pages and returns rows

The [Extract API](https://specstream.ai/extract-api?utm_source=alternatives&utm_campaign=google-custom-search-api-javascript) reads up to 20 pages or documents a call at $0.80 per 1,000 pages and scores 0.908 F1 on WCXB. [Deep Search](https://specstream.ai/deep-search?utm_source=alternatives&utm_campaign=google-custom-search-api-javascript) takes a request in plain words and returns every match as structured rows at 5¢, 15¢ or $1 a row, with the most a run can cost quoted before it starts.

## Other options for the Custom Search JSON API in JavaScript and Node.js

### Vertex AI Search

The product Google points Custom Search customers to, for up to 50 domains, at $1.50 per 1,000 queries on Search Standard Edition. Its call is a `POST` to `discoveryengine.googleapis.com` with a different request and reply, so the Node.js code that reads `items` is rewritten. SpecStream answers the `cse.list` call you already send, across the whole web.

### Grounding with Google Search in the Gemini API

A Gemini model runs the searches and writes an answer grounded in the results, at $14 per 1,000 search requests on Gemini 3 and newer after 5,000 free a month. Your code receives the model's answer. SpecStream returns `items` with `title`, `link` and `snippet` at $5 per 1,000.

### Brave Search API

A search API on Brave's own index at $5 per 1,000 requests, with $5 in free credits every month and 50 queries per second. Brave's own guide says moving from Google means swapping the endpoint and updating how you read the response. On SpecStream the code that reads Google's response stays as it is.

## How to run the Node.js example

1. Create a key under Agents & API in the workspace. A new account gets $10 of credit, no card, which covers 2,000 searches.

2. Put it in the environment and install the client if you use it.

```
export SPECSTREAM_API_KEY="your key"
npm install googleapis
```

3. In code that uses `googleapis`, add `rootUrl: "https://api.specstream.ai/"` where `google.customsearch` is built and pass the SpecStream key as `key`. In code that calls the URL with `fetch` or `axios`, change `https://www.googleapis.com` or `https://customsearch.googleapis.com` to `https://api.specstream.ai`.

4. Check the address with curl. A `200` with `items` means the key and the route work.

```
curl "https://api.specstream.ai/customsearch/v1?key=$SPECSTREAM_API_KEY&cx=any&q=web+data+api&num=3"
```

The same call from Python, with `requests` and with `google-api-python-client`, is on the [Python page](https://specstream.ai/google-custom-search-api-python?utm_source=alternatives&utm_campaign=google-custom-search-api-javascript). What changes on January 1, 2027 is on the [shutdown page](https://specstream.ai/google-custom-search-api-shutdown?utm_source=alternatives&utm_campaign=google-custom-search-api-javascript).

When your product needs every match in place of a results page, write the request in plain words. SpecStream reads it back as the conditions every row must meet and the facts to bring back, quotes the most it can cost, and delivers the rows after you approve.

## Frequently asked questions

### How do I use the Google Custom Search API in JavaScript?

Send `GET /customsearch/v1` with `key`, `cx` and `q` from `fetch` or `googleapis`, and read `items`. Google closed the API to new customers and ends it on January 1, 2027. The same call works at `https://api.specstream.ai/customsearch/v1` with a SpecStream key.

### Is there an npm package for the Google Custom Search API?

Two: `googleapis` and `@googleapis/customsearch`. On November 10, 2026, version 189.0.0 of the first and 12.0.1 of the second ran `cse.list` against SpecStream with `rootUrl` set to `https://api.specstream.ai/`, and each returned 10 items.

### Can I keep my googleapis customsearch Node example?

Yes, with 1 changed option: add `rootUrl: "https://api.specstream.ai/"` to `google.customsearch({ version: "v1" })` and send a SpecStream key as `key`. `cse.list`, `cx` and the code that reads `res.data.items` stay as they are.

### Which parameters does the route honour?

Nine: `q`, `num`, `start`, `hq`, `exactTerms`, `orTerms`, `excludeTerms`, `siteSearch` and `siteSearchFilter`. `fileType`, `dateRestrict`, `lowRange` and `highRange` are accepted and not applied, and any `cx` is accepted.

### What does the Google Custom Search API cost?

$5 per 1,000 queries after 100 free queries a day, up to 10,000 queries a day, for existing customers until January 1, 2027. SpecStream costs $5 per 1,000 searches of up to 10 results with no daily cap, and every rate is on the [pricing](https://specstream.ai/pricing?utm_source=alternatives&utm_campaign=google-custom-search-api-javascript) page.

### What happens when a call is busy?

It answers `429` in Google's error form with a `Retry-After` header, and it is not charged. Wait the number of seconds in `Retry-After` and send the call again.

## Sources

SpecStream wrote this page. Each figure about Google comes from Google's own pages, and each other figure from that company's own page. The client runs are from November 10, 2026.

- [Google Custom Search JSON API overview](https://developers.google.com/custom-search/v1/overview), read Nov 9, 2026
- [Google Custom Search JSON API reference, cse.list](https://developers.google.com/custom-search/v1/reference/rest/v1/cse/list), read Nov 9, 2026
- [Google Custom Search JSON API, using REST](https://developers.google.com/custom-search/v1/using_rest), read Nov 9, 2026
- [Google Custom Search terms of service](https://developers.google.com/custom-search/terms), read Nov 9, 2026
- [Programmable Search Engine blog: updates to our web search products](https://programmablesearchengine.googleblog.com/2026/01/updates-to-our-web-search-products.html), read Nov 9, 2026
- [Google Cloud: Agent Search pricing](https://cloud.google.com/generative-ai-app-builder/pricing), read Nov 9, 2026
- [Google Cloud: servingConfigs.search method](https://cloud.google.com/generative-ai-app-builder/docs/reference/rest/v1/projects.locations.collections.engines.servingConfigs/search), read Nov 9, 2026
- [Gemini API: Grounding with Google Search](https://ai.google.dev/gemini-api/docs/google-search), read Nov 9, 2026
- [Brave Search API](https://brave.com/search/api/), read Nov 9, 2026
- [Brave, alternatives to the Google Search API](https://brave.com/learn/google-api-shutdown/), read Nov 9, 2026
- [SpecStream benchmarks](https://specstream.ai/benchmarks), read Nov 10, 2026
- [SpecStream pricing](https://specstream.ai/pricing), read Nov 10, 2026
- [SpecStream for agents](https://specstream.ai/agents.md), read Nov 10, 2026
