> For the complete documentation index, see [llms.txt](https://docs.mapbox.com/help/llms.txt)

# Switch from Google Geocoding API to Mapbox Geocoding API

Are you using the **Google Geocoding API** and want to switch to the **Mapbox Geocoding API**? This tutorial walks you through the core geocoding concepts side by side, showing you the Google approach alongside the equivalent Mapbox implementation at each step.

In this tutorial, you will:

-   Authenticate requests using a Mapbox access token
-   Make forward geocoding requests to convert an address to coordinates
-   Parse the Mapbox GeoJSON response format
-   Make reverse geocoding requests to convert coordinates to an address
-   Filter results by feature type
-   Bias results toward a specific location using proximity

## Prerequisites

This guide assumes familiarity with making HTTP requests in JavaScript (using `fetch` or a similar library). Experience with the Google Geocoding API is helpful but not required.

To complete this tutorial, you will need:

-   **A Mapbox access token**: Find yours on the [Access token page](https://console.mapbox.com/account/access-tokens/) of your Mapbox account.
-   **A code editor**: A program like [Visual Studio Code](https://code.visualstudio.com/).

## Authentication and request structure

Both APIs authenticate requests with a key passed as a query parameter, but the parameter name and URL structure differ significantly.

### Google Geocoding API

The Google Geocoding API uses a single endpoint for both forward and reverse geocoding, distinguished by which query parameter you provide (`address` for forward, `latlng` for reverse):

```text
https://maps.googleapis.com/maps/api/geocode/json?address={search_text}&key=YOUR_GOOGLE_API_KEY
```

### Mapbox Geocoding API

The Mapbox Geocoding API uses separate endpoints for forward and reverse geocoding, authenticated with an `access_token` parameter:

```text
https://api.mapbox.com/search/geocode/v6/forward?q={search_text}&access_token=YOUR_MAPBOX_ACCESS_TOKEN
https://api.mapbox.com/search/geocode/v6/reverse?longitude={lng}&latitude={lat}&access_token=YOUR_MAPBOX_ACCESS_TOKEN
```

A few key differences:

-   **Parameter name**: Google uses `key`; Mapbox uses `access_token`.
-   **Separate endpoints**: Mapbox uses `/forward` and `/reverse` as distinct endpoints rather than a single endpoint with different parameters.
-   **Search parameter**: Google uses `address`; Mapbox uses `q`.

> **Note: Keep your access token secure**
> 
> Avoid committing your Mapbox access token to source control. For client-side use, consider restricting your token to specific URLs using [token scopes and allowed URLs](https://docs.mapbox.com/api/accounts/tokens/) in the Mapbox console.

## Forward geocoding

Forward geocoding converts a text string — an address, place name, or point of interest — into geographic coordinates.

### Google Geocoding API

With the Google Geocoding API, pass the address as the `address` parameter:

```js
const address = '1600 Amphitheatre Parkway, Mountain View, CA';

const url = `https://maps.googleapis.com/maps/api/geocode/json?address=${encodeURIComponent(address)}&key=YOUR_GOOGLE_API_KEY`;

const response = await fetch(url);
const data = await response.json();

if (data.status === 'OK') {
  const result = data.results[0];
  console.log(result.formatted_address);
  console.log(result.geometry.location); // { lat: 37.422, lng: -122.084 }
}
```

### Mapbox Geocoding API

With the Mapbox Geocoding API, pass the search text as the `q` parameter to the `/forward` endpoint:

```js
const address = '1600 Amphitheatre Parkway, Mountain View, CA';

const url = `https://api.mapbox.com/search/geocode/v6/forward?q=${encodeURIComponent(address)}&access_token=YOUR_MAPBOX_ACCESS_TOKEN`;

const response = await fetch(url);
const data = await response.json();

if (data.features.length > 0) {
  const feature = data.features[0];
  console.log(feature.properties.full_address);
  console.log(feature.geometry.coordinates); // [-122.084, 37.422] — [lng, lat]
}
```

Key differences:

-   **Error handling**: Google returns a `status` field (`"OK"`, `"ZERO_RESULTS"`, etc.). Mapbox uses standard HTTP status codes — check for a `200` response to confirm success, and check whether `features` is empty to determine if the query matched anything.
-   **Coordinate order**: Mapbox returns coordinates as `[longitude, latitude]` in the GeoJSON `geometry.coordinates` array, following the GeoJSON specification. Google returns `{ lat, lng }` objects.
-   **Response structure**: Mapbox returns a GeoJSON `FeatureCollection`; Google returns a custom `results` array. See the next step for a full response comparison.

## Parse the response

The two APIs return results in different formats. Understanding the structure of each response is key to migrating your parsing code.

### Google Geocoding API response

The Google Geocoding API returns a custom JSON object with a `results` array and a `status` string:

```json
{
  "status": "OK",
  "results": [
    {
      "formatted_address": "1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA",
      "geometry": {
        "location": {
          "lat": 37.4224764,
          "lng": -122.0842499
        },
        "location_type": "ROOFTOP",
        "viewport": { ... }
      },
      "types": ["street_address"],
      "address_components": [
        { "long_name": "1600", "short_name": "1600", "types": ["street_number"] },
        { "long_name": "Amphitheatre Pkwy", "short_name": "Amphitheatre Pkwy", "types": ["route"] },
        { "long_name": "Mountain View", "short_name": "Mountain View", "types": ["locality", "political"] },
        { "long_name": "California", "short_name": "CA", "types": ["administrative_area_level_1", "political"] },
        { "long_name": "United States", "short_name": "US", "types": ["country", "political"] },
        { "long_name": "94043", "short_name": "94043", "types": ["postal_code"] }
      ],
      "place_id": "ChIJ2eUgeAK6j4ARbn5u_wAGqWA"
    }
  ]
}
```

To extract coordinates and the formatted address from a Google result:

```js
const result = data.results[0];

const lat = result.geometry.location.lat;
const lng = result.geometry.location.lng;
const address = result.formatted_address;
```

### Mapbox Geocoding API response

The Mapbox Geocoding API returns a [GeoJSON](https://geojson.org/) `FeatureCollection`. Each result is a GeoJSON `Feature` with a `Point` geometry and a `properties` object:

```json
{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [-122.0842499, 37.4224764]
      },
      "properties": {
        "mapbox_id": "dXJuOm1ieHBsYzpB...",
        "feature_type": "address",
        "full_address": "1600 Amphitheatre Pkwy, Mountain View, California 94043, United States",
        "name": "1600 Amphitheatre Pkwy",
        "place_formatted": "Mountain View, California 94043, United States",
        "coordinates": {
          "longitude": -122.0842499,
          "latitude": 37.4224764
        },
        "context": {
          "street": { "name": "Amphitheatre Pkwy" },
          "postcode": { "name": "94043" },
          "place": { "name": "Mountain View" },
          "region": { "name": "California", "region_code": "CA" },
          "country": { "name": "United States", "country_code": "US" }
        }
      }
    }
  ]
}
```

Mapbox may return a few additional context objects, on top of the ones provided by Google. This includes features like secondary addresses, neighborhoods and districts.

To extract the same data from a Mapbox result:

```js
const feature = data.features[0];

const [lng, lat] = feature.geometry.coordinates;
const address = feature.properties.full_address;
```

The following table maps the most common Google response fields to their Mapbox equivalents:

| Google | Mapbox |
| --- | --- |
| `data.results` | `data.features` |
| `result.formatted_address` | `feature.properties.full_address` |
| `result.geometry.location.lat` | `feature.geometry.coordinates[1]` |
| `result.geometry.location.lng` | `feature.geometry.coordinates[0]` |
| `result.types[0]` | `feature.properties.feature_type` |
| `result.address_components` | `feature.properties.context` |
| `result.place_id` | `feature.properties.mapbox_id` |

> **Note: Accessing address components**
> 
> While Google returns address components as a flat array that you filter by type, Mapbox organizes them in a structured `context` object with named properties (`context.place`, `context.region`, `context.country`, etc.). This makes it easier to access specific parts of an address without iterating over an array.

## Reverse geocoding

Reverse geocoding converts geographic coordinates into a human-readable address. This is commonly used when a user clicks a location on a map and you want to display the address at that point.

### Google Geocoding API

The Google Geocoding API uses the same endpoint for reverse geocoding, passing coordinates as a combined `latlng` parameter (latitude first, longitude second):

```js
const lat = 37.4224764;
const lng = -122.0842499;

const url = `https://maps.googleapis.com/maps/api/geocode/json?latlng=${lat},${lng}&key=YOUR_GOOGLE_API_KEY`;

const response = await fetch(url);
const data = await response.json();

if (data.status === 'OK') {
  console.log(data.results[0].formatted_address);
}
```

The Google reverse geocoding response follows the same structure as forward geocoding — a `results` array ranked from most to least specific. For a precise coordinate, the first result is typically a rooftop-level address:

```json
{
  "status": "OK",
  "results": [
    {
      "formatted_address": "1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA",
      "geometry": {
        "location": { "lat": 37.4224764, "lng": -122.0842499 },
        "location_type": "ROOFTOP"
      },
      "types": ["street_address"],
      "address_components": [
        { "long_name": "1600", "short_name": "1600", "types": ["street_number"] },
        { "long_name": "Amphitheatre Pkwy", "short_name": "Amphitheatre Pkwy", "types": ["route"] },
        { "long_name": "Mountain View", "short_name": "Mountain View", "types": ["locality", "political"] },
        { "long_name": "California", "short_name": "CA", "types": ["administrative_area_level_1", "political"] },
        { "long_name": "United States", "short_name": "US", "types": ["country", "political"] },
        { "long_name": "94043", "short_name": "94043", "types": ["postal_code"] }
      ],
      "place_id": "ChIJ2eUgeAK6j4ARbn5u_wAGqWA"
    },
    {
      "formatted_address": "Mountain View, CA 94043, USA",
      "types": ["postal_code"],
      ...
    },
    {
      "formatted_address": "Mountain View, CA, USA",
      "types": ["locality", "political"],
      ...
    }
  ]
}
```

### Mapbox Geocoding API

The Mapbox Geocoding API uses a dedicated `/reverse` endpoint with separate `longitude` and `latitude` parameters:

```js
const lat = 37.4224764;
const lng = -122.0842499;

const url = `https://api.mapbox.com/search/geocode/v6/reverse?longitude=${lng}&latitude=${lat}&access_token=YOUR_MAPBOX_ACCESS_TOKEN`;

const response = await fetch(url);
const data = await response.json();

if (data.features.length > 0) {
  console.log(data.features[0].properties.full_address);
}
```

Like forward geocoding, the Mapbox response is a GeoJSON `FeatureCollection`. By default, results are ranked from most specific to least specific — the first feature is the most precise match (typically a street address), followed by progressively broader administrative features:

```json
{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [-122.0842499, 37.4224764]
      },
      "properties": {
        "mapbox_id": "dXJuOm1ieHBsYzpB...",
        "feature_type": "address",
        "full_address": "1600 Amphitheatre Pkwy, Mountain View, California 94043, United States",
        "name": "1600 Amphitheatre Pkwy",
        "place_formatted": "Mountain View, California 94043, United States",
        "coordinates": {
          "longitude": -122.0842499,
          "latitude": 37.4224764
        },
        "context": {
          "street": { "name": "Amphitheatre Pkwy" },
          "postcode": { "name": "94043" },
          "place": { "name": "Mountain View" },
          "region": { "name": "California", "region_code": "CA" },
          "country": { "name": "United States", "country_code": "US" }
        }
      }
    },
    {
      "type": "Feature",
      "properties": {
        "feature_type": "postcode",
        "full_address": "Mountain View, California 94043, United States",
        ...
      }
    },
    {
      "type": "Feature",
      "properties": {
        "feature_type": "place",
        "full_address": "Mountain View, California, United States",
        ...
      }
    }
  ]
}
```

::: warning If you pass in the `types` parameter into your request, along with a `limit`, the results will instead be ranked by distance instead, based off the queried co-ordinate. :::

Key differences between the two response formats:

-   **Result structure**: Google returns an array of flat objects with `formatted_address` and `address_components`. Mapbox returns GeoJSON features with `properties.full_address` and a structured `properties.context` object.
-   **Specificity indicator**: Google signals precision with `geometry.location_type` (`"ROOFTOP"`, `"RANGE_INTERPOLATED"`, `"GEOMETRIC_CENTER"`, `"APPROXIMATE"`). Mapbox uses `properties.feature_type` (`"address"`, `"street"`, `"place"`, etc.) — if the top result is `"address"`, the match is precise; if it's `"place"` or broader, the coordinate didn't resolve to a specific address. Mapbox also offers access to addition address features, like rooftop, parcel, point, approximate, interpolated, etc. information, which be accessed through `feature.properties.coordinates.accuracy`.
-   **Result count**: By default, Mapbox returns one feature per level of the administrative hierarchy (address, place, region, country, etc.), so a single reverse query typically returns several entries — like Google. To get only the top match, take `data.features[0]`.

## Filter by result type

Filtering results by feature type is an area where the two APIs behave quite differently — and where Mapbox's `types` parameter does something Google's API cannot do on forward geocoding requests.

### Google Geocoding API

Google's `result_type` parameter is a **post-search filter available only for reverse geocoding** (when using `latlng`). It does not apply to forward geocoding. When used with a reverse geocoding request, the API fetches all results for the coordinate and then discards any that don't match the specified type:

```js
// Return only city-level results for a coordinate
const url = `https://maps.googleapis.com/maps/api/geocode/json?latlng=37.4224764,-122.0842499&result_type=locality&key=YOUR_GOOGLE_API_KEY`;
```

For forward geocoding, `result_type` is silently ignored — Google will not return an error, it returns normal forward geocoding results as if the parameter wasn't there. The only server-side restriction available for forward geocoding is the `components` parameter, and even then, only `country` and `postal_code` components are enforced as hard filters. Other component types (such as `locality`) exist in the docs but only bias results rather than filter them.

To get only city-level or postal-code-type results from a Google forward geocoding request, you must filter client-side by inspecting the `types` array in each result:

```js
const response = await fetch(url);
const data = await response.json();

