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: 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. The following models support grounding with your API: For more information, see Gemini models. To use grounding with your search API, do the following: To use your existing search infrastructure with Gemini, your API endpoint must meet the following requirements: Request Body (from Gemini to your API): Response body (from your API to Gemini): A JSON array of objects. Each object represents a search result and must contain If no results are found, your API endpoint should return an empty array. 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 Before you begin, decide whether to use an existing API endpoint or set up a new one. The following table compares these two approaches. If you already have an API endpoint that meets the schema and authentication requirements, you can directly configure it in your Gemini API calls. When making a request to the Gemini API, include the Before using any of the request data, make the following replacements: To ground your model, send a HTTP method and URL: Request JSON body: The response includes grounding metadata with details about the retrieved context: The following command assumes that you have logged in to the gcloud CLI with your user account by running Save the request body from the REST tab in a file named The following command assumes that you have logged in to the gcloud CLI with your user account by running Save the request body from the REST tab in a file named If you don't have a compatible API endpoint, this section guides you through setting one up using Cloud Functions and API Gateway. 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. Deployment Navigate to the directory containing After deployment, note the trigger URL. You use this URL in the next step. 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 Replace 2. Deploy the API Gateway Execute the following gcloud CLI commands after replacing the variables: After deployment, the gateway hostname has the format 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. In the Google Cloud console, go to the APIs & Services > Credentials page.
How grounding with your search API works
Supported models
Before you begin
Search API requirements
API schema
POST
{
"query": "the user's search query string"
}
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"
}
]
Authentication
key
.Choose your grounding method
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
Configure the
externalApi
tooltools
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.
us-central1
.gemini-2.0-flash-001
.https://YOUR_GATEWAY_HOSTNAME/v0/search
. This endpoint must adhere to the specified API schema.POST
request to the generateContent
method. REST
POST https://LOCATION-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/publishers/google/models/MODEL_ID:generateContent
{
"contents": [{
"role": "user",
"parts": [{
"text": "USER_PROMPT"
}]
}],
"tools": [{
"retrieval": {
"externalApi": {
"api_spec": "SIMPLE_SEARCH",
"endpoint": "EXTERNAL_API_ENDPOINT",
"apiAuth": {
"apiKeyConfig": {
"apiKeyString": "EXTERNAL_API_KEY"
}
}
}
}
}]
}
{
"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
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
.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
gcloud init
or gcloud auth login
. You can check the active account by running gcloud auth list
.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
Create an external API wrapper with Cloud Functions
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
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
YOUR_REGION
with your chosen Google Cloud region, such as us-central1
.--allow-unauthenticated
is specified because API Gateway handles authentication.Secure the Cloud Function with an API Gateway and API key
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
YOUR_CLOUD_FUNCTION_TRIGGER_URL
with the trigger URL that you noted when deploying your Cloud Functions.
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
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
.
Click Create credentials, and select API key.
Copy the generated API key and store it in a secure location. This key is used by Gemini.
Click Edit API key.
In the API restrictions section, do the following:
- Select the Restrict key option.
- 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
.
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
- Learn about Grounding with Search.