Skip to content
How-to8 min read

How to Collect Google Street View Data at Scale with Official APIs

The official route starts with free metadata, then permitted image requests. At city scale, sampling, quota, cost, retries, QA and a traceable manifest become the real collection 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 explains the official collection method from pilot to city scale: how the endpoints differ, which parameters define the image, how to design a repeatable sampling frame, how billing and terms constrain storage, and when request orchestration, quality control and provenance become a production data pipeline rather than a short script.

Two endpoints, two jobs

What each Street View Static API endpoint is for
EndpointReturnsBilled as an image?
streetview/metadataJSON: status, snapped location, capture month, pano_id, copyrightNo. Google documents metadata as free of charge and as not consuming image quota.
streetviewA perspective JPEG at the size you requested, up to 640 × 640 pixelsYes. 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
Google Street View perspective of Fifth Avenue in New York, with buildings, a delivery truck, a yellow taxi and pedestrians
One billed JPEG from a real sample point on Fifth Avenue. The Static API returns this kind of perspective crop, not a downloadable equirectangular archive.

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

  1. A handful of sites: a thesis figure, a methods appendix, or a client sample of twenty points.
  2. A coverage-and-age check across a district, using metadata only, before anyone spends on images.
  3. 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.

More from the blog

Keep reading

Next step

Need this done rather than explained?

If the article describes a problem you are facing, tell us the specifics and we will scope it with a fixed price.