Grounding with Google Maps

Grounding with Google Maps connects the generative capabilities of Gemini with the rich, factual, and up-to-date data of Google Maps. This feature enables developers to easily incorporate location-aware functionality into their applications. When a user query has a context related to Maps data, the Gemini model leverages Google Maps to provide factually accurate and fresh answers that are relevant to the user's specified location or general area.

  • Accurate, location-aware responses: Leverage Google Maps' extensive and current data for geographically specific queries.
  • Enhanced personalization: Tailor recommendations and information based on user-provided locations.
  • Contextual information and widgets: Context tokens to render interactive Google Maps widgets alongside generated content.

Get started

This example demonstrates how to integrate Grounding with Google Maps into your application to provide accurate, location-aware responses to user queries. The prompt asks for local recommendations with an optional user location, enabling the Gemini model to leverage Google Maps data.

Python

from google import genai
from google.genai import types

client = genai.Client()

prompt = "What are the best Italian restaurants within a 15-minute walk from here?"

response = client.models.generate_content(
    model='gemini-2.5-flash-lite',
    contents=prompt,
    config=types.GenerateContentConfig(
        # Turn on grounding with Google Maps
        tools=[types.Tool(google_maps=types.GoogleMaps())],
        # Optionally provide the relevant location context (this is in Los Angeles)
        tool_config=types.ToolConfig(retrieval_config=types.RetrievalConfig(
            lat_lng=types.LatLng(
                latitude=34.050481, longitude=-118.248526))),
    ),
)

print("Generated Response:")
print(response.text)

if grounding := response.candidates[0].grounding_metadata:
  if grounding.grounding_chunks:
    print('-' * 40)
    print("Sources:")
    for chunk in grounding.grounding_chunks:
      print(f'- [{chunk.maps.title}]({chunk.maps.uri})')

JavaScript

import { GoogleGenAI } from "@google/gnai";

const ai = new GoogleGenAI({});

async function generateContentWithMapsGrounding() {
  const response = await ai.models.generateContent({
    model: "gemini-2.5-flash",
    contents: "What are the best Italian restaurants within a 15-minute walk from here?",
    config: {
      // Turn on grounding with Google Maps
      tools: [{ googleMaps: {} }],
      toolConfig: {
        retrievalConfig: {
          // Optionally provide the relevant location context (this is in Los Angeles)
          latLng: {
            latitude: 34.050481,
            longitude: -118.248526,
          },
        },
      },
    },
  });

  console.log("Generated Response:");
  console.log(response.text);

  const grounding = response.candidates[0]?.groundingMetadata;
  if (grounding?.groundingChunks) {
    console.log("-".repeat(40));
    console.log("Sources:");
    for (const chunk of grounding.groundingChunks) {
      if (chunk.maps) {
        console.log(`- [${chunk.maps.title}](${chunk.maps.uri})`);
      }
    }
  }
}

generateContentWithMapsGrounding();

REST

curl -X POST 'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-lite:generateContent' \
  -H 'Content-Type: application/json' \
  -H "x-goog-api-key: ${GEMINI_API_KEY}" \
  -d '{
  "contents": [{
    "role": "user",
    "parts": [{
      "text": "What are the best Italian restaurants within a 15-minute walk from here?"
    }]
  }],
  "tools": [{"googleMaps": {}}],
  "toolConfig": {
    "retrievalConfig": {
      "latLng": {"latitude": 34.050481, "longitude": -118.248526}
    }
  }
}'

How Grounding with Google Maps works

Grounding with Google Maps integrates the Gemini API with the Google Geo ecosystem by using the Maps API as a grounding source. When a user's query contains geographical context, the Gemini model can invoke the Grounding with Google Maps tool. The model can then generate responses grounded in Google Maps data relevant to the provided location.

The process typically involves:

  1. User query: A user submits a query to your application, potentially including geographical context (e.g., "coffee shops near me," "museums in San Francisco").
  2. Tool invocation: The Gemini model, recognizing the geographical intent, invokes the Grounding with Google Maps tool. This tool can optionally be provided with the user's latitude and longitude for location-aware results.
  3. Data retrieval: The Grounding with Google Maps service queries Google Maps for relevant information (e.g., places, reviews, photos, addresses, opening hours).
  4. Grounded generation: The retrieved Maps data is used to inform the Gemini model's response, ensuring factual accuracy and relevance.
  5. Response & widget token: The model returns a text response, which includes citations to Google Maps sources. Optionally, the API response may also contain a google_maps_widget_context_token, allowing developers to render a contextual Google Maps widget in their application for visual interaction.

