Grounding with your search API

This guide shows you how to connect Gemini to your external data sources by grounding with your search API.

This page covers the following topics:

The following diagram summarizes the workflow for setting up a new search API endpoint:

How grounding with your search API works

When you ground with your search API, Gemini can query an external API endpoint that you provide. This allows Gemini to use your custom search functionality as a tool to enhance its responses. It enables more dynamic and context-aware interactions, as the model can seek out information from your specified data sources when needed.

During a generation request, Gemini can call the external API endpoint with a search query. Your API should then return relevant data snippets. Gemini uses these snippets as a source of truth to generate a more accurate and grounded response.

You can combine grounding using your search API with other grounding sources like Google Search. A generation request supports up to 10 grounding sources and multi-tool queries where Gemini can use different information sources to generate a more comprehensive answer.

Supported models

The following models support grounding with your API:

For more information, see Gemini models.

Before you begin

To use grounding with your search API, do the following:

  1. Enable the Vertex AI API in your Google Cloud project.
  2. If you plan to follow the detailed setup guide for creating a new search API endpoint, make sure you have the Google Cloud CLI installed and initialized.

Search API requirements

To use your existing search infrastructure with Gemini, your API endpoint must meet the following requirements:

API schema

  • HTTP method: POST
  • Request Body (from Gemini to your API):

    {
      "query": "the user's search query string"
    }
    
  • Response body (from your API to Gemini): A JSON array of objects. Each object represents a search result and must contain snippet and uri fields.

    [
      {
        "snippet": "A text snippet containing the answer or relevant information.",
        "uri": "A URI/URL linking to the source of the information, or a relevant identifier."
      },
      {
        "snippet": "Another piece of information.",
        "uri": "https://example.com/another-source"
      }
    ]
    

    If no results are found, your API endpoint should return an empty array.

Authentication

Grounding with your search API supports the use of an API key to secure your endpoint. Gemini sends this API key as a query parameter named key.

Choose your grounding method

Before you begin, decide whether to use an existing API endpoint or set up a new one. The following table compares these two approaches.

Option Description Pros Cons Use Case
Use a compatible endpoint Directly use an existing API that meets the required schema and authentication method. Faster setup; leverages existing infrastructure. Requires your API to conform to a specific schema. You already have a search service with a compatible API.
Set up a new endpoint Create a new API endpoint using services like Cloud Functions and API Gateway to act as a wrapper for your data source. Highly flexible; can adapt any data source to meet the requirements. More complex setup involving multiple Google Cloud services. Your data source doesn't have a compatible API, or you need to build a new search interface from scratch.

Use a compatible endpoint

If you already have an API endpoint that meets the schema and authentication requirements, you can directly configure it in your Gemini API calls.

Configure the externalApi tool

When making a request to the Gemini API, include the tools parameter with a retrieval tool configured for the externalApi. The configuration includes the following key fields:

  • api_spec: "SIMPLE_SEARCH": This tells Gemini to use the predefined input and output schema.
  • endpoint: The full URL to your API Gateway endpoint, such as https://YOUR_GATEWAY_HOSTNAME/v0/search.
  • apiAuth.apiKeyConfig.apiKeyString: The API key that Gemini uses to authenticate with your API. Gemini appends this key as ?key=<YOUR_API_KEY> to the endpoint URL.

Before using any of the request data, make the following replacements:

  • LOCATION: The region to process the request, such as us-central1.
  • PROJECT_ID: Your Google Cloud project ID.
  • MODEL_ID: The model ID of a compatible Gemini model, such as gemini-2.0-flash-001.
  • USER_PROMPT: The text instructions to include in the prompt.
  • EXTERNAL_API_ENDPOINT: The full URL to your secured API Gateway endpoint that Gemini calls, such as https://YOUR_GATEWAY_HOSTNAME/v0/search. This endpoint must adhere to the specified API schema.
  • EXTERNAL_API_KEY: The API key you generated and configured for your API Gateway. Gemini uses this key to authenticate with your endpoint.

To ground your model, send a POST request to the generateContent method.

REST

HTTP method and URL:

POST https://LOCATION-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/publishers/google/models/MODEL_ID:generateContent

Request JSON body:

{
  "contents": [{
      "role": "user",
      "parts": [{
          "text": "USER_PROMPT"
      }]
  }],
  "tools": [{
      "retrieval": {
        "externalApi": {
          "api_spec": "SIMPLE_SEARCH",
          "endpoint": "EXTERNAL_API_ENDPOINT",
          "apiAuth": {
            "apiKeyConfig": {
              "apiKeyString": "EXTERNAL_API_KEY"
            }
          }
        }
      }
  }]
}