// Filter results to only those with "locality" in their types array
const cities = data.results.filter(result =>
  result.types.includes('locality')
);
```

### Mapbox Geocoding API

Mapbox uses the `types` parameter, which works as a **true pre-search filter for both forward and reverse geocoding**. Only features matching the specified types are returned — no client-side filtering needed:

```js
// Return only city-level results
const url = `https://api.mapbox.com/search/geocode/v6/forward?q=Springfield&types=place&access_token=YOUR_MAPBOX_ACCESS_TOKEN`;

// Return only postal codes
const url = `https://api.mapbox.com/search/geocode/v6/forward?q=94043&types=postcode&access_token=YOUR_MAPBOX_ACCESS_TOKEN`;
```

The following table maps Google result types to their Mapbox equivalents:

| Google `result_type` | Mapbox `types` | Description |
| --- | --- | --- |
| `country` | `country` | Country-level results |
| `administrative_area_level_1` | `region` | States, provinces |
| `administrative_area_level_2` | `district` | Counties, districts |
| `locality` | `place` | Cities and towns |
| `sublocality` | `locality` | Sub-city neighborhoods |
| `neighborhood` | `neighborhood` | Neighborhoods |
| `postal_code` | `postcode` | Postal codes |
| `route` | `street` | Named streets |
| `street_address` | `address` | Street-level addresses |
| `sub_premise` | `secondary_address` | Apartment, unit, suite number, etc. (forward geocoding only) |

You can pass multiple types as a comma-separated list to the Mapbox `types` parameter:

```js
// Return addresses and places
const url = `https://api.mapbox.com/search/geocode/v6/forward?q=ontario&types=street%2Cplace&access_token=YOUR_MAPBOX_ACCESS_TOKEN`;
```

## Bias results with proximity

When the search context matters — for example, when a user is searching for "Main Street" from a specific city — both APIs let you bias results toward a geographic area.

### Google Geocoding API

Google uses `bounds` to define a bounding box that biases results. Results within the box are prioritized but results outside it are not excluded:

```js
// Bias toward San Francisco
const bounds = '37.708,-122.512|37.812,-122.358'; // southwest|northeast