Why and when to use Grounding with Google Maps

Grounding with Google Maps is ideal for applications that require accurate, up-to-date, and location-specific information. It enhances the user experience by providing relevant and personalized content backed by Google Maps' extensive database of over 250 million places worldwide.

You should use Grounding with Google Maps when your application needs to:

  • Provide complete and accurate responses to geo-specific questions.
  • Build conversational trip planners and local guides.
  • Recommend points of interest based on location and user preferences like restaurants or shops.
  • Create location-aware experiences for social, retail, or food delivery services.

Grounding with Google Maps excels in use cases where proximity and current factual data are critical, such as finding the "best coffee shop near me" or getting directions.

API methods and parameters

Grounding with Google Maps is exposed through the Gemini API as a tool within the generateContent method. You enable and configure Grounding with Google Maps by including a googleMaps object in the tools parameter of your request.

JSON

{
  "contents": [{
    "parts": [
      {"text": "Restaurants near Times Square."}
    ]
  }],
  "tools":  { "googleMaps": {} }
}

The googleMaps tool can additionally accept a boolean enableWidget parameter, that is used to control whether the googleMapsWidgetContextToken field is returned in the response. This can be used to display a contextual Places widget.

JSON

{
"contents": [{
    "parts": [
      {"text": "Restaurants near Times Square."}
    ]
  }],
  "tools":  { "googleMaps": { "enableWidget": true } }
}

Additionally, the tool supports passing the contextual location as toolConfig.

JSON

{
  "contents": [{
    "parts": [
      {"text": "Restaurants near here."}
    ]
  }],
  "tools":  { "googleMaps": {} },
  "toolConfig":  {
    "retrievalConfig": {
      "latLng": {
        "latitude": 40.758896,
        "longitude": -73.985130
      }
    }
  }
}

Understanding the grounding response

When a response is successfully grounded with Google Maps data, the response includes a groundingMetadata field. This structured data is essential for verifying claims and building a rich citation experience in your application, as well as meeting the service usage requirements.

JSON

{
  "candidates": [
    {
      "content": {
        "parts": [
          {
            "text": "CanteenM is an American restaurant with..."
          }
        ],
        "role": "model"
      },
      "groundingMetadata": {
        "groundingChunks": [
          {
            "maps": {
              "uri": "https://maps.google.com/?cid=13100894621228039586",
              "title": "Heaven on 7th Marketplace",
              "placeId": "places/ChIJ0-zA1vBZwokRon0fGj-6z7U"
            },
            // repeated ...
          }
        ],
        "groundingSupports": [
          {
            "segment": {
              "startIndex": 0,
              "endIndex": 79,
              "text": "CanteenM is an American restaurant with a 4.6-star rating and is open 24 hours."
            },
            "groundingChunkIndices": [0]
          },
          // repeated ...
        ],
        "webSearchQueries": [
          "restaurants near me"
        ],
        "googleMapsWidgetContextToken": "widgetcontent/..."
      }
    }
  ]
}

The Gemini API returns the following information with the groundingMetadata:

  • groundingChunks: Array of objects containing the maps sources (uri, placeId and title).
  • groundingSupports: Array of chunks to connect model response text to the sources in groundingChunks. Each chunk links a text span (defined by startIndex and endIndex) to one or more groundingChunkIndices. This is the key to building inline citations.
  • googleMapsWidgetContextToken: A text token that can be used to render a contextual Places widget.

For a code snippet showing how to render inline citations in text, see the example in the Grounding with Google Search docs.

Display the Google Maps contextual widget

To use the returned googleMapsWidgetContextToken, you need to load the Google Maps JavaScript API.

Use cases

Grounding with Google Maps supports a variety of location-aware use cases. The following examples demonstrate how different prompts and parameters can leverage Grounding with Google Maps. Information in the Google Maps Grounded Results may differ from actual conditions.

Handling place-specific questions

Ask detailed questions about a specific place to get answers based on Google user reviews and other Maps data.

Python

from google import genai
from google.genai import types

client = genai.Client()

prompt = "Is there a cafe near the corner of 1st and Main that has outdoor seating?"

response = client.models.generate_content(
    model='gemini-2.5-flash-lite',
    contents=prompt,
    config=types.GenerateContentConfig(
        # Turn on the Maps tool
        tools=[types.Tool(google_maps=types.GoogleMaps())],

        # Provide the relevant location context (this is in Los Angeles)
        tool_config=types.ToolConfig(retrieval_config=types.RetrievalConfig(
            lat_lng=types.LatLng(
                latitude=34.050481, longitude=-118.248526))),
    ),
)

