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

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

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 C# code that calls it stops on that day.

SpecStream answers the same call. In `Google.Apis.CustomSearchAPI.v1` 1.78.0.3520, set `BaseUri` on `BaseClientService.Initializer` to `https://api.specstream.ai/` and put a SpecStream key in `ApiKey`. Its `service.Cse.List().Execute()` ran 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-csharp) page.

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

## The Custom Search call from C#: 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 | `Google.Apis.CustomSearchAPI.v1` 1.78.0.3520 with `BaseClientService.Initializer.BaseUri = "https://api.specstream.ai/"` and `ApiKey`. It ran 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 C# code that called Custom Search moves to SpecStream

### Google.Apis.CustomSearchAPI.v1: the same call with one more property

This is code that calls Google today, with the `Google.Apis.CustomSearchAPI.v1` NuGet package:

```
var service = new CustomSearchAPIService(new BaseClientService.Initializer
{
    ApiKey = Environment.GetEnvironmentVariable("GOOGLE_API_KEY"),
    ApplicationName = "my-app",
});

var request = service.Cse.List();
request.Q = "web data api";
request.Cx = Environment.GetEnvironmentVariable("GOOGLE_CSE_ID");
var result = request.Execute();
```

And the same program on SpecStream. `BaseUri` on `BaseClientService.Initializer` is set to `https://api.specstream.ai/` and `ApiKey` holds a SpecStream key. `service.Cse.List()`, `Q`, `Cx`, `Execute()` and the code that reads `result.Items` stay as they were. This is the call that ran on November 10, 2026 with 1.78.0.3520 and printed 10 items.

```
using Google.Apis.CustomSearchAPI.v1;
using Google.Apis.Services;

var service = new CustomSearchAPIService(new BaseClientService.Initializer
{
    ApiKey = Environment.GetEnvironmentVariable("SPECSTREAM_API_KEY"),
    BaseUri = "https://api.specstream.ai/", // the one changed option
    ApplicationName = "my-app",
});

var request = service.Cse.List();
request.Q = "web data api";
request.Cx = Environment.GetEnvironmentVariable("GOOGLE_CSE_ID"); // any value is accepted
var result = request.Execute();

Console.WriteLine($"{result.Items.Count} items");
foreach (var item in result.Items)
    Console.WriteLine($"{item.Title} {item.Link}");
```

### The same call with HttpClient, no package to add

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 code checks for it with `TryGetProperty`.

```
using System.Net;
using System.Text.Json;

var key = Environment.GetEnvironmentVariable("SPECSTREAM_API_KEY");
var q = Uri.EscapeDataString("open source vector databases");
var url = $"https://api.specstream.ai/customsearch/v1?key={key}&cx=any&q={q}&num=10";

using var http = new HttpClient();
using var response = await http.GetAsync(url);
if (response.StatusCode == HttpStatusCode.TooManyRequests)
{
    Console.WriteLine($"busy, retry after {response.Headers.RetryAfter}");
    return;
}

using var doc = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
var root = doc.RootElement;
if (root.TryGetProperty("error", out var error))
    throw new Exception(error.GetProperty("message").GetString());

if (root.TryGetProperty("items", out var items))
{
    foreach (var item in items.EnumerateArray())
        Console.WriteLine($"{item.GetProperty("title")} {item.GetProperty("link")}");
}
```

An error comes back in Google's shape, `{"error": {"code", "message", "errors", "status"}}`, so the client library's `GoogleApiException` and code that reads `error.message` keep 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.

```
// Page with Start: 1, 11, 21. Each page of up to 10 is one search.
foreach (var start in new long[] { 1, 11, 21 })
{
    var page = service.Cse.List();
    page.Q = "open source vector databases";
    page.Cx = "any";
    page.Num = 10;
    page.Start = start;
    var reply = page.Execute();
    foreach (var item in reply.Items ?? new List<Google.Apis.CustomSearchAPI.v1.Data.Result>())
        Console.WriteLine(item.Link);
    if (reply.Queries?.NextPage == null) break;
}
```

### 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-csharp).

### $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-csharp) 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-csharp) 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 C# and .NET

### 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 .NET 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 .NET 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"
dotnet add package Google.Apis.CustomSearchAPI.v1
```

3. In code that uses `CustomSearchAPIService`, add `BaseUri = "https://api.specstream.ai/"` to the `BaseClientService.Initializer` and put the SpecStream key in `ApiKey`. In code that calls the URL with `HttpClient`, 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-csharp). 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-csharp).

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 C#?

Build a `CustomSearchAPIService` from the `Google.Apis.CustomSearchAPI.v1` package and call `service.Cse.List().Execute()`, or send `GET /customsearch/v1` with `HttpClient`. Google closed the API to new customers and ends it on January 1, 2027. The same call works at `https://api.specstream.ai/` with a SpecStream key.

### Does Google.Apis.CustomSearchAPI.v1 work with SpecStream?

Yes. Version 1.78.0.3520 ran `service.Cse.List().Execute()` against SpecStream on November 10, 2026 and returned 10 items, with `BaseClientService.Initializer.BaseUri` set to `https://api.specstream.ai/` and the key in `ApiKey`.

### How do I call the Custom Search API from .NET without the NuGet package?

Send 1 `GET` to `https://api.specstream.ai/customsearch/v1?key=...&cx=any&q=...` with `HttpClient` and parse `items` with `System.Text.Json`, as in the example above.

### 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-csharp) 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
