Google Custom Search API in Go
The call that still answers.
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 Go code that calls it stops on that day.
SpecStream answers the same call. In google.golang.org/api v0.311.0, add option.WithEndpoint("https://api.specstream.ai/") and pass a SpecStream key with option.WithAPIKey. Its svc.Cse.List().Do() ran 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 page.
New accounts get $10 of credit, no card. It covers 2,000 searches.
The Custom Search call from Go: 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.golang.org/api v0.311.0 (customsearch/v1) with option.WithEndpoint("https://api.specstream.ai/") and option.WithAPIKey. 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 Go code that called Custom Search moves to SpecStream
customsearch/v1: the same call with one more option
This is code that calls Google today, with google.golang.org/api/customsearch/v1:
svc, err := customsearch.NewService(ctx,
option.WithAPIKey(os.Getenv("GOOGLE_API_KEY")),
)
if err != nil {
log.Fatal(err)
}
res, err := svc.Cse.List().Q("web data api").Cx(os.Getenv("GOOGLE_CSE_ID")).Do()And the whole program on SpecStream. option.WithEndpoint("https://api.specstream.ai/") is added to customsearch.NewService and option.WithAPIKey takes a SpecStream key. svc.Cse.List().Q(...).Cx(...).Do() and the code that reads res.Items stay as they were. This is the call that ran on November 10, 2026 with v0.311.0 and printed 10 items.
package main
import (
"context"
"fmt"
"log"
"os"
"google.golang.org/api/customsearch/v1"
"google.golang.org/api/option"
)
func main() {
ctx := context.Background()
svc, err := customsearch.NewService(ctx,
option.WithAPIKey(os.Getenv("SPECSTREAM_API_KEY")),
option.WithEndpoint("https://api.specstream.ai/"), // the one changed option
)
if err != nil {
log.Fatal(err)
}
res, err := svc.Cse.List().Q("web data api").Cx(os.Getenv("GOOGLE_CSE_ID")).Do()
if err != nil {
log.Fatal(err)
}
fmt.Println(len(res.Items), "items")
for _, item := range res.Items {
fmt.Println(item.Title, item.Link)
}
}The same call with net/http, no module 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 data.Items is an empty slice and the loop runs zero times.
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"net/url"
"os"
)
type reply struct {
Items []struct {
Title string `json:"title"`
Link string `json:"link"`
Snippet string `json:"snippet"`
} `json:"items"`
Error *struct {
Message string `json:"message"`
} `json:"error"`
}
func main() {
params := url.Values{}
params.Set("key", os.Getenv("SPECSTREAM_API_KEY"))
params.Set("cx", "any")
params.Set("q", "open source vector databases")
params.Set("num", "10")
resp, err := http.Get("https://api.specstream.ai/customsearch/v1?" + params.Encode())
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
if resp.StatusCode == http.StatusTooManyRequests {
log.Fatalf("busy, retry after %s s", resp.Header.Get("Retry-After"))
}
var data reply
if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
log.Fatal(err)
}
if data.Error != nil {
log.Fatal(data.Error.Message)
}
for _, item := range data.Items {
fmt.Println(item.Title, item.Link, item.Snippet)
}
}An error comes back in Google's shape, {"error": {"code", "message", "errors", "status"}}, so the client library's *googleapi.Error 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.
for _, start := range []int64{1, 11, 21} {
res, err := svc.Cse.List().Q("open source vector databases").Cx("any").Num(10).Start(start).Do()
if err != nil {
log.Fatal(err)
}
for _, item := range res.Items {
fmt.Println(item.Link)
}
if len(res.Queries.NextPage) == 0 {
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.
$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 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 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 Go
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 Go 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 SpecStream scores
The same numbers as the benchmarks page, from the official tasks and scorers.
How to run the Go 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"
go get google.golang.org/api/customsearch/v13. In code that uses customsearch.NewService, add option.WithEndpoint("https://api.specstream.ai/") and pass the SpecStream key to option.WithAPIKey. In code that builds the URL with net/http, 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. What changes on January 1, 2027 is on the shutdown page.
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
Something we didn't answer? Talk to a human
How do I use the Google Custom Search API in Go?
customsearch.NewService from google.golang.org/api/customsearch/v1, then svc.Cse.List().Q(...).Cx(...).Do(), or send GET /customsearch/v1 with net/http. 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.Which Go client works with SpecStream?
google.golang.org/api v0.311.0 ran svc.Cse.List().Do() against SpecStream on November 10, 2026 and returned 10 items. The setting is option.WithEndpoint("https://api.specstream.ai/"), and the key goes in option.WithAPIKey.Is there a customsearch Go example that still runs?
customsearch/v1 package with 1 option added, option.WithEndpoint, and a SpecStream key.Which parameters does the route honour?
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?
What happens when a call is busy?
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 overviewdevelopers.google.com/custom-search/v1/overview, read Nov 9, 2026
- Google Custom Search JSON API reference, cse.listdevelopers.google.com/custom-search/v1/reference/rest/v1/cse/list, read Nov 9, 2026
- Google Custom Search JSON API, using RESTdevelopers.google.com/custom-search/v1/using_rest, read Nov 9, 2026
- Google Custom Search terms of servicedevelopers.google.com/custom-search/terms, read Nov 9, 2026
- Programmable Search Engine blog: updates to our web search productsprogrammablesearchengine.googleblog.com/2026/01/updates-to-our-web-search-products.html, read Nov 9, 2026
- Google Cloud: Agent Search pricingcloud.google.com/generative-ai-app-builder/pricing, read Nov 9, 2026
- Google Cloud: servingConfigs.search methodcloud.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 Searchai.google.dev/gemini-api/docs/google-search, read Nov 9, 2026
- Brave Search APIbrave.com/search/api/, read Nov 9, 2026
- Brave, alternatives to the Google Search APIbrave.com/learn/google-api-shutdown/, read Nov 9, 2026
- SpecStream benchmarksspecstream.ai/benchmarks, read Nov 10, 2026
- SpecStream pricingspecstream.ai/pricing, read Nov 10, 2026
- SpecStream for agentsspecstream.ai/agents.md, read Nov 10, 2026