print("Generated Response:")
print(response.text)

if grounding := response.candidates[0].grounding_metadata:
  if chunks := grounding.grounding_chunks:
    print('-' * 40)
    print("Sources:")
    for chunk in chunks:
      print(f'- [{chunk.maps.title}]({chunk.maps.uri})')
  ```

Javascript

import { GoogleGenAI } from '@google/genai';

const ai = new GoogleGenAI({});

async function run() {
  const prompt = "Is there a cafe near the corner of 1st and Main that has outdoor seating?";

  const response = await ai.models.generateContent({
    model: 'gemini-2.5-flash',
    contents: prompt,
    config: {
      // Turn on the Maps tool
      tools: [{googleMaps: {}}],
      // Provide the relevant location context (this is in Los Angeles)
      toolConfig: {
        retrievalConfig: {
          latLng: {
            latitude: 34.050481,
            longitude: -118.248526
          }
        }
      }
    },
  });

  console.log("Generated Response:");
  console.log(response.text);

  const chunks = response.candidates[0].groundingMetadata?.groundingChunks;
  if (chunks) {
    console.log('-'.repeat(40));
    console.log("Sources:");
    for (const chunk of chunks) {
      if (chunk.maps) {
        console.log(`- [${chunk.maps.title}](${chunk.maps.uri})`);
      }
    }
  }
}

run();

REST

curl -X POST 'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-lite:generateContent' \
  -H 'Content-Type: application/json' \
  -H "x-goog-api-key: ${GEMINI_API_KEY}" \
  -d '{
  "contents": [{
    "role": "user",
    "parts": [{
      "text": "Is there a cafe near the corner of 1st and Main that has outdoor seating?"
    }]
  }],
  "tools": [{"googleMaps": {}}],
  "toolConfig": {
    "retrievalConfig": {
      "latLng": {"latitude": 34.050481, "longitude": -118.248526}
    }
  }
}'

Providing location-based personalization

Get recommendations tailored to a user's preferences and a specific geographical area.

Python

from google import genai
from google.genai import types

client = genai.Client()

prompt = "Which family-friendly restaurants near here have the best playground reviews?"

response = client.models.generate_content(
    model='gemini-2.5-flash',
    contents=prompt,
    config=types.GenerateContentConfig(
      tools=[types.Tool(google_maps=types.GoogleMaps())],
      tool_config=types.ToolConfig(retrieval_config=types.RetrievalConfig(
          # Provide the location as context; this is Austin, TX.
          lat_lng=types.LatLng(
              latitude=30.2672, longitude=-97.7431))),
    ),
)

print("Generated Response:")
print(response.text)

if grounding := response.candidates[0].grounding_metadata:
  if chunks := grounding.grounding_chunks:
    print('-' * 40)
    print("Sources:")
    for chunk in chunks:
      print(f'- [{chunk.maps.title}]({chunk.maps.uri})')

Javascript

import { GoogleGenAI } from '@google/genai';

const ai = new GoogleGenAI({});

async function run() {
  const prompt = "Which family-friendly restaurants near here have the best playground reviews?";

  const response = await ai.models.generateContent({
    model: 'gemini-2.5-flash',
    contents: prompt,
    config: {
      tools: [{googleMaps: {}}],
      toolConfig: {
        retrievalConfig: {
          // Provide the location as context; this is Austin, TX.
          latLng: {
            latitude: 30.2672,
            longitude: -97.7431
          }
        }
      }
    },
  });

  console.log("Generated Response:");
  console.log(response.text);

  const chunks = response.candidates[0].groundingMetadata?.groundingChunks;
  if (chunks) {
    console.log('-'.repeat(40));
    console.log("Sources:");
    for (const chunk of chunks) {
      if (chunk.maps) {
        console.log(`- [${chunk.maps.title}](${chunk.maps.uri})`);
      }
    }
  }
}

run();

REST

curl -X POST 'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-lite:generateContent' \
  -H 'Content-Type: application/json' \
  -H "x-goog-api-key: ${GEMINI_API_KEY}" \
  -d '{
  "contents": [{
    "role": "user",
    "parts": [{
      "text": "Which family-friendly restaurants near here have the best playground reviews?"
    }],
  }],
  "tools": [{"googleMaps": {}}],
  "toolConfig": {
    "retrievalConfig": {
      "latLng": {"latitude": 30.2672, "longitude": -97.7431}
    }
  }
}'

Assisting with itinerary planning

Generate multi-day plans with directions and information about various locations, perfect for travel applications.

In this example, the googleMapsWidgetContextToken has been requested by enabling the widget in the Google Maps tool. When enabled, the returned token can be used to render a contextual Places widget using the <gmp-places-contextual> component from the Google Maps JavaScript API.

Python

from google import genai
from google.genai import types

client = genai.Client()

prompt = "Plan a day in San Francisco for me. I want to see the Golden Gate Bridge, visit a museum, and have a nice dinner."

response = client.models.generate_content(
    model='gemini-2.5-flash',
    contents=prompt,
    config=types.GenerateContentConfig(
      tools=[types.Tool(google_maps=types.GoogleMaps(enable_widget=True))],
      tool_config=types.ToolConfig(retrieval_config=types.RetrievalConfig(
          # Provide the location as context, this is in San Francisco.
          lat_lng=types.LatLng(
              latitude=37.78193, longitude=-122.40476))),
    ),
)

print("Generated Response:")
print(response.text)

if grounding := response.candidates[0].grounding_metadata:
  if grounding.grounding_chunks:
    print('-' * 40)
    print("Sources:")
    for chunk in grounding.grounding_chunks:
      print(f'- [{chunk.maps.title}]({chunk.maps.uri})')

  if widget_token := grounding.google_maps_widget_context_token:
    print('-' * 40)
    print(f'<gmp-place-contextual context-token="{widget_token}"></gmp-place-contextual>')

Javascript

import { GoogleGenAI } from '@google/genai';

const ai = new GoogleGenAI({});

async function run() {
  const prompt = "Plan a day in San Francisco for me. I want to see the Golden Gate Bridge, visit a museum, and have a nice dinner.";

  const response = await ai.models.generateContent({
    model: 'gemini-2.5-flash',
    contents: prompt,
    config: {
      tools: [{googleMaps: {enableWidget: true}}],
      toolConfig: {
        retrievalConfig: {
          // Provide the location as context, this is in San Francisco.
          latLng: {
            latitude: 37.78193,
            longitude: -122.40476
          }
        }
      }
    },
  });

  console.log("Generated Response:");
  console.log(response.text);

  const groundingMetadata = response.candidates[0]?.groundingMetadata;
  if (groundingMetadata) {
    if (groundingMetadata.groundingChunks) {
      console.log('-'.repeat(40));
      console.log("Sources:");
      for (const chunk of groundingMetadata.groundingChunks) {
        if (chunk.maps) {
          console.log(`- [${chunk.maps.title}](${chunk.maps.uri})`);
        }
      }
    }

    if (groundingMetadata.googleMapsWidgetContextToken) {
      console.log('-'.repeat(40));
      document.body.insertAdjacentHTML('beforeend', `<gmp-place-contextual context-token="${groundingMetadata.googleMapsWidgetContextToken}`"></gmp-place-contextual>`);
    }
  }
}

run();

REST

curl -X POST 'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-lite:generateContent' \
  -H 'Content-Type: application/json' \
  -H "x-goog-api-key: ${GEMINI_API_KEY}" \
  -d '{
  "contents": [{
    "role": "user",
    "parts": [{
      "text": "Plan a day in San Francisco for me. I want to see the Golden Gate Bridge, visit a museum, and have a nice dinner."
    }]
  }],
  "tools": [{"googleMaps": {"enableWidget":"true"}}],
  "toolConfig": {
    "retrievalConfig": {
    "latLng": {"latitude": 37.78193, "longitude": -122.40476}
  }
  }
}'

When the widget is rendered, it will look something like the following:

An example of a maps widget when rendered

Service usage requirements

This section describes the service usage requirements for Grounding with Google Maps.

Inform the user about the use of Google Maps sources

With each Google Maps Grounded Result, you'll receive sources in groundingChunks that support each response. The following metadata is also returned:

  • source uri
  • title
  • ID

When presenting results from Grounding with Google Maps, you must specify the associated Google Maps sources, and inform your users of the following:

  • The Google Maps sources must immediately follow the generated content that the sources support. This generated content is also referred to as Google Maps Grounded Result.
  • The Google Maps sources must be viewable within one user interaction.

For each source in groundingChunks and in grounding_chunks.maps.placeAnswerSources.reviewSnippets, a link preview must be generated following these requirements:

  • Attribute each source to Google Maps following the Google Maps text attribution guidelines.
  • Display the source title provided in the response.
  • Link to the source using the uri or googleMapsUri from the response.

These images show the minimum requirements for displaying the sources and Google Maps links.

Prompt with response showing sources

You can collapse the view of the sources.

Prompt with response and sources collapsed

Optional: Enhance the link preview with additional content, such as:

  • A Google Maps favicon is inserted before the Google Maps text attribution.
  • A photo from the source URL (og:image).

For more information about some of our Google Maps data providers and their license terms, see the Google Maps and Google Earth legal notices.

Google Maps text attribution guidelines

When you attribute sources to Google Maps in text, follow these guidelines:

  • Don't modify the text Google Maps in any way:
    • Don't change the capitalization of Google Maps.
    • Don't wrap Google Maps onto multiple lines.
    • Don't localize Google Maps into another language.
    • Prevent browsers from translating Google Maps by using the HTML attribute translate="no".
  • Style Google Maps text as described in the following table:
Property Style
Font family Roboto. Loading the font is optional.
Fallback font family Any sans serif body font already used in your product or "Sans-Serif" to invoke the default system font
Font style Normal
Font weight 400
Font color White, black (#1F1F1F), or gray (#5E5E5E). Maintain accessible (4.5:1) contrast against the background.
Font size
  • Minimum font size: 12sp
  • Maximum font size: 16sp
  • To learn about sp, see Font size units on the Material Design website.
Spacing Normal

Example CSS

The following CSS renders Google Maps with the appropriate typographic style and color on a white or light background.

CSS

@import url('https://fonts.googleapis.com/css2?family=Roboto&display=swap');

.GMP-attribution {

font-family: Roboto, Sans-Serif;
font-style: normal;
font-weight: 400;
font-size: 1rem;
letter-spacing: normal;
white-space: nowrap;
color: #5e5e5e;
}

Context token, place ID, and review ID

The Google Maps data includes context token, place ID, and review ID. You might cache, store, and export the following response data:

  • googleMapsWidgetContextToken
  • placeId
  • reviewId

The restrictions against caching in the Grounding with Google Maps Terms don't apply.

Prohibited activity and territory

Grounding with Google Maps has additional restrictions for certain content and activities to maintain a safe and reliable platform. In addition to the usage restrictions in the Terms, you will not use Grounding with Google Maps for high risk activities including emergency response services. You will not distribute or market your application that offers Grounding with Google Maps in a Prohibited Territory. The current Prohibited Territories are:

  • China
  • Crimea
  • Cuba
  • Donetsk People's Republic
  • Iran
  • Luhansk People's Republic
  • North Korea
  • Syria
  • Vietnam

This list may be updated from time to time.

Best practices

  • Provide user location: For the most relevant and personalized responses, always include the user_location (latitude and longitude) in your googleMapsGrounding configuration when the user's location is known.
  • Render the Google Maps contextual widget: The contextual widget is rendered using the context token, googleMapsWidgetContextToken, which is returned in the Gemini API response and can be used to render visual content from Google Maps. For more information on the contextual widget, see Grounding with Google Maps widget in the Google Developer Guide.
  • Inform End-Users: Clearly inform your end-users that Google Maps data is being used to answer their queries, especially when the tool is enabled.
  • Monitor Latency: For conversational applications, ensure that the P95 latency for grounded responses remains within acceptable thresholds to maintain a smooth user experience.
  • Toggle Off When Not Needed: Grounding with Google Maps is off by default. Only enable it ("tools": [{"googleMaps": {}}]) when a query has a clear geographical context, to optimize performance and cost.

Limitations

  • Geographical Scope: Currently, Grounding with Google Maps is globally available
  • Model Support: Only specific Gemini models support Grounding with Google Maps: Gemini 2.5 Flash-Lite, Gemini 2.5 Pro, Gemini 2.5 Flash, and Gemini 2.0 Flash (but not 2.0 Flash Lite).
  • Multimodal Inputs/Outputs: Grounding with Google Maps does not currently support multimodal inputs or outputs beyond text and contextual map widgets.
  • Default State: The Grounding with Google Maps tool is off by default. You must explicitly enable it in your API requests.

Pricing and rate limits

Grounding with Google Maps pricing is based on queries. The current rate is $25 / 1K grounded prompts. A request is only counted towards the quota when a prompt successfully returns at least one Google Maps grounded result (i.e., results containing at least one Google Maps source). If multiple queries are sent to Google Maps from a single request, it counts as one request towards the rate limit.

For detailed pricing information, see the Gemini API pricing page.

Supported models

You can find their capabilities on the model overview page.

Model Grounding with Google Maps
Gemini 2.5 Pro ✔️
Gemini 2.5 Flash ✔️
Gemini 2.5 Flash-Lite ✔️
Gemini 2.0 Flash ✔️

What's next