const url = `https://maps.googleapis.com/maps/api/geocode/json?address=Market+Street&bounds=${bounds}&key=YOUR_GOOGLE_API_KEY`;
```

### Mapbox Geocoding API

Mapbox uses a `proximity` parameter — a single longitude,latitude coordinate — to bias results toward a specific point. Results closer to that point are ranked higher:

```js
// Bias toward San Francisco
const url = `https://api.mapbox.com/search/geocode/v6/forward?q=Market+Street&proximity=-122.431,37.773&access_token=YOUR_MAPBOX_ACCESS_TOKEN`;
```

Mapbox also supports a `bbox` parameter to restrict results to a strict bounding box (excluding results outside the box entirely):

```js
// Restrict to San Francisco bounding box
const bbox = '-122.512,37.708,-122.358,37.812'; // minLng,minLat,maxLng,maxLat

const url = `https://api.mapbox.com/search/geocode/v6/forward?q=Market+Street&bbox=${bbox}&access_token=YOUR_MAPBOX_ACCESS_TOKEN`;
```

A few things to note about proximity and bounding boxes:

-   The Mapbox `proximity` parameter takes `longitude,latitude` order (longitude first), consistent with coordinate format in all Mapbox APIs and SDKs.
-   The Mapbox `bbox` parameter takes four comma-separated values in `minLng,minLat,maxLng,maxLat` order. Google's `bounds` uses `lat,lng|lat,lng` (latitude first, pipe-separated).
-   `proximity` biases results without excluding anything; `bbox` strictly filters results to the specified area.

## Limit results

Both APIs let you control how many results are returned.

### Google Geocoding API

The Google Geocoding API does not expose a `limit` parameter. You get however many results Google's ranking returns — for reverse geocoding, this often includes 8–15 or more entries as the API walks up the geographic hierarchy (street address → route → neighborhood → postal code → city → admin levels → country). To get only the top match, take the first element of the `results` array:

```js
const topResult = data.results[0];
```

### Mapbox Geocoding API

The `limit` parameter behaves differently depending on the endpoint.

**Forward geocoding** (`/forward`): defaults to `5`, maximum `10`.

```js
// Return only the single best match
const url = `https://api.mapbox.com/search/geocode/v6/forward?q=${encodeURIComponent(address)}&limit=1&access_token=YOUR_MAPBOX_ACCESS_TOKEN`;
```

**Reverse geocoding** (`/reverse`): defaults to `1`, maximum `5`. The default of `1` reflects how the reverse endpoint works — by default it returns one feature per level of the administrative hierarchy (address, place, region, country, etc.) rather than multiple features of the same type.

There is also a constraint when raising `limit` above its default on reverse requests: you must supply exactly one `types` value, or the API returns a `422` error. This is because without a `types` filter, the reverse endpoint already returns one result per hierarchy level; requesting more results only makes sense when you have constrained it to a single type.

```js
// Return up to 3 address-level results near a coordinate
const url = `https://api.mapbox.com/search/geocode/v6/reverse?longitude=${lng}&latitude=${lat}&limit=3&types=address&access_token=YOUR_MAPBOX_ACCESS_TOKEN`;
```

## Next steps

**Congratulations!** You have learned how to migrate from the Google Geocoding API to the Mapbox Geocoding API.

### What we covered

-   Authenticating requests with a Mapbox access token
-   Making [forward geocoding](https://docs.mapbox.com/api/search/geocoding/#forward-geocoding) requests
-   Parsing the [GeoJSON FeatureCollection](https://docs.mapbox.com/api/search/geocoding/#geocoding-response-object) response
-   Making [reverse geocoding](https://docs.mapbox.com/api/search/geocoding/#reverse-geocoding) requests
-   Filtering results with the [`types` parameter](https://docs.mapbox.com/api/search/geocoding/#optional-parameters-for-the-forward-endpoint)
-   Biasing results with the [`proximity` parameter](https://docs.mapbox.com/api/search/geocoding/#optional-parameters-for-the-forward-endpoint)

### Try the Geocoding API Playground

The [Geocoding API Playground](https://docs.mapbox.com/playground/geocoding/) is a browser-based GUI for experimenting with the API without writing any code. You can construct forward and reverse geocoding requests, adjust parameters like `types`, `proximity`, and `language`, and inspect the full JSON response — useful for validating your query parameters before wiring them into your application.

### Client libraries

If you prefer not to call the HTTP API directly, Mapbox provides client libraries that wrap the Geocoding API with a typed interface:

-   **Web and Node.js**: [Mapbox Search JS](https://docs.mapbox.com/mapbox-search-js/guides/) provides `searchBox`, `autofill`, and low-level geocoding methods for browser and server-side JavaScript applications.
-   **iOS**: The [Search SDK for iOS](https://docs.mapbox.com/ios/search/guides/) provides Swift APIs for forward and reverse geocoding, autocomplete, and category search.
-   **Android**: The [Search SDK for Android](https://docs.mapbox.com/android/search/guides/) provides equivalent Kotlin APIs for Android applications.

Continue building with these tutorials and guides:

> **Related content (guide): [Mapbox Geocoding API](https://docs.mapbox.com/api/search/geocoding/)**
> 
> Full reference documentation for all Geocoding API endpoints and parameters.

> **Related content (tutorial): [Switch from Google Maps JavaScript API to Mapbox GL JS](https://docs.mapbox.com/help/tutorials/google-to-mapbox/)**
> 
> Migrate your web map from the Google Maps JavaScript API to Mapbox GL JS.

> **Related content (tutorial): [Add a search box to your website](https://docs.mapbox.com/help/tutorials/add-address-autofill-to-your-website/)**
> 
> Use Mapbox Search JS to add a ready-to-use address search component to a webpage.

> **Related content (guide): [Mapbox Search JS](https://docs.mapbox.com/mapbox-search-js/guides/)**
> 
> Learn about the Mapbox JavaScript library for adding search, autocomplete, and address autofill to web applications.