# The Go client for Google Maps web services, and the APIs it will never add

> google-maps-services-go is an Apache-2.0 Go client for the Google Maps Platform web service APIs, covering elevation, geocoding, roads, time zone and static maps plus three legacy APIs. Its README states that Places Legacy, Directions Legacy and Distance Matrix Legacy can no longer be enabled for new projects as of October 2026, and that the newer APIs will not be added to this library at all.

**googlemaps/google-maps-services-go** — Go client library for Google Maps API Web Services

- Repository: https://github.com/googlemaps/google-maps-services-go
- Website: https://pkg.go.dev/googlemaps.github.io/maps
- Stars: 830 · Forks: 231
- Language: Go
- License: Apache-2.0
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/googlemaps-google-maps-services-go

## A thin client with a fixed API surface

google-maps-services-go is a Go client library for the Google Maps Platform web service APIs, published as the module googlemaps.github.io/maps and documented on pkg.go.dev at googlemaps.github.io/maps.

The set of APIs it covers is short. The current ones are the Elevation API, the Geocoding API, the Roads API, the Time Zone API and the Maps Static API. On top of that it carries three APIs the README labels as legacy, the Directions API, the Distance Matrix API and the Places API.

The source layout is one file per API, with directions.go, distancematrix.go, elevation.go, geocoding.go, geolocation.go, places.go, roads.go, staticmap.go, timezone.go and transport.go, plus the shared pieces such as client.go, latlng.go, polyline.go, encoding.go, types.go and addressdescriptor.go. Every one of those has a matching test file, and the examples/ directory holds a runnable example per API, with directories for directions, distancematrix, elevation, geocoding, places, roads, staticmap and timezone.

That structure is what tells you the library is a faithful mapping of the wire protocols rather than a higher level abstraction. There is a types.go and a latlng.go, which is what native types means here, and the geolocation.go file shows that the geolocation API is covered as well even though the README's list does not mention it.

Requirements are Go 1.7 or later, though the module file itself declares go 1.14, and a Google Maps Platform API key from a project with the relevant APIs enabled, with the note that the key should be kept secret on your server.

## The notice that decides whether you can use this at all

The first thing in the README is a boxed warning, and for a new project it is the deciding factor.

Several APIs supported by this library are in legacy status. Places API (Legacy), Directions API (Legacy) and Distance Matrix API (Legacy) can no longer be enabled for new Google Cloud projects as of October 2026, while existing projects remain fully supported. For new features and improved performance the README points at migrating to Places API (New) for Places, and to the Routes API for both Directions and Distance Matrix.

Then comes the sentence that closes the door on the obvious plan of waiting for this library to catch up. The newer APIs will not be added to this client library.

Instead, the README directs you to the Google Maps Platform Cloud Client Library for Go, the maps subtree of google-cloud-go, and lists the packages to use there: Places API (New), Routes API, Address Validation API and Datasets API.

So the library's future is bounded and known. It will keep working for the APIs it has, with the legacy endpoints and the current ones such as elevation, geocoding, roads, time zone and static maps, and the migration path for the three legacy APIs is a different library entirely.

The release history fits that picture. The tagged versions are v1.5.0 on 2023-05-31, v1.6.0 on 2023-12-01 and v1.7.0 on 2023-12-02, so the last published release is from December 2023, while the last push to the repository was on 2026-10-06. Work continues in the tree without producing a new tagged release.

That combination is a warning for a team pinning a version, because you may be pinning a two and a half year old release while the repository moves.

## The client is built with an option pattern and every call takes a context

The usage section shows one pattern for everything. You construct a client with an API key, build a request struct, call a method with a context, and handle an error.

```go
package main

import (
	"context"
	"log"

	"github.com/kr/pretty"
	"googlemaps.github.io/maps"
)

func main() {
	c, err := maps.NewClient(maps.WithAPIKey("Insert-API-Key-Here"))
	if err != nil {
		log.Fatalf("fatal error: %s", err)
	}
	r := &maps.DirectionsRequest{
		Origin:      "Sydney",
		Destination: "Perth",
	}
	route, _, err := c.Directions(context.Background(), r)
	if err != nil {
		log.Fatalf("fatal error: %s", err)
	}

	pretty.Println(route)
}
```