The response includes grounding metadata with details about the retrieved context:

{
  "candidates": [
    {
      "content": {
        "role": "model",
        "parts": [
          {
            "text": "You can make an appointment on the website https://dmv.gov/"
          }
        ]
      },
      "finishReason": "STOP",
      "safetyRatings": [
        "..."
      ],
      "groundingMetadata": {
        "retrievalQueries": [
          "How to make appointment to renew driving license?"
        ],
        "groundingChunks": [
          {
            "retrievedContext": {
              "uri": "https://...",
              "snippet": "Snippet text about driving license renewal"
            }
          }
        ],
        "groundingSupport": [
          {
            "segment": {
              "startIndex": 25,
              "endIndex": 147
            },
            "segment_text": "ipsum lorem ...",
            "supportChunkIndices": [1, 2],
            "confidenceScore": [0.9541752, 0.97726375]
          },
          {
            "segment": {
              "startIndex": 294,
              "endIndex": 439
            },
            "segment_text": "ipsum lorem ...",
            "supportChunkIndices": [1],
            "confidenceScore": [0.9541752, 0.9325467]
          }
        ]
      }
    }
  ],
  "usageMetadata": {
    "..."
  }
}

curl

The following command assumes that you have logged in to the gcloud CLI with your user account by running gcloud init or gcloud auth login, or by using Cloud Shell, which automatically logs you into the gcloud CLI. You can check the active account by running gcloud auth list.

Save the request body from the REST tab in a file named request.json, and execute the following command:

curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
-d @request.json \
"https://LOCATION-aiplatform.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/publishers/google/models/MODEL_ID:generateContent"

Powershell

The following command assumes that you have logged in to the gcloud CLI with your user account by running gcloud init or gcloud auth login. You can check the active account by running gcloud auth list.

Save the request body from the REST tab in a file named request.json, and execute the following command:

$cred = gcloud auth print-access-token
$headers = @{ "Authorization" = "Bearer $cred" }

