How to Get Google Street View Imagery Through the Official API
The official route is two HTTP endpoints: a free metadata check, then a billed JPEG for each heading you need. That is enough for a pilot. A city-scale sample is a different job.
- Author
- HuiTu Technology
- Published
- Updated
If you need Google Street View as data — not as a map you pan by hand — the supported way is the Street View Static API. It is an HTTP image service: you send a location and camera parameters, Google returns a JPEG. There is no documented bulk-export of raw 360° files, and there is no licence to scrape the consumer Street View website.
This article covers the official method for a small, well-defined sample: how the two endpoints differ, which parameters actually change the picture, how billing and terms constrain storage, and where a handful of requests stops being the right tool.
Two endpoints, two jobs
| Endpoint | Returns | Billed as an image? |
|---|---|---|
| streetview/metadata | JSON: status, snapped location, capture month, pano_id, copyright | No. Google documents metadata as free of charge and as not consuming image quota. |
| streetview | A perspective JPEG at the size you requested, up to 640 × 640 pixels | Yes. Each successful image request is a billed Static Street View panorama. |
Always run metadata first. If status is not OK, there is nothing to fetch, and you should not pay for a grey placeholder. When you do request an image, set return_error_code=true so a miss comes back as an HTTP error instead of a generic grey frame that a pipeline will happily save.
The parameters that define one picture
An image request is a URL. Required pieces are an API key, a size, and either a location (address or latitude,longitude) or a panorama id. Optional camera controls decide what the JPEG actually shows.
- location or pano: the search origin. With coordinates, the API looks within a radius (default 50 m) for the nearest panorama. Panorama ids change over time; store coordinates, not ids, if you need to refresh later.
- size: width × height in pixels, maximum 640 × 640 on this API.
- heading: compass direction, 0–360. Four headings (0°, 90°, 180°, 270°) are the usual research pattern so one camera angle does not decide how green or how enclosed a street looks.
- fov: horizontal field of view, default 90, maximum 120. Smaller values look more zoomed in.
- pitch: tilt relative to the vehicle, default 0. Keep it near horizontal unless you have a reason; a slight upward tilt inflates sky share.
- source=outdoor: skip indoor panoramas that sit near a street sample.
- signature: a digital signature on the URL. Google recommends it; some billing plans require it.
import os
from urllib.parse import urlencode
import requests
KEY = os.environ["GOOGLE_MAPS_API_KEY"] # never hard-code a key
META = "https://maps.googleapis.com/maps/api/streetview/metadata"
IMAGE = "https://maps.googleapis.com/maps/api/streetview"
def fetch_heading(lat, lon, heading, path):
"""Check coverage first, then request one billed perspective JPEG."""
meta = requests.get(
META,
params={"location": f"{lat},{lon}", "source": "outdoor", "key": KEY},
timeout=10,
).json()
if meta.get("status") != "OK":
return meta.get("status")
params = {
"location": f"{lat},{lon}",
"size": "640x640",
"heading": heading,
"fov": 90,
"pitch": 0,
"source": "outdoor",
"return_error_code": "true",
"key": KEY,
}
response = requests.get(IMAGE, params=params, timeout=20)
response.raise_for_status()
with open(path, "wb") as handle:
handle.write(response.content)
return "OK"
# Example: one sample point, four compass headings
# fetch_heading(40.7536, -73.9804, 0, "heading-000.jpg")
print(urlencode({"size": "640x640", "heading": 90})) # inspect query shape only

Billing and throughput
Image requests are pay-as-you-go under the Static Street View SKU. Metadata is a separate SKU that Google lists as free. There is a documented usage cap of 30,000 queries per minute; for a research script the binding constraint is usually cost and the terms, not that cap. Enable billing, keep the key in an environment variable, and put a daily quota in Google Cloud so a loop cannot run away.
What this method is good for
- A handful of sites: a thesis figure, a methods appendix, or a client sample of twenty points.
- A coverage-and-age check across a district, using metadata only, before anyone spends on images.
- A four-heading pack per point so a segmentation model sees a comparable street, not a single lucky angle.
At that scale you can run the official API yourself: one key, a CSV of coordinates, metadata, then images. The work is mostly sampling design and not mixing capture months.
When you need it at city scale
A metro road network sampled every 25 metres, four headings each, is tens or hundreds of thousands of image requests, plus retries, grey-image checks, coordinate snapping, vintage control and a manifest that ties every number back to a source image. That is no longer a weekend script. It is a collection job: quota and billing, sampling geometry, licence-aware storage, and validation before analysis starts.
Related services