The method returns three values, the response, something second, and the error, and the second return value is a response object that carries things like the API status. The context is passed in rather than hidden, so cancellation and timeouts work the way the rest of your Go code expects.

The geocoding example shows the same shape with a different request type and the reverse geocoding call.

```go
package main

import (
	"context"
	"log"

	"github.com/kr/pretty"
	"googlemaps.github.io/maps"
)

func main() {
	c, err := maps.NewClient(maps.WithAPIKey("Insert-API-Key-Here"))
	if err != nil {
		log.Fatalf("fatal error: %s", err)
	}
	r := &maps.GeocodingRequest{
		LatLng: &LatLng{Lat: 40.714224, Lng: -73.961452},
		EnableAddressDescriptor: True
	}
	reverseGeocodingResponse, _, err := c.ReverseGeocode(context.Background(), r)
	if err != nil {
		log.Fatalf("fatal error: %s", err)
	}

	pretty.Println(reverseGeocodingResponse)
}
```

As printed, that second sample does not compile. It references LatLng without a package qualifier even though LatLng lives in the maps package, and it sets EnableAddressDescriptor to True rather than the Go boolean true. It is worth knowing that before you copy it, and it is a fair signal to check the package documentation rather than the README sample when you are writing against a new field.

## Rate limiting is the feature that saves you from 429 responses

The rate limiting section describes a client that paces itself, and the pitch is blunt: never sleep between requests again.

By default, requests are sent at the expected rate limit for each web service, typically 50 queries per second for free users. The limit can be raised or lowered by passing an option when the client is created.

```go
c, err := maps.NewClient(maps.WithAPIKey(apiKey), maps.WithRateLimit(qps))
```

The implementation is visible in the module file. The only non-test dependency that is not a Google or testing library is golang.org/x/time, which is the rate limiting package. So the pacing is a token bucket or limiter inside the client rather than something the caller has to build.

For a Go service making many geocoding calls, this is the difference between a working integration and a stream of quota errors, and it is the sort of behaviour that is easy to leave to a library and hard to retrofit. The default of the API's expected per service rate means that a client created with only an API key will not exceed the quota on its own.

One caveat is implied rather than stated. Because the default is the expected limit for each web service, a service that talks to several of these APIs through one client shares whatever limiter it was given, so the per service figure may not hold for each one individually.

## OpenCensus metrics, and the option to bring your own reporter

The monitoring feature is small and specific. It is possible to get metrics for status counts and latency histograms, and the mechanism is OpenCensus.

The README shows the two pieces you need. The reporter is set with maps.WithMetricReporter(metrics.OpenCensusReporter{}), and metrics.RegisterViews() makes the metrics available to be exported, after which OpenCensus can send them to a variety of monitoring services.

The last sentence of that section is the useful one: you can also implement your own metric reporter instead of using the provided one. That matters more than it looks. OpenCensus is a project in maintenance mode rather than a growing one, so a library that hard-codes it would eventually become a liability, and a reporter interface lets a team plug in whatever metrics stack they are already running.

The dependencies confirm the shape. The module requires go.opencensus.io at v0.22.3, along with github.com/google/uuid, github.com/kr/pretty for the pretty printing in the samples, github.com/sergi/go-diff and github.com/stretchr/testify for the tests.

The native types feature sits alongside: native objects for each of the API responses, which is what latlng.go and types.go are for, so you get typed structs rather than a generic map to walk.

## Support terms are narrower than the API's own

The Terms of Service and Support sections say something that is easy to skim and important to a procurement conversation.

The library uses Google Maps Platform services, so any use of Google Maps Platform is subject to the Google Maps Platform Terms of Service. For clarity, the library and each underlying component is not a Google Maps Platform Core Service.

The support section is more pointed. The library is offered via an open source licence, and it is not governed by the Google Maps Platform Support Technical Support Services Guidelines, the SLA, or the Deprecation Policy, although any Google Maps Platform services used through the library remain subject to the platform Terms of Service.