Invoke-WebRequest `
  -Method POST `
  -Headers $headers `
  -ContentType: "application/json; charset=utf-8" `
  -InFile request.json `
  -Uri "https://LOCATION-aiplatform.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/publishers/google/models/MODEL_ID:generateContent" | Select-Object -Expand Content

Set up a new search API endpoint

If you don't have a compatible API endpoint, this section guides you through setting one up using Cloud Functions and API Gateway.

Create an external API wrapper with Cloud Functions

A Cloud Function can act as an intermediary that receives queries from Gemini, issues appropriate queries to your existing search infrastructure (such as a database, internal search engine, or vector search), and then formats the results in the schema that Gemini requires.

For more information, see Cloud Functions documentation.

Example Cloud Function setup (Python)

This example uses a hardcoded product list for demonstration. You need to replace the data retrieval logic with calls to your actual search system.

main.py

import functions_framework
import json
from flask import jsonify

@functions_framework.http
def custom_search_wrapper_minimal(request):
    """
    HTTP Cloud Function to provide a minimal, fixed response for Gemini grounding.
    """
    if request.method != 'POST':
        return 'Only POST requests are accepted', 405

    request_json = request.get_json(silent=True)

    if not request_json or 'query' not in request_json:
        return jsonify({"error": "Invalid request. JSON body with 'query' field is required."}), 400

    user_query = request_json['query']
    print(f"Received query: '{user_query}'. Responding with fixed data.")

    # --- FIXED RESPONSE ---
    # This is a hardcoded response. In a real scenario, you would
    # use the 'user_query' to fetch relevant data.
    fixed_results = [
        {
            "snippet": "This is a fixed snippet from your custom Search API. The original query was: " + user_query,
            "uri": "https://example.com/docs/fixed-test-data"
        },
        {
            "snippet": "Another piece of fixed information to demonstrate the list format.",
            "uri": "https://example.com/another-fixed-source"
        }
    ]
    # --- END OF FIXED RESPONSE ---

    return jsonify(fixed_results)

requirements.txt

functions-framework>=3.0.0
Flask>=2.0.0

Deployment

Navigate to the directory containing main.py and requirements.txt and run the following command:

gcloud functions deploy custom_search_wrapper \
  --runtime python311 \
  --trigger-http \
  --entry-point custom_search_wrapper \
  --region YOUR_REGION \
  --allow-unauthenticated \
  --gen2
  • Replace YOUR_REGION with your chosen Google Cloud region, such as us-central1.
  • --allow-unauthenticated is specified because API Gateway handles authentication.

After deployment, note the trigger URL. You use this URL in the next step.

Secure the Cloud Function with an API Gateway and API key

API Gateway provides a secure, managed entry point to your Cloud Functions and enables you to enforce API key authentication. For more information, see the API Gateway documentation.

1. Create an OpenAPI specification

Create a file named openapi-spec.yaml. This file defines how API Gateway exposes your Cloud Functions. It specifies that the gateway expects a POST request to the /v0/search path and requires an API key sent as a query parameter named key.

swagger: '2.0'
info:
  title: Custom Search API for Gemini Grounding
  description: Wraps an internal search function, secured by API Key for Gemini.
  version: 1.0.0
schemes:
  - https
produces:
  - application/json
consumes:
  - application/json
paths:
  /v0/search: # TODO: This will be part of API endpoint URL change if necessary
    post:
      summary: Custom search endpoint for Gemini
      operationId: customSearchForGemini # TODO: Change if needed
      x-google-backend:
        address: YOUR_CLOUD_FUNCTION_TRIGGER_URL # TODO: Replace with your Cloud Function trigger URL
      parameters:
        - name: body
          in: body
          required: true
          schema:
            type: object
            properties:
              query:
                type: string
      security:
        - api_key_query: []
      responses:
        '200':
          description: Search results
          schema:
            type: array
            items:
              type: object
              properties:
                snippet:
                  type: string
                uri:
                  type: string
        '400':
          description: Invalid request
        '401':
          description: Unauthorized (Missing or invalid API key)
        '500':
          description: Internal server error
securityDefinitions:
  api_key_query:
    type: apiKey
    name: key # Gemini will send its API key using this query parameter name
    in: query

Replace YOUR_CLOUD_FUNCTION_TRIGGER_URL with the trigger URL that you noted when deploying your Cloud Functions.

2. Deploy the API Gateway

Execute the following gcloud CLI commands after replacing the variables:

  • YOUR_PROJECT_ID: Your Google Cloud project ID.
  • YOUR_REGION: The Google Cloud region that you used for your Cloud Functions, such as us-central1.
# 1. Create an API
gcloud api-gateway apis create custom-search-gemini-api --project=YOUR_PROJECT_ID

# 2. Create an API Config from your OpenAPI spec
gcloud api-gateway api-configs create v1 \
  --api=custom-search-gemini-api \
  --openapi-spec=openapi-spec.yaml \
  --project=YOUR_PROJECT_ID \
  --display-name="Version 1"

# 3. Create a Gateway
gcloud api-gateway gateways create custom-search-gateway \
  --api=custom-search-gemini-api \
  --api-config=v1 \
  --location=YOUR_REGION \
  --project=YOUR_PROJECT_ID

After deployment, the gateway hostname has the format https://custom-search-gateway-UNIQUE_ID.nw.gateway.dev. Use this hostname to construct the full endpoint URL for Gemini, for example: https://custom-search-gateway-UNIQUE_ID.nw.gateway.dev/v0/search.

3. Create and restrict an API key

You must create an API key that Gemini uses to access your API Gateway endpoint. For more information, see Manage API keys.

  1. In the Google Cloud console, go to the APIs & Services > Credentials page.

    Go to API Gateway API / Enable APIs

  2. Click Create credentials, and select API key.

  3. Copy the generated API key and store it in a secure location. This key is used by Gemini.

  4. Click Edit API key.

  5. In the API restrictions section, do the following:

    1. Select the Restrict key option.
    2. From the dropdown, select your API Gateway managed service. It should be named after your API, such as Custom Search API for Gemini Grounding API.
  6. Click Save.

Your API Gateway endpoint is now secured. When you use the endpoint, pass the API key as a query parameter. For example: https://custom-search-gateway-UNIQUE_ID.nw.gateway.dev/v0/search?key=YOUR_GENERATED_API_KEY.

Considerations for your search API

Review the following considerations to help you design your search API:

  • Snippet quality: The snippet text returned by your API is crucial. It should be concise yet informative enough for Gemini to use as a factual basis for its response.
  • Latency: Your search API should respond quickly. High latency in your API increases the overall response time from Gemini.
  • Error handling: Implement robust error handling in your Cloud Functions or search API. If your API frequently errors or times out, it negatively impacts Gemini's ability to generate grounded responses.

What's next