---
title: "¿Existe una API de búsqueda de Google? Opciones tras Custom Search"
slug: google-search-api
date: 2026-10-18T11:31:46+00:00
modified: 2026-10-18T11:31:47+00:00
permalink: https://brightdata.es/blog/datos-web/google-search-api
type: blog
---

[ Blog ](https://brightdata.es/blog "Blog") / [Datos web](https://brightdata.es/blog/datos-web)







 [Datos web](https://brightdata.es/blog/datos-web)

# ¿Existe una API de búsqueda de Google? Opciones tras Custom Search

Aprende a migrar de la Custom Search JSON API de Google a la API SERP de Bright Data, con un adaptador cse.list() listo para usar y un mapa de parámetros.

 8 min de lectura





 [ ![Satyam Tripathi](https://media.brightdata.es/2024/09/Satyam-Tripathi-50x50.png) ](https://brightdata.com/blog/authors/satyam-tripathi)

 [Satyam Tripathi

Technical Writer

 ](https://brightdata.com/blog/authors/satyam-tripathi)





 ![Is There a Google Search API](https://media.brightdata.es/2026/10/Is-There-a-Google-Search-API_.png)





Google cerró su Custom Search JSON API a nuevos clientes, y el acceso de los clientes existentes terminará el 1 de enero de 2027. Entonces, ¿hay una API de búsqueda de Google a la que aún puedas suscribirte? No para resultados de toda la web, porque las opciones públicas de Google buscan en sitios elegidos o devuelven respuestas de Gemini basadas en Google Search. La API SERP de Bright Data devuelve resultados de Google de toda la web como JSON.

Custom Search JSON API devuelve un 403 a los proyectos nuevos. Las solicitudes HTTP directas a google.com fallaron silenciosamente en las pruebas, con estado 200 y 0 resultados.

Esta guía compara las opciones de Google, explica por qué fallan las solicitudes directas y muestra cómo migrar.

## Resumen

- **Google no vende ninguna API de búsqueda de autoservicio de toda la web a nuevos desarrolladores.** La fecha de finalización de Custom Search JSON API es el 1 de enero de 2027.
- **Grounding con Google Search devuelve respuestas de Gemini, no listas de resultados.** Sus términos prohíben almacenar en caché o analizar los resultados, o indexar sus enlaces.
- **Las solicitudes HTTP directas a Google Search no obtuvieron resultados en las pruebas.** Luego, los navegadores en la misma conexión recibieron un CAPTCHA.
- **La API SERP de Bright Data devuelve la página de resultados de Google como JSON.** 5K solicitudes al mes son gratuitas, luego $1.50 por cada 1,000 solicitudes exitosas. Un adaptador listo para usar convierte las llamadas a `cse.list()`.

## Qué reemplazo de Custom Search API se adapta a tu código

Averigua qué necesita tu código:

Si tu código necesitaUsaResultados de búsqueda de Google de toda la web[API SERP de Bright Data](#migrate)Búsqueda limitada a una lista fija de sitios[API SERP de Bright Data](#step-3) con filtros `site:`, o [Agent Search, de Google](#google-options)Mantener los parámetros existentes de `cse.list()`[El adaptador del paso 3](#step-3)Resultados de Google Images[El adaptador del paso 3](#step-3) con `searchType="image"`Una herramienta de búsqueda MCP (Model Context Protocol), LangChain o n8n[Bright Data Web MCP, una herramienta de LangChain, o el nodo de n8n](#agent-tools)Una respuesta de Gemini mostrada al usuario que preguntó[Grounding con Google Search](#google-options)Una solución para un mensaje de error[La tabla de solución de problemas](#troubleshooting)## Qué pasó con la Google Custom Search JSON API

Google anunció el cierre el 20 de enero de 2026. Su [resumen de Custom Search JSON API](https://developers.google.com/custom-search/v1/overview) marca la API como “cerrada a nuevos clientes” y da a los clientes existentes hasta el 1 de enero de 2027.

![Página de Google for Developers para la Custom Search JSON API, con su nota destacada. La nota dice que la API está cerrada a nuevos clientes, nombra a Vertex AI Search como la alternativa para hasta 50 dominios, pide a los usuarios de toda la web que contacten a Google, y da a los clientes existentes hasta el 1 de enero de 2027.](https://media.brightdata.com/2026/10/rk7YQLLoMg.png)Los proyectos nuevos ya reciben un 403 de Custom Search JSON API, incluso antes de la fecha límite de 2027. Esta es la respuesta, acortada a sus campos principales.

```none
{
  "error": {
    "code": 403,
    "message": "This project does not have the access to Custom Search JSON API.",
    "status": "PERMISSION_DENIED"
  }
}
```

En el foro de desarrolladores de Google, un desarrollador reporta este 403 en un proyecto existente después de un cambio de facturación.

La tabla pone los límites documentados de Google junto a la [API SERP de Bright Data](/products/serp-api):

Custom Search JSON APIAPI SERP de Bright DataUso gratuito100 consultas al día, unas 3K al mes5K solicitudes al mes, sin tarjeta de créditoUso de pago$5 por cada 1,000 consultas, hasta 10K al día[$1.50 por cada 1,000 solicitudes exitosas](/pricing/serp), concurrencia ilimitadaResultados por solicitudHasta 10Una página completa de resultados de GoogleResultados por consultaHasta 100Pagina con `start`, u obtén las posiciones 1 a 100 en una sola llamadaUbicación`gl` favorece resultados de un paísResultados tal como los ve un usuario en el país que configuresQué devuelve la APIResultados de un Programmable Search Engine, que busca en un subconjunto del índice de GoogleLa página de resultados de Google, incluyendo anuncios y People Also Ask cuando Google los muestra. Un parámetro extra añade el AI OverviewLa migración es más fácil de lo que parece, porque los resultados de Custom Search ya diferían de los resultados de google.com. La [página de ayuda](https://support.google.com/programmable-search/answer/70392?hl=en) de Google dice que un motor de toda la web busca solo en “un subconjunto del total del corpus de Google Web Search” y excluye resultados en tiempo real. Así que no necesitas reproducir los resultados antiguos exactamente. Comprueba los nuevos resultados contra google.com, y usa resultados guardados de Custom Search para encontrar errores en tu migración.

## Las propias alternativas de Google a Custom Search API

Google dirige a los usuarios de Custom Search hacia Agent Search y un formulario de interés para toda la web. Grounding con Google Search, una función de la API de Gemini, también aparece cuando buscas un reemplazo:

Producto y alcanceQué devuelvePrecio de listaAgent Search (también llamado Vertex AI Search), para hasta 50 dominiosResultados y respuestas de esos sitios[$4 por cada 1,000 consultas de búsqueda en sitios web](https://cloud.google.com/generative-ai-app-builder/pricing)Grounding con Google Search (API de Gemini), para Google SearchUna respuesta de Gemini con enlaces[$14 por cada 1,000 solicitudes de búsqueda](https://ai.google.dev/gemini-api/docs/pricing)Solución de búsqueda de toda la web, para el índice completo de GoogleNo documentado públicamenteSolo formulario de interésSi tu motor buscaba en una lista fija de sitios, tienes 2 opciones. La API SERP de Bright Data acepta la misma lista como filtros `site:`, y Agent Search admite hasta 50 dominios.

Grounding es el producto más cercano a la búsqueda web, pero sus términos limitan lo que puedes construir. Los [términos de la API de Gemini](https://ai.google.dev/gemini-api/terms) exigen que muestres los resultados fundamentados al usuario que preguntó. Prohíben “almacenar en caché, enmarcar, sindicar, revender, analizar, entrenar con, o aprender de otro modo” de esos resultados o indexar sus enlaces.

Microsoft también retiró sus APIs de Bing Search en agosto de 2025. Nuestras guías sobre [alternativas a la API de Bing Search](/blog/web-data/best-bing-search-apis) y las [mejores APIs SERP](/blog/web-data/best-serp-apis) comparan a los demás proveedores.

Ninguno de los productos de autoservicio de Google ofrece a los nuevos clientes resultados de búsqueda de toda la web. La API SERP de Bright Data sí.

## Por qué fallan las solicitudes directas a Google Search

Con el cierre de Custom Search, la alternativa obvia es solicitar directamente la página de resultados de Google. Google Search requiere JavaScript desde enero de 2025. En pruebas desde 1 conexión de banda ancha doméstica, 10 solicitudes de clientes HTTP y luego varios navegadores reales no obtuvieron resultados de búsqueda:

![Diagrama de flujo de solicitudes directas a google.com/search, en pruebas. Un cliente HTTP sin JavaScript termina en HTTP 200 con 0 resultados, etiquetado como fallo silencioso. Un navegador real que ejecuta JavaScript, probado después de 10 de esas solicitudes, termina en una página CAPTCHA /sorry/ con la conexión bloqueada.](https://media.brightdata.com/2026/10/Bkz9XILsMe.png)Los clientes HTTP fallan de la manera más difícil de detectar. Las 10 solicitudes provinieron de 5 configuraciones comunes de clientes HTTP, incluyendo `curl` y Python `httpx`. Las 10 obtuvieron el estado 200 y ningún resultado, por lo que un scraper que solo comprueba los códigos de estado registra un éxito y no almacena nada. La página contenía solo un script que tiene que ejecutarse en un motor de JavaScript antes de que aparezca algún resultado.

Comprueba cada respuesta en busca de resultados, no solo el código de estado.

Todos los navegadores probados, incluyendo Chromium y Chrome sin interfaz gráfica, ejecutaron el JavaScript pero recibieron la página CAPTCHA `/sorry/` de Google en su primera consulta. Se ejecutaron después de esas 10 solicitudes HTTP, y el bloqueo se aplicó a toda la conexión durante 40 minutos o más.

Con un volumen de producción, tendrías que ejecutar el JavaScript de Google en cada búsqueda y mantener analizadores para un markup cambiante. La API SERP de Bright Data gestiona los navegadores y analizadores por ti y devuelve resultados ya procesados.

## Cómo migrar el código de Custom Search JSON API a la API SERP de Bright Data

Envías una URL de búsqueda normal de Google, y la respuesta es esa página como JSON. Los pasos 1 a 3 son la migración principal.

### Paso 1: Configura y envía una primera solicitud

Necesitas una [cuenta gratuita de Bright Data](/cp/start), una clave API y una zona de API SERP. Una zona es un conjunto nombrado de configuraciones que usan tus solicitudes. Si tu equipo de seguridad revisa primero a los nuevos proveedores, envíale el enlace del [Trust Center de Bright Data](/trustcenter). Esa página enumera informes SOC 2 y SOC 3, certificados ISO 27701 y documentación de cumplimiento GDPR.

En el panel de control, una zona se llama API. Abre **Web Access**, selecciona **Create API**, elige **SERP API**, y selecciona **Continue**:

![Panel de control de Bright Data, página de Web Access, Add API. La opción SERP API está destacada entre Browser API, Web Unlocker API, y SERP API, sobre el botón Continue.](https://media.brightdata.com/2026/10/H1dsm8Ljfx.png)Dale un nombre a la API, asegúrate de que el formato de datos sea **Raw HTML**, y selecciona **Add API**. El JSON proviene de un parámetro en cada solicitud, no de este ajuste. El nombre de API que elegiste es el nombre de tu zona, que configuras en `BRIGHTDATA_SERP_ZONE` más abajo:

![Panel de control de Bright Data, paso de Configure API para una SERP API. El campo Name y el botón Add API están destacados, y una nota bajo el campo dice que el nombre no se puede cambiar después.](https://media.brightdata.com/2026/10/B1haX8LiGe.png)La clave API está en la barra de **Quick start** en la parte inferior de la página **Home**:

![Página Home del panel de control de Bright Data. El campo de clave API en la barra Quick start de abajo está destacado. La clave y la URL del servidor MCP están ocultas en esta imagen.](https://media.brightdata.com/2026/10/SyAAXULifg.png)Crea un entorno virtual, configura la clave y el nombre de la zona, e instala la única dependencia de Python. Reemplaza ambos valores con tu propia clave y nombre de zona:

```none
python3 -m venv .venv && source .venv/bin/activate
export BRIGHTDATA_API_KEY="your-api-key"
export BRIGHTDATA_SERP_ZONE="serp_api1"
python -m pip install "httpx>=0.27,<1"
```

En Windows PowerShell, usa este bloque en su lugar:

```none
python -m venv .venv; .venv\Scripts\Activate.ps1
$env:BRIGHTDATA_API_KEY = "your-api-key"
$env:BRIGHTDATA_SERP_ZONE = "serp_api1"
python -m pip install "httpx>=0.27,<1"
```

Con uv, omite el entorno virtual e inicia cada script con `uv run --with "httpx>=0.27,<1" python`, seguido del nombre del script.

Un único POST al endpoint `/request` de Bright Data obtiene una URL de Google a través de tu zona y devuelve una página de resultados. Este comando curl envía esa solicitud e imprime la respuesta con formato legible:

```none
curl https://api.brightdata.com/request \
  -H "Authorization: Bearer $BRIGHTDATA_API_KEY" \
  -H "Content-Type: application/json" \
  --data @- <<EOF | python -m json.tool
{
  "zone": "$BRIGHTDATA_SERP_ZONE",
  "url": "https://www.google.com/search?q=is+there+a+google+search+api&gl=us&hl=en&brd_json=1",
  "format": "raw"
}
EOF
```

El parámetro `brd_json=1` convierte la página en JSON ya procesado, y `"format": "raw"` devuelve ese JSON sin cambios. La respuesta a continuación está acortada:

```none
{
  "general": {
    "search_engine": "google",
    "query": "is there a google search api",
    "language": "en",
    "country_code": "US"
  },
  "organic": [
    {
      "link": "https://developers.google.com/custom-search/v1/overview",
      "title": "Custom Search JSON API | Google for Developers",
      "description": "The Custom Search JSON API lets you develop websites and applications to retrieve and display search results from Programmable Search Engine ...",
      "rank": 1
    }
  ],
  "pagination": {
    "current_page": 1,
    "next_page": 2,
    "next_page_start": 10
  }
}
```

Esa misma respuesta también contenía 8 búsquedas relacionadas y 4 preguntas de People Also Ask. La respuesta de Custom Search no tiene campos para ninguna de las dos cosas.

### Paso 2: Mapea los parámetros de Custom Search a los parámetros de Google

La [referencia de parámetros de consulta de Google](https://docs.brightdata.com/products/serp-api/query-parameters/google) de Bright Data y su lista de [parámetros y operadores de URL de búsqueda de Google](/blog/web-data/google-search-url-parameters) explican en detalle los parámetros de Google. Los campos de respuesta están en `items[]` en Custom Search y en `organic[]` en la respuesta de la API SERP:

Custom Search JSON APIGoogle, a través de la API SERP`q``q``num` (máximo 10)Eliminado por Google. El adaptador solicita más páginas`start` (cuenta desde 1)`start` (cuenta desde 0, en pasos de 10)`gl` (favorece resultados de un país)`gl` (ejecuta la búsqueda como un usuario de ese país)`hl` (idioma de la interfaz)`hl``siteSearch=a.com``site:a.com` añadido a `q``siteSearchFilter=e``-site:a.com` añadido a `q``exactTerms=a b``"a b"` añadido a `q``excludeTerms=a``-"a"` añadido a `q``fileType=pdf``filetype:pdf` añadido a `q``dateRestrict=d7``tbs=qdr:d7`, y lo mismo para `w`, `m`, y `y``safe=active``safe=active``searchType=image``udm=2` (Google Images)`title`, `link``title`, `link``snippet``description``displayLink`Nombre de host de `link``queries.nextPage`Calculado por el adaptadorEn Google, 3 parámetros funcionan de forma distinta:

**Google cuenta los desplazamientos desde 0.** Custom Search trata `start=11` como la parte superior de la página 2, y Google trata `start=10` como la página 2. Envía `start` en pasos de 10 y descarta en el código los resultados anteriores a tu posición inicial, tal como hace el adaptador.

**Google eliminó `num`.** La documentación de la API SERP indica que Google desaprobó `num` el 11 de septiembre de 2025. Cada página de Google contiene alrededor de 10 resultados, y el adaptador solicita tantas páginas como necesite `num`. Para más resultados por consulta, Bright Data puede devolver los [100 mejores resultados de Google](https://docs.brightdata.com/products/serp-api/get-top-100-google-results), posiciones 1 a 100, en una sola llamada.

**En Google, `gl` establece el país de búsqueda.** La consulta “cloud hosting pricing” devolvió los mejores resultados del Reino Unido, Alemania e India sin compartir ninguna URL con los mejores resultados de EE. UU. Configura `gl` en cada solicitud según el país desde el que buscan tus usuarios.

### Paso 3: Añade un adaptador listo para usar para cse.list()

El adaptador envía las llamadas `cse.list()` a la API SERP de Bright Data y funciona en Python 3.9 y versiones posteriores. Acepta los parámetros de Custom Search de la tabla y mantiene los campos `title`, `link`, `snippet` y `displayLink` en `items`. Ignora `cx` con una advertencia, porque la búsqueda de Google no tiene ID de motor, y añade ajustes de `attempts` y `timeout`.

En cada punto de llamada, el cambio se ve así:

```none
# Antes, con el cliente de la API de Google
res = service.cse().list(q=query, cx=CX, num=10).execute()

# Después, con los mismos campos principales de items, sin ID de motor, y con gl y hl configurados
from cse_to_serp import cse_list

res = cse_list(q=query, num=10, gl="us", hl="en")
```

Comprueba 3 cosas más en cada punto de llamada:

- Si tu motor buscaba en una lista fija de sitios, inclúyelos en la consulta como `(site:a.com OR site:b.com)`. Una consulta restringida a 2 sitios de documentación de esta forma devolvió 10 resultados, todos de esos 2 hosts.
- En un controlador de solicitudes web, pasa `attempts=1` y un `timeout` que se ajuste al presupuesto de tiempo del controlador.
- Donde capturabas `HttpError`, captura en su lugar `(httpx.HTTPError, ValueError, RuntimeError)`.

Guarda el adaptador como `cse_to_serp.py`, o clona el [repositorio complementario en GitHub](https://github.com/triposat/google-custom-search-api-alternative), que también contiene los otros scripts a continuación y pruebas sin conexión. Aquí está el archivo completo:

```none
"""Replace Google Custom Search JSON API calls with the Bright Data SERP API.

Same cse.list() parameters and core items fields.
"""

import math
import os
import time
import warnings
from urllib.parse import urlencode, urlparse

import httpx

API_URL = "https://api.brightdata.com/request"
API_KEY = os.environ.get("BRIGHTDATA_API_KEY")
if not API_KEY:
    raise RuntimeError("Set the BRIGHTDATA_API_KEY environment variable "
                       "to your Bright Data API key (step 1).")
ZONE = os.environ.get("BRIGHTDATA_SERP_ZONE", "serp_api1")
RETRY_STATUSES = {429, 500, 502, 503, 504}

def fetch_serp(params: dict, attempts: int = 4, timeout: float = 60) -> dict:
    """Fetch one Google results page as parsed JSON."""
    url = "https://www.google.com/search?" + urlencode(params)
    body = {"zone": ZONE, "url": url, "format": "raw"}
    headers = {"Authorization": f"Bearer {API_KEY}"}
    for attempt in range(attempts):
        try:
            resp = httpx.post(API_URL, json=body, headers=headers,
                              timeout=timeout)
        except httpx.TransportError:  # timeout or dropped connection
            if attempt == attempts - 1:
                raise
            time.sleep(16 + attempt * 10)
            continue
        error = (resp.headers.get("x-brd-error")  # API-level errors
                 or resp.headers.get("x-brd-err-msg"))  # proxy-level errors
        if resp.status_code == 200 and not error:
            page = resp.json()
            if "general" not in page:  # not a parsed results page
                raise ValueError("Unexpected response: " + resp.text[:200])
            return page
        if not error and resp.status_code not in RETRY_STATUSES:
            break  # wrong key, zone, or URL, so retrying will not help
        if attempt < attempts - 1:
            # Back off before resending the same query.
            time.sleep(16 + attempt * 10)
    resp.raise_for_status()
    code = (resp.headers.get("x-brd-error-code")  # maps to the error catalog
            or resp.headers.get("x-brd-err-code"))
    raise RuntimeError(f"SERP API error {code}: {error or resp.status_code}")

def cse_list(q, num=10, start=1, gl=None, hl=None, siteSearch=None,
             siteSearchFilter="i", exactTerms=None, excludeTerms=None,
             fileType=None, dateRestrict=None, safe="off", searchType=None,
             attempts=4, timeout=60, **extra):
    """Accept cse.list() parameters, return a dict in cse.list() format."""
    if extra.pop("cx", None):  # no engine ID, so every call searches Google
        warnings.warn("cx is ignored. Add (site:a.com OR site:b.com) to q "
                      "if your engine searched a fixed list of sites")
    if extra:  # fail loudly instead of ignoring a filter
        raise TypeError(f"No mapping for: {sorted(extra)}")
    if exactTerms:  # Custom Search filters become Google search operators
        q = f'{q} "{exactTerms}"'
    if excludeTerms:
        q = f'{q} -"{excludeTerms}"'
    if fileType:
        q = f"{q} filetype:{fileType}"
    if siteSearch:
        exclude = "-" if siteSearchFilter == "e" else ""
        q = f"{q} {exclude}site:{siteSearch}"
    params = {"q": q, "brd_json": 1}  # brd_json=1 returns parsed JSON
    if gl:
        params["gl"] = gl
    if hl:
        params["hl"] = hl
    if safe == "active":
        params["safe"] = "active"
    if dateRestrict:  # "d7" -> qdr:d7 (past 7 days), "m6" -> qdr:m6
        params["tbs"] = "qdr:" + dateRestrict
    if searchType == "image":
        return image_list(params, num, start, attempts, timeout)
    if searchType:
        raise ValueError(f"No mapping for: searchType={searchType}")

    # Custom Search counts from 1 (start=11 is page 2), Google from 0
    # (start=10 is page 2). Track each result's Google position.
    first = start - 1
    offset = first // 10 * 10  # the Google page that contains `start`
    items, next_start = [], None
    # Fetch the pages for positions first to first + num - 1, 1 request each
    for _ in range(math.ceil((num + first - offset) / 10)):
        params["start"] = offset
        page = fetch_serp(params, attempts, timeout)
        for i, result in enumerate(page.get("organic", [])):
            position = offset + i
            if position < first or not result.get("link"):
                continue
            if len(items) == num:
                next_start = position + 1  # convert to 1-based
                break
            items.append({
                "title": result.get("title", ""),
                "link": result["link"],
                "snippet": result.get("description", ""),
                "displayLink": urlparse(result["link"]).netloc,
            })
        if next_start:
            break
        offset = (page.get("pagination") or {}).get("next_page_start")
        if not offset:  # Google has no further pages for this query
            break
    else:
        next_start = offset + 1  # continue at the next Google page

    response = {"items": items, "queries": {}}
    if next_start:
        response["queries"]["nextPage"] = [{"startIndex": next_start}]
    return response

def image_list(params, num, start, attempts, timeout):
    """Google Images returns the whole image grid in one request."""
    params["udm"] = 2
    page = fetch_serp(params, attempts, timeout)
    images = [i for i in page.get("images") or [] if i.get("original_image")]
    items = [{
        "title": image.get("image_alt", ""),
        "link": image["original_image"],
        "snippet": image.get("image_alt", ""),
        "displayLink": urlparse(image["original_image"]).netloc,
    } for image in images[start - 1:start - 1 + num]]
    response = {"items": items, "queries": {}}
    if start - 1 + num < len(images):
        response["queries"]["nextPage"] = [{"startIndex": start + num}]
    return response

if __name__ == "__main__":
    res = cse_list("httpx timeout configuration", num=10,
                   gl="us", hl="en")
    for i, item in enumerate(res["items"], start=1):
        print(i, item["displayLink"], "|", item["title"][:60])
```

Al ejecutar `python cse_to_serp.py` se imprimieron estos como sus primeros 5 resultados. Los resultados provienen de la página en vivo de Google, así que los tuyos pueden variar.

```none
1 www.python-httpx.org | Timeouts
2 github.com | Proposal: Add a Global Timeout Setting in httpx #3356
3 www.python-httpx.org | QuickStart
4 stackoverflow.com | python - Httpx requests timing out when it shouldn't
5 oneuptime.com | How to Use httpx for Async HTTP Requests
```

Con `num=10`, cada llamada a `nextPage` obtiene una sola página de Google, por lo que cuesta 1 solicitud.

Con `searchType="image"`, 1 solicitud para “ergonomic office chair” devolvió 100 imágenes, mientras que Custom Search devolvía como máximo 10 por solicitud. Cada llamada del adaptador obtiene la cuadrícula completa de imágenes y devuelve `num` imágenes de ella.

### Reemplaza la herramienta de búsqueda en agentes MCP, LangChain y n8n

Los agentes que se conectan a herramientas a través de MCP no necesitan adaptador. El servidor [Bright Data Web MCP](/ai/mcp-server/google) expone la búsqueda de Google como su herramienta `search_engine`, y el servidor alojado es una sola URL con un [nivel gratuito](/blog/ai/web-mcp-free-tier). En Claude Code, lo añades con un solo comando:

```none
claude mcp add --transport http brightdata https://mcp.brightdata.com/mcp
```

Los clientes MCP que admiten OAuth, como Claude Code y Cursor, inician sesión a través de tu navegador, sin ninguna clave API en un archivo de configuración. Para trabajos de CI y scripts, usa en su lugar `https://mcp.brightdata.com/mcp?token=YOUR_API_KEY`. Añade `&tools=search_engine,scrape_as_markdown` a esa URL para darle al agente búsqueda más una herramienta que lee cada página de resultados como Markdown.

Los agentes de codificación también pueden usar la CLI de Bright Data. Instálala con `npm install -g @brightdata/cli`, luego ejecuta `brightdata login` para iniciar sesión a través de tu navegador. El agente obtiene un comando `brightdata search`.

Para código que ya llama a LangChain, el método `GoogleSearchAPIWrapper.results()` devuelve diccionarios con `title`, `link` y `snippet`. Los items del adaptador tienen las mismas claves. Instala el paquete core de LangChain, que necesita Python 3.10 o posterior, con `python -m pip install "langchain-core>=1.0,<2"`. Guarda este archivo como `langchain_tool.py` junto al [adaptador `cse_to_serp.py`](https://github.com/triposat/google-custom-search-api-alternative/blob/main/cse_to_serp.py), y pasa `google_search` en la lista de herramientas de tu agente.

```none
"""LangChain tool that replaces GoogleSearchAPIWrapper.results()."""

from langchain_core.tools import ToolException, tool

from cse_to_serp import cse_list

@tool
def google_search(query: str) -> list[dict]:
    """Search Google and return the top results with title, link, snippet."""
    try:  # 2 attempts and a 20 s timeout limit each search
        return cse_list(q=query, num=10, gl="us", hl="en",
                        attempts=2, timeout=20)["items"]
    except Exception as exc:
        raise ToolException(f"Google search failed: {exc}") from exc

google_search.handle_tool_error = True  # the agent gets the error as text
```

Para ver un agente completo construido de esta forma, consulta [Usar LangChain y Bright Data para la búsqueda web](/blog/ai/langchain-serp-scraping).

Los flujos de trabajo sin código que llaman a Custom Search reciben el mismo 403, y el foro de la comunidad de n8n tiene un hilo sobre ese error exacto. El [nodo oficial de n8n](https://github.com/brightdata/n8n-nodes-brightdata) de Bright Data se instala como el nodo comunitario `@brightdata/n8n-nodes-brightdata`. Tiene una operación Web Search que envía la consulta a Google a través de la zona que selecciones, como tu zona de API SERP. Reemplaza la solicitud de Custom Search del flujo de trabajo con esa operación.

### Ejecuta búsquedas a volumen de producción

Los trabajos por lotes, y los agentes que envían muchas búsquedas en una sola tarea, necesitan ejecutar varias consultas al mismo tiempo. El [módulo `serp_batch.py`](https://github.com/triposat/google-custom-search-api-alternative/blob/main/serp_batch.py) del repositorio complementario ejecuta en paralelo una versión asíncrona del bucle de solicitud y reintento del adaptador. Por separado, la propia API SERP ofrece un modo asíncrono para lotes de 1K consultas o más.

El bloque principal del archivo envía las mismas 10 consultas dos veces, y la segunda ejecución se sirve desde su caché en memoria.

```none
{'queries': 20, 'cache_hits': 10, 'empty': 0, 'failed': 0}
```

Su función `search_many()` tiene 3 ajustes y un conjunto de contadores.

- **`concurrency`** establece cuántas solicitudes se ejecutan a la vez. La API SERP no tiene límite de concurrencia, así que configúralo según la carga que tu propio sistema pueda manejar.
- **`deadline`** limita el tiempo total para una consulta, así que mantenlo corto para una herramienta de agente y más largo para un trabajo por lotes.
- **`ttl`** establece cuánto tiempo permanece válida una página en caché.
- **Los contadores** muestran aciertos de caché, resultados vacíos y fallos, así que un filtro `site:` o un valor `gl` incorrecto aparece temprano como resultados vacíos.

Una llamada devuelve un diccionario que asigna cada consulta a su página ya procesada, o a `None` si la consulta falló.

```none
import asyncio

from serp_batch import search_many

pages = asyncio.run(search_many(["redis cache ttl", "nginx rate limiting"],
                                concurrency=20, gl="us", hl="en"))
```

### Obtén el AI Overview y las preguntas de People Also Ask

Los agentes, las canalizaciones RAG, y los equipos de SEO pueden necesitar más que una lista de 10 enlaces. La página de Google para “what is retrieval augmented generation” muestra un AI Overview y preguntas de People Also Ask, que Custom Search nunca devolvía.

![Página de resultados de Google para "what is retrieval augmented generation", con el AI Overview y 3 preguntas de People Also Ask destacadas.](https://media.brightdata.com/2026/10/S1QlNLUsGe.png)Un parámetro extra solicita el AI Overview, y la misma respuesta contiene cualquier pregunta de People Also Ask. Guarda este script junto al adaptador `cse_to_serp.py` del paso 3.

```none
"""Read the AI Overview and People Also Ask questions from one Google query."""

from cse_to_serp import fetch_serp

page = fetch_serp({
    "q": "what is retrieval augmented generation",
    "gl": "us",
    "hl": "en",
    "brd_json": 1,
    "brd_ai_overview": 2,  # requests the AI Overview
})

overview = page.get("ai_overview") or {}
print("AI Overview text blocks:", len(overview.get("texts", [])))
print("AI Overview sources:", len(overview.get("references", [])))
questions = dict.fromkeys(  # keeps each question once, in order
    item["question"] for item in page.get("people_also_ask", [])
    if item.get("question")
)
for question in list(questions)[:2]:
    print("People also ask:", question)
```

El script imprimió esta salida. La página de Google está en vivo, así que tus preguntas pueden diferir de la captura de pantalla.

```none
AI Overview text blocks: 3
AI Overview sources: 8
People also ask: Does ChatGPT use Retrieval-Augmented Generation?
People also ask: What is RAG in LLM with example?
```

Cada entrada de `references` contiene el `href` y el `title` de la página citada, así que los equipos de SEO pueden rastrear qué sitios cita el AI Overview. La página [Google AI Overview API](/products/serp-api/google-search/ai-overview) de Bright Data explica el parámetro en detalle. Para Google AI Mode, la [Google Scraper API](https://docs.brightdata.com/products/scrapers/google/introduction) devuelve los resultados de AI Mode Search como JSON.

Una canalización RAG que lee las páginas de resultados puede obtenerlas a través del mismo endpoint `/request`. Usa una zona de [Web Unlocker](/products/web-unlocker) y la misma clave API.

## Lista de verificación de migración antes del 1 de enero de 2027

Ejecuta estos pasos mientras tu clave de Custom Search todavía funcione, porque el punto 2 la necesita.

1. Encuentra todos los puntos de llamada. Busca en tu código `customsearch/v1`, `cse().list`, y envoltorios como `GoogleSearchAPIWrapper`. En una base de código grande, un agente de codificación puede ejecutar esa búsqueda y hacer el cambio del paso 3 en cada punto de llamada.
2. Guarda los resultados de Custom Search para una muestra de consultas reales de producción, para así mantener una línea base después de que la clave deje de funcionar. Si la clave ya ha dejado de funcionar, guarda en su lugar resultados de google.com para los mismos `gl` y `hl`.
3. Empieza con el nivel gratuito, luego presupuesta 1 solicitud de API SERP por página de resultados.
4. Deja que el adaptador convierta los valores de `start` basados en 1 a los valores basados en 0 de Google, o conviértelos tú mismo y solicita páginas completas.
5. Configura `gl` y `hl` en cada solicitud.
6. Compara los resultados antiguos y nuevos como conjuntos de URLs, no por posición exacta. Para los agentes, vuelve a ejecutar también tus evaluaciones de tareas y puntúa las respuestas finales. Espera algunas diferencias, porque los nuevos resultados provienen de la página completa de resultados de Google, no del subconjunto del índice de Custom Search.
7. Cambia detrás de un feature flag, ejecuta ambas rutas en paralelo durante unos días, luego elimina la clave de Google.

Para el punto 6, el [ayudante `compare_baseline.py`](https://github.com/triposat/google-custom-search-api-alternative/blob/main/compare_baseline.py) puntúa cada consulta de 0 a 1. La puntuación es la proporción de las 10 URLs principales guardadas que todavía aparecen en las nuevas 10 principales.

Primero, ejecuta cada consulta dos veces a través de la API SERP y puntúa las 2 ejecuciones entre sí. El ranking de Google puede cambiar entre llamadas, así que una puntuación justo por debajo de 1.0 puede ser normal. En las pruebas, 2 ejecuciones de una consulta con el mismo `gl` puntuaron 1.0, y una ejecución de EE. UU. frente a una del Reino Unido puntuó 0.0. Luego puntúa todas las consultas guardadas, revisa a mano las puntuaciones más bajas, y comprueba los filtros `gl` y `site:` para cualquier puntuación cercana a 0.

## Soluciona errores de migración

Estos son problemas de configuración de la primera ejecución o comportamiento de Google.

SíntomaCausaSoluciónGoogle devuelve 403 en las llamadas a Custom SearchAPI cerrada a nuevos clientesUna clave nueva no ayudará. Migra a la API SERP de Bright Data`RuntimeError: Set the BRIGHTDATA_API_KEY environment variable…`Variable no configurada en esta terminalConfigura `BRIGHTDATA_API_KEY` como en el paso 1401 “Invalid token”Clave API de Bright Data incorrectaCopia la clave desde la barra Quick start en Home400 `zone "..." not found`Nombre de zona incorrectoUsa el nombre que le diste a la API en el paso 1`UserWarning: cx is ignored…`La búsqueda de Google no tiene ID de motorElimina `cx`. Si el motor buscaba en una lista fija de sitios, añade `(site:a.com OR site:b.com)` a `q``TypeError: No mapping for: [...]`Un parámetro que no está en la tabla del paso 2Añade el equivalente de Google a `q` o a los `params` del adaptador, o elimina el parámetro`KeyError` en `pagemap` o `searchInformation`El adaptador devuelve 4 campos principalesElimina el código que lee el campo, o mapéalo desde la respuesta de la API SERP`items` tiene menos de `num` resultadosLa página de Google contenía menos resultados orgánicosSigue `queries.nextPage``items` está vacíoSin coincidencia, o un valor incorrecto de filtro `site:` o `gl`Prueba la consulta en google.comLos resultados difieren de Custom SearchCustom Search buscaba en un subconjunto del índice de GoogleCompara conjuntos de URLs. Ejecuta cada consulta dos veces primero para ver la variación normalUn mensaje `RuntimeError: SERP API error…` incluye el valor `x-brd-error-code` o `x-brd-err-code`. Busca el código en el [catálogo de errores de la API SERP](https://docs.brightdata.com/products/serp-api/debugging).

## Reflexiones finales

El producto de búsqueda de toda la web de Google no es público, y la fecha de finalización de Custom Search JSON API es el 1 de enero de 2027. Las opciones públicas de Google buscan en una lista fija de dominios o devuelven respuestas de Gemini, y los términos de Gemini prohíben almacenar en caché o analizar los resultados. Las solicitudes HTTP directas no obtuvieron resultados en las pruebas, así que la API SERP de Bright Data es el reemplazo práctico cuando tu código necesita la página de resultados.

El adaptador del paso 3 gestiona el `start` basado en 0 de Google y el `num` eliminado, así que tu código principalmente necesita `gl` en cada llamada. Ejecuta tus consultas guardadas a través del nivel gratuito de la [API SERP de Bright Data](/products/serp-api/google-search), sin tarjeta de crédito, y compáralas con tu línea base de Custom Search o con google.com.

## Preguntas frecuentes

### ¿Está descontinuada la Google Custom Search API?

Sí, en 2 etapas. Google cerró Custom Search JSON API a nuevos clientes en enero de 2026, y el acceso de los clientes existentes terminará el 1 de enero de 2027. Google sugiere Agent Search para hasta 50 dominios. La API SERP de Bright Data devuelve resultados de Google de toda la web como JSON.

### ¿Tiene Google una API de búsqueda?

No una API de búsqueda de toda la web a la que los nuevos desarrolladores puedan suscribirse. Google ofrece Agent Search para hasta 50 dominios y Grounding con Google Search, que devuelve respuestas de Gemini con enlaces. El producto de búsqueda de toda la web de Google no es público. Para resultados de Google como JSON, usa la Google Search API de Bright Data, parte de su API SERP.

### ¿Es gratuita la API de búsqueda de Google?

No para los nuevos desarrolladores que necesitan resultados de toda la web. Custom Search JSON API da a los clientes existentes 100 consultas gratuitas al día, y luego cobra $5 por cada 1,000, hasta el 1 de enero de 2027. La API SERP de Bright Data devuelve resultados de Google como JSON, con 5K solicitudes gratuitas al mes.

### ¿Qué puede reemplazar a la Google Custom Search API?

La API SERP de Bright Data reemplaza directamente a Custom Search JSON API, porque devuelve la página completa de resultados de Google como JSON. Las propias opciones de Google devuelven respuestas de IA o buscan en una lista fija de dominios. Un adaptador de Python de código abierto y listo para usar convierte tus llamadas `cse.list()` en parámetros de Google.

### ¿Cómo puedo hacer scraping de los resultados de búsqueda de Google?

No solo con un cliente HTTP. Google Search requiere JavaScript, así que en las pruebas, los clientes HTTP obtuvieron una página 200 sin resultados. Luego, los navegadores en la misma conexión recibieron una página CAPTCHA. La API SERP de Bright Data devuelve la página de resultados de Google como JSON ya procesado, sin navegadores ni analizadores que tengas que mantener.

### ¿Por qué la Custom Search API devuelve 403?

Google cerró Custom Search JSON API a nuevos clientes en enero de 2026, así que una clave o proyecto nuevo no solucionará el error 403. En el foro de desarrolladores de Google, un desarrollador también reporta que un proyecto existente perdió el acceso tras un cambio de facturación. Mueve las llamadas a la API SERP de Bright Data, que devuelve resultados de Google como JSON.



Contactar ventasPrueba gratuita![google social icon](/wp-content/themes/brightdata/assets/images/ic_google.svg)









 Tabla de Contenidos













 [ ](https://news.ycombinator.com/submitlink?t=%C2%BFExiste+una+API+de+b%C3%BAsqueda+de+Google%3F+Opciones+tras+Custom+Search&u=https://brightdata.es/blog/datos-web/google-search-api) [ ](https://www.linkedin.com/shareArticle?mini=true&title=%C2%BFExiste+una+API+de+b%C3%BAsqueda+de+Google%3F+Opciones+tras+Custom+Search&url=https://brightdata.es/blog/datos-web/google-search-api) [ ](http://www.reddit.com/submit?title=%C2%BFExiste+una+API+de+b%C3%BAsqueda+de+Google%3F+Opciones+tras+Custom+Search&url=https://brightdata.es/blog/datos-web/google-search-api)







##  Usted también puede estar interesado en

 [ ![Amazon Bedrock Knowledge Bases with Bright Data](https://media.brightdata.es/2026/08/Amazon-Bedrock-Knowledge-Bases-with-Bright-Data.png) ](https://brightdata.es/blog/procedimientos/amazon-bedrock-knowledge-bases-with-bright-data "Cómo alimentar Amazon Bedrock Knowledge Bases con datos web en vivo usando Bright Data")

 [Procedimientos



 ![Satyam Tripathi](https://media.brightdata.es/2024/09/Satyam-Tripathi-50x50.png)

Satyam Tripathi

Technical Writer





### Cómo alimentar Amazon Bedrock Knowledge Bases con datos web en vivo usando Bright Data

Bright Data permite que Amazon Bedrock Knowledge Bases acceda a datos web bloqueados por renderizado JavaScript, protección antibots, o restricciones geográficas.



 15-Oct-2026

 55 min de lectura

 ](https://brightdata.es/blog/procedimientos/amazon-bedrock-knowledge-bases-with-bright-data)

 [ ![MiniMax M3 with Bright Data](https://media.brightdata.es/2026/09/MiniMax-M3-with-Bright-Data.png) ](https://brightdata.es/blog/ai/minimax-m3-with-bright-data "Dar a los agentes MiniMax M3 autoalojados acceso web en vivo con Bright Data")

 [AI



 ![Satyam Tripathi](https://media.brightdata.es/2024/09/Satyam-Tripathi-50x50.png)

Satyam Tripathi

Technical Writer





### Dar a los agentes MiniMax M3 autoalojados acceso web en vivo con Bright Data

Los agentes MiniMax M3 autoalojados obtienen acceso web en vivo usando las herramientas de búsqueda y scraping de Bright Data. Evita bloqueos y CAPTCHAs.



 15-Oct-2026

 68 min de lectura

 ](https://brightdata.es/blog/ai/minimax-m3-with-bright-data)

 [ ![Agentic Registration](https://media.brightdata.es/2026/09/Agentic-Registration.png) ](https://brightdata.es/blog/ai/agentic-registration "Registro Agéntico: Cómo un Agente de IA se Registra en Bright Data Con auth.md")

 [AI



 ![Daniel Shashko](https://media.brightdata.es/2022/04/Daniel-Shashko-2-50x50.png)

Daniel Shashko

Web Data &amp; AI Expert





### Registro Agéntico: Cómo un Agente de IA se Registra en Bright Data Con auth.md

Cómo un agente de IA se registra en Bright Data vía auth.md y obtiene un token de API funcional, con un humano solo confirmando un código de correo.



 15-Oct-2026

 17 min de lectura

 ](https://brightdata.es/blog/ai/agentic-registration)
