<br />

A collection of HTTP interfaces, the Google Maps Platform static web APIs
generate images for embedding directly on your web page.

The Google Maps Platform web services are a collection of HTTP interfaces
that provide geographic data for your maps applications.

This guide describes some common practices useful for setting up your image and
web service requests and processing service responses. For more information
about Street View Static API, see the [developer's guide](https://developers.google.com/maps/documentation/streetview/overview.md.txt).

The Street View Static API acts like a static web API, while the
metadata service acts as a web service. For more information about the
metadata service, see [Street View image metadata](https://developers.google.com/maps/documentation/streetview/metadata.md.txt).

## What is a static web API?

The Google Maps Platform static web APIs let you embed a Google Maps image in
your web page without requiring JavaScript or any dynamic page loading. The
static web APIs create an image based on URL parameters that are sent using a
standard HTTPS request.

A typical Street View Static API request has the following form:

```json
  https://www.googleapis.com/streetview/z/x/y?parameters
```

## What is a web service?

Google Maps Platform web services are an interface for requesting Maps API
data from external services and using the data within your Maps applications.
These services are designed to be used in conjunction with a map, according to
the
[License Restrictions](https://cloud.google.com/maps-platform/terms/#3.-license.)
in the Google Maps Platform Terms of Service.

The Maps APIs web services use HTTP or HTTPS requests to specific URLs, passing
URL parameters or JSON-format POST data as arguments to the services. Generally,
these services return data in the response body as JSON for parsing or
processing by your application.

A Street View Static API Metadata request is of the following form:

```
https://maps.googleapis.com/maps/api/streetview/parameters
```

> [!NOTE]
> **Note:** All Street View Static API applications require authentication. For more information, see [authentication credentials](https://developers.google.com/maps/documentation/streetview/get-api-key.md.txt).

## SSL and TLS access

HTTPS is required for all Google Maps Platform requests that use API keys or
contain user data. Requests made over HTTP that contain sensitive data might be
rejected.

## Building a valid URL

You may think that a "valid" URL is self-evident, but
that's not quite the case. A URL entered within an address bar in a
browser, for example, may contain special characters (e.g.
`"上海+中國"`); the browser needs to internally translate
those characters into a different encoding before transmission.
By the same token, any code that generates or accepts UTF-8 input
might treat URLs with UTF-8 characters as "valid", but would also need
to translate those characters before sending them out to a web server.
This process is called [URL-encoding](https://en.wikipedia.org/wiki/Query_string#URL_encoding) or [percent-encoding](https://en.wikipedia.org/wiki/Percent-encoding).

> [!CAUTION]
> **Caution** : Browsers and/or services may automatically URL-encode a request URI before sending. On APIs that use cryptographic request signing, this can potentially invalidate the signature, if URL-encoding alters the request after signing. To avoid this issue, *always* URL-encode your query string **before** signing the request.

### Special characters

We need to translate special characters because
all URLs need to conform to the syntax specified by the
[Uniform
Resource Identifier (URI)](http://tools.ietf.org/html/rfc3986) specification. In effect, this means that URLs
must contain only a special subset of ASCII characters: the familiar
alphanumeric symbols, and some reserved characters for use as control
characters within URLs. This table summarizes these characters:
Summary of Valid URL Characters

| Set | characters | URL usage |
|---|---|---|
| Alphanumeric | a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 | Text strings, scheme usage (`http`), port (`8080`), etc. |
| Unreserved | - _ . \~ | Text strings |
| Reserved | ! \* ' ( ) ; : @ \& = + $ , / ? % # \[ \] | Control characters and/or Text Strings |

When building a valid URL, you must ensure that it contains only those characters shown in the
table. Conforming a URL to use this set of characters generally
leads to two issues, one of omission and one of substitution:

- Characters that you wish to handle exist outside of the above set. For example, characters in foreign languages such as `上海+中國` need to be encoded using the above characters. By popular convention, spaces (which are not allowed within URLs) are often represented using the plus `'+'` character as well.
- Characters exist within the above set as reserved characters, but need to be used literally. For example, `?` is used within URLs to indicate the beginning of the query string; if you wish to use the string "? and the Mysterions," you'd need to encode the `'?'` character.

All characters to be URL-encoded are encoded
using a `'%'` character and a two-character hex
value corresponding to their UTF-8 character. For example,
`上海+中國` in UTF-8 would be URL-encoded as
`%E4%B8%8A%E6%B5%B7%2B%E4%B8%AD%E5%9C%8B`. The
string `? and the Mysterians` would be URL-encoded as
`%3F+and+the+Mysterians` or `%3F%20and%20the%20Mysterians`.

### Common characters that need encoding

Some common characters that must be encoded are:

| Unsafe character | Encoded value |
|---|---|
| Space | `%20` |
| " | `%22` |
| \< | `%3C` |
| \> | `%3E` |
| # | `%23` |
| % | `%25` |
| \| | `%7C` |

Converting a URL that you receive from user input is sometimes
tricky. For example, a user may enter an address as "5th\&Main St."
Generally, you should construct your URL from its parts, treating
any user input as literal characters.

Additionally, URLs are limited to 16384 characters for all Google Maps Platform web services
and static web APIs. For most services, this character limit will seldom be approached. However,
note that certain services have several parameters that may result in long URLs.

## Polite use of Google APIs

Poorly designed API clients can place heavy loads on the internet and on
servers. This section contains best practices for API clients. Following these
best practices can help prevent your application from being blocked for
inadvertent abuse of the APIs.

### Exponential backoff

In rare cases, something might go wrong with your request; you might receive a
4xx or 5xx HTTP response code, or the TCP connection might fail somewhere
between your client and Google's server. Often, it's worthwhile retrying the
request because the follow-up request might succeed when the original failed.
However, it's important not to repeatedly make requests to Google's servers.
This looping behavior can overload the network between your client and Google,
causing problems for many parties.

A better approach is to retry with increasing delays between attempts. The
delay typically increases by a multiplicative factor with each attempt, an
approach known as
[exponential backoff](https://en.wikipedia.org/wiki/Exponential_backoff).

For example, consider an application that makes this request to the
Time Zone API:

```
https://maps.googleapis.com/maps/api/timezone/json?location=39.6034810,-119.6822510&timestamp=1331161200&key=YOUR_API_KEY
```

The following Python example shows how to make the request with exponential
backoff:

```python
import json
import time
import urllib.error
import urllib.parse
import urllib.request

# The maps_key defined in the following code isn't a valid Google Maps API key.
# You need to get your own API key.
# See https://developers.google.com/maps/documentation/timezone/get-api-key
API_KEY = "YOUR_KEY_HERE"
TIMEZONE_BASE_URL = "https://maps.googleapis.com/maps/api/timezone/json"


def timezone(lat, lng, timestamp):

    # Join the parts of the URL together into one string.
    params = urllib.parse.urlencode(
        {"location": f"{lat},{lng}", "timestamp": timestamp, "key": API_KEY,}
    )
    url = f"{TIMEZONE_BASE_URL}?{params}"

    current_delay = 0.1  # Set the initial retry delay to 100ms.
    max_delay = 5  # Set the maximum retry delay to 5 seconds.

    while True:
        try:
            # Get the API response.
            response = urllib.request.urlopen(url)
        except urllib.error.URLError:
            pass  # Fall through to the retry loop.
        else:
            # If the request didn't produce an IOError, parse the result.
            result = json.load(response)

            if result["status"] == "OK":
                return result["timeZoneId"]
            elif result["status"] != "UNKNOWN_ERROR":
                # Many API errors can't be fixed by a retry, such as
                # INVALID_REQUEST or ZERO_RESULTS. Don't retry these requests.
                raise Exception(result["error_message"])

        if current_delay > max_delay:
            raise Exception("Too many retry attempts.")

        print("Waiting", current_delay, "seconds before retrying.")

        time.sleep(current_delay)
        current_delay *= 2  # Increase the delay on each retry.


if __name__ == "__main__":
    tz = timezone(39.6034810, -119.6822510, 1331161200)
    print(f"Timezone: {tz}")
```

Make sure that there isn't retry code higher in the application call chain that
leads to repeated requests in quick succession.

### Synchronized requests

Large numbers of synchronized requests to Google's APIs can look like a
distributed denial-of-service (DDoS) attack on Google's infrastructure, and be
treated accordingly. To avoid this issue, make sure that API requests aren't
synchronized between clients.

For example, consider an application that displays the time in the current time
zone. This application probably sets an alarm in the client operating system to
wake it up at the start of the minute so that the displayed time can be updated.
Don't make any API calls in the application as part of the processing associated
with that alarm.

Making API calls in response to a fixed alarm is bad because it results in the
API calls being synchronized to the start of the minute, even between different
devices, rather than being distributed evenly over time. A poorly designed
application doing this generates a spike of traffic at 60 times normal levels at
the start of each minute.

Instead, you can design the application to have a second alarm set to a
randomly chosen time. When this second alarm fires, the application calls any
APIs it needs and stores the results. When the application updates its display
at the start of the minute, it uses previously stored results rather than
calling the API again. With this approach, API calls spread evenly over time.
Further, the API calls don't delay rendering when the display updates.

Aside from the start of the minute, don't target other common synchronization
times, such as the start of an hour and the start of each day at midnight.

## Processing responses

Because the exact format of individual responses to a web service request isn't
guaranteed---some elements might be missing or in multiple locations---don't assume
that the format returned for any given response is the same for different
queries. Instead, process the response and select appropriate values by
using expressions.

This section discusses how to extract these values dynamically from web service
responses.

The Google Maps web services provide responses that are understandable, but not
user-friendly. When performing a query, rather than display a set of data, you
probably want to extract a few specific values. Generally, parse responses from
the web service and extract only those values that interest you.

The parsing scheme you use depends on whether you're returning output in JSON.
JSON responses, being already in the form of JavaScript objects, can be
processed within JavaScript itself on the client.