In practice, that means the code is Apache-2.0, so you can read it, fork it and vendor it without restriction, and the licence file in the repository is the MIT style permissive licence with the Apache 2.0 terms. But you do not get a support contract with Google by depending on this library, and the deprecation policy that protects you as a platform customer does not apply to the client code itself.

The library does adhere to semantic versioning, which is what tells you when a backwards incompatible change is coming, and the repository uses a release configuration file alongside the semantic release tooling, so the version numbers in the tags mean something.

The repository also carries SECURITY.md, AUTHORS, CONTRIBUTORS, CONTRIB.md and a code of conduct, which is the standard set of files for a library that expects external contributions.

## When this library is the wrong choice

Three situations rule it out.

The first and largest is a new project. The README is explicit that as of October 2026, Places API Legacy, Directions API Legacy and Distance Matrix API Legacy can no longer be enabled for new Google Cloud projects. A team starting today cannot switch those endpoints on for the first time, and the library that wraps them will not gain the replacements. That is a hard boundary rather than a preference.

The second is a team that wants one client library across the whole Google Cloud surface. This library is scoped to the Maps web services, and the migration path it names lives in a different module, the maps subtree of google-cloud-go, with its own Places, Routes, Address Validation and Datasets packages. Adopting this library and the cloud client together means two API surfaces, two sets of types and two dependency trees in one service.

The third is a project with a strict dependency policy around abandoned things. The tagged releases date from December 2023, the module requires an OpenCensus version that is a fixed point rather than a moving one, and the README states the newer APIs will not be added here.

Where it still fits is the case the library was built for: an existing Go service that already has these legacy APIs enabled, that wants rate limiting and typed responses without writing them, and that has no immediate plan to migrate. For that service, the library is a small, permissive, well tested dependency that does one job.

## Conclusion

google-maps-services-go fits an existing Go service that still calls the legacy Maps web services, since it handles rate limiting, response types and metrics in a small Apache-2.0 library, and the legacy APIs remain fully supported for projects that already have them enabled. It is the wrong choice for a new project, because the three APIs this library centres on cannot be enabled for new Google Cloud projects as of October 2026, and its README says the newer APIs will not be added here. Before adopting it, check whether your project can still enable the legacy endpoints, and if you are starting fresh, start from the Google Maps Platform Cloud Client Library for Go instead.

## FAQ

### How do I install the Google Maps Go client?

Run go get googlemaps.github.io/maps. The module path is googlemaps.github.io/maps, the README states a requirement of Go 1.7 or later while the module file declares go 1.14, and you need an API key from a project with the relevant APIs enabled.

### Can I still use the Places, Directions and Distance Matrix APIs with this client?

Only from an existing project. The README states that Places API (Legacy), Directions API (Legacy) and Distance Matrix API (Legacy) can no longer be enabled for new Google Cloud projects as of October 2026, while existing projects remain fully supported, and that the newer APIs will not be added to this client library.

### How does rate limiting work in google-maps-services-go?

By default the client sends requests at the expected rate limit for each web service, typically 50 queries per second for free users, and the rate can be set with maps.NewClient(maps.WithAPIKey(apiKey), maps.WithRateLimit(qps)). The limiter comes from golang.org/x/time.

### What monitoring does the Google Maps Go client provide?

Metrics for status counts and latency histograms, using OpenCensus. You set maps.WithMetricReporter(metrics.OpenCensusReporter{}) and call metrics.RegisterViews() to expose them, and you can implement your own metric reporter instead of using the provided one.

### Which library should I use for the newer Maps APIs?

The README points to the Google Maps Platform Cloud Client Library for Go, the maps subtree of google-cloud-go, which has packages for Places API (New), the Routes API, the Address Validation API and the Datasets API. The newer APIs will not be added to this client library.

## Sources

- [googlemaps/google-maps-services-go on GitHub](https://github.com/googlemaps/google-maps-services-go)
- [License: Apache-2.0](https://github.com/googlemaps/google-maps-services-go/blob/master/LICENSE)
- [Project website](https://pkg.go.dev/googlemaps.github.io/maps)
- [README](https://github.com/googlemaps/google-maps-services-go/blob/master/README.md)
- [Releases](https://github.com/googlemaps/google-maps-services-go/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/googlemaps-google-maps-services-go
