Project Sidewalk

Welcome back

Project Sidewalk

Join Project Sidewalk

Map sidewalks. Help make your city accessible to everyone.

3–30 characters — letters, numbers, hyphens, and underscores

Pick a nickname — you don't have to use your real name. It's shown publicly on the leaderboard and your profile, and you can change it anytime.

  • At least 8 characters
  • One uppercase letter
  • One lowercase letter
  • One number
Passwords match

Sidewalk Presence API

Experimental. This endpoint is new and its data is inferred from crowdsourced labels, not surveyed. The inference has been measured against a ground-truth sidewalk inventory in one city (Seattle; see how it is inferred) and will perform differently elsewhere. Field names, enum values, and the inference rule may change as we learn, and because the /v3 API is a preview surface, such changes are made in place rather than under a new version.

Use it to explore and to compare, and pin your expectations if you build on it.

The Sidewalk Presence API says, for each side of each street, whether Project Sidewalk's labels indicate a sidewalk is there. The unit is a block face: one side of one street segment. Every street segment yields two records, left and right, both carrying the segment's geometry, so a consumer can draw the two verdicts side by side or roll them up however suits.

The verdict comes from the NoSidewalk labels our contributors place, resolved to a side of the street using each label's position relative to the street's centerline. It is inferred, not surveyed: treat it as a strong prior with a stated confidence rather than ground truth, and see how it is inferred for what the confidence means.

Street geometry and way_type come from OpenStreetMap and are © OpenStreetMap contributors, available under the Open Database License.

How it is inferred

Each face gets one of three verdicts, and a presence_basis saying which evidence produced it. The rules are tried in this order and the first that applies wins:

  1. absent from no_sidewalk_labels: at least one NoSidewalk label sits on this side of the street. The label count is the confidence, and no_sidewalk_label_count carries it.
  2. absent from other_side_tag: this side has no NoSidewalk label, but the other side has one tagged street has no sidewalks.
  3. present from audited_no_labels: the street has been audited (virtually walked) at least once and nobody placed a NoSidewalk label on this side.
  4. unknown from unaudited: the street has never been audited, so the absence of a label means nothing.

Obstacle and SurfaceProblem labels never override a NoSidewalk label. On a face without a sidewalk they describe the roadway people walk in (a parked car, gravel, a bin), not a sidewalk. Curb ramp labels are corner features whose side is ambiguous and are not used as evidence either way. A label within a meter of the street's centerline has no side and does not count.

Contributors whose work Project Sidewalk has flagged as unreliable count for nothing here: neither their labels nor their audits, so they can neither call a face absent nor, by way of an audit with no labels, call one present. This is the same population the rest of the APIs report on.

We measured this rule against Seattle's per-face sidewalk inventory (about 41,000 audited faces). The figures are for Seattle and will differ elsewhere, but they are the best available guide to what each tier means:

Verdict and evidence Precision Recall
absent, 1 or more NoSidewalk labels on the face69%79%
absent, 2 or more (minNoSidewalkLabels=2)80%67%
absent, 3 or more (minNoSidewalkLabels=3)84%55%
absent from the other side's tag only78%
present, audited with no NoSidewalk label96%93%

Pooling NoSidewalk labels per street rather than per side, which is how AccessScore currently treats them, is right on only 56% of its "no sidewalk" calls, because most streets that lack a sidewalk lack it on one side only. Divided roads and arterials are the weakest class: labels placed from a median can read as a missing sidewalk on the far side.

The table behind this endpoint is rebuilt nightly, so a label placed today appears here tomorrow.

Sidewalk Presence API Preview

Below is a live preview of sidewalk presence for a sample region in Madison, WI, retrieved directly from the API. Each street is drawn twice, its left and right side offset to either side of the centerline and colored by verdict. Hover and click a side to see the evidence behind its verdict and what the other side says.

Note: This preview shows a single region; the API can return every street in the city or just a selected region or bounding box. See the API Query Parameters below.

Endpoint

Retrieves one record per block face (street side), optionally filtered by the Query Parameters below.

GET /v3/api/sidewalkPresence

Examples

/v3/api/sidewalkPresence?filetype=geojson Get every street side in GeoJSON format (default)

/v3/api/sidewalkPresence?filetype=geojson&inline=true The same, opened in the browser

/v3/api/sidewalkPresence?filetype=csv Get every street side in CSV format

/v3/api/sidewalkPresence?presence=absent Only the sides called absent

/v3/api/sidewalkPresence?presence=absent&minNoSidewalkLabels=2 Only absent calls backed by two or more labels (the 80% tier)

/v3/api/sidewalkPresence?presence=present,absent Every audited side, leaving out the unknowns

/v3/api/sidewalkPresence?wayType=residential&minAuditCount=2 Residential streets audited at least twice

/v3/api/sidewalkPresence?status=open Only streets currently open for auditing, leaving out closed neighborhoods and streets without imagery

Quick Download

Download sidewalk presence data directly in your preferred format:

Generating your download...
This may take anywhere from a few seconds to a few minutes depending on the data size.

Note: This downloads every street side in the city — including the unknowns, and including streets that are not currently open for auditing (each carries a status). For filtered data, use the API Query Parameters described below.

Query Parameters

Filter the street sides returned by this endpoint using the following query parameters. All parameters are optional. Combine multiple filter parameters to narrow down results (filters are applied using AND logic).

Note: When multiple location filters are provided (bbox, regionId, and regionName), bbox takes precedence over region filters, and regionId takes precedence over regionName.

Parameter Type Description
bbox string Filter by bounding box, keeping the sides of every street that intersects it. Coordinates should be provided as a comma-separated string in the format: minLongitude,minLatitude,maxLongitude,maxLatitude (e.g., -74.01,40.71,-74.00,40.72). Uses WGS84 (EPSG:4326) coordinates. If omitted, results are not spatially filtered (potentially very large response).
regionId integer Filter by region ID. Returns only the sides of streets within the specified region. Note: If both bbox and regionId are provided, bbox takes precedence.
regionName string Filter by region name. Note: If bbox or regionId are provided, they take precedence over regionName.
presence string Keep only the given verdicts. Provide comma-separated values from present, absent, unknown (e.g., presence=present,absent for every audited side). By default all three are returned. Unrecognized values return a 400 error.
minNoSidewalkLabels integer Keep only sides with at least this many NoSidewalk labels: the confidence dial for absent calls. 2 selects the 80%-precision tier and 3 the 84% tier (Seattle figures). Any value above 0 drops every side whose own NoSidewalk count is below it, which is every present and unknown side and also every absent side called from other_side_tag — those carry the evidence on the other face, so their own count is 0. To keep that tier alongside a filtered one, make two requests (presence=absent&minNoSidewalkLabels=2 and presence=absent&minNoSidewalkLabels=0 filtered on presence_basis) rather than one.
minAuditCount integer Keep only the sides of streets that have been audited (virtually walked) at least this many times. A present call on a street audited several times is stronger than one audited once.
wayType string Filter by one or more way types (road classifications, mostly following OSM's highway values), as comma-separated values (e.g., wayType=residential,primary). The types present in a given city are listed by the Street Types API; the full list of valid values is on the Streets API. Unrecognized values return a 400 error.
status string Filter by the street's availability in Project Sidewalk, as comma-separated values from open, no_imagery, closed, disabled (e.g., status=open). By default every status is returned, as on the Streets API. Unrecognized values return a 400 error.
filetype string Specify the output format. Options: geojson (default), csv, shapefile, geopackage.
inline boolean Whether to display the file inline or as an attachment. Default: false (attachment). Set to true to view data in the browser instead of downloading.

Responses

Success Response (200 OK)

On success, the API returns an HTTP 200 OK status code and the requested data in the specified filetype format.

GeoJSON Format (Default)

Returns a GeoJSON FeatureCollection where each feature represents one side of one street segment. The two sides of a segment carry the same LineString; street_side tells them apart. Coordinate Reference System (CRS) is WGS84 (EPSG:4326).

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "LineString",
        "coordinates": [
          [-122.3546715, 47.5309889],
          [-122.3546693, 47.5319025]
        ]
      },
      "properties": {
        "street_edge_id": 10425,
        "street_side": "left",
        "osm_way_id": 6479562,
        "region_id": 44,
        "region_name": "Highland Park",
        "way_type": "residential",
        "status": "open",
        "presence": "absent",
        "presence_basis": "no_sidewalk_labels",
        "no_sidewalk_label_count": 3,
        "no_sidewalk_user_count": 2,
        "label_count": 5,
        "audit_count": 2,
        "first_no_sidewalk_label_date": "2019-11-04T22:31:07Z",
        "last_no_sidewalk_label_date": "2023-02-18T17:05:44Z"
      }
    },
    {
      "type": "Feature",
      "geometry": {
        "type": "LineString",
        "coordinates": [
          [-122.3546715, 47.5309889],
          [-122.3546693, 47.5319025]
        ]
      },
      "properties": {
        "street_edge_id": 10425,
        "street_side": "right",
        "osm_way_id": 6479562,
        "region_id": 44,
        "region_name": "Highland Park",
        "way_type": "residential",
        "status": "open",
        "presence": "present",
        "presence_basis": "audited_no_labels",
        "no_sidewalk_label_count": 0,
        "no_sidewalk_user_count": 0,
        "label_count": 2,
        "audit_count": 2,
        "first_no_sidewalk_label_date": null,
        "last_no_sidewalk_label_date": null
      }
    },
    ...
  ]
}
GeoJSON Field Descriptions

Each feature in the GeoJSON response represents one side of one street segment, with the segment's LineString geometry and these properties:

Field Path Type Description
geometry.coordinates array[number] Array of coordinate pairs forming the street segment's path, in [longitude, latitude] format using WGS84 (EPSG:4326). Identical for the segment's two sides.
properties.street_edge_id integer Project Sidewalk's unique identifier for the street segment. Shared by the segment's two sides; the pair (street_edge_id, street_side) identifies a face.
properties.street_side string left or right, relative to the direction the geometry's coordinates run in (its digitized direction), not to a compass bearing: walking the segment from its first coordinate to its last, left is on your left. This is the same convention as street_side on the Raw Labels API.
properties.osm_way_id integer OpenStreetMap Way ID for the street segment.
properties.region_id integer Identifier for the region where the street segment is located.
properties.region_name string Name of the region where the street segment is located, as defined in Project Sidewalk's regions.
properties.way_type string OpenStreetMap classification of the road type (e.g., residential, primary, secondary, service, footway).
properties.status string Whether the street is available for auditing in Project Sidewalk: open, no_imagery (no street view coverage), closed (in a neighborhood that has not been opened, or has been hidden), or disabled. Non-open streets still carry a verdict, since labels may predate the change. A closed street's region_id may name a neighborhood the Regions API does not return; filter with status=open if you are joining the two.
properties.presence string The verdict for this side: present, absent, or unknown. unknown means the street has never been audited, not that there is no sidewalk.
properties.presence_basis string The evidence behind the verdict, one of no_sidewalk_labels (absent: NoSidewalk labels on this side), other_side_tag (absent: the other side's label is tagged "street has no sidewalks"), audited_no_labels (present: audited, no NoSidewalk label here), or unaudited (unknown). See how it is inferred.
properties.no_sidewalk_label_count integer Number of NoSidewalk labels on this side of the street. The confidence behind an absent call; always 0 for present and unknown.
properties.no_sidewalk_user_count integer Number of distinct contributors who placed those NoSidewalk labels. A call backed by one contributor is weaker than one several contributors agree on.
properties.label_count integer Number of labels of any type on this side of the street (labels within a meter of the centerline have no side and are not counted on either).
properties.audit_count integer Number of completed audits of the street segment. Shared by its two sides.
properties.first_no_sidewalk_label_date string Timestamp of the first NoSidewalk label on this side, in ISO 8601 format. null when there are none.
properties.last_no_sidewalk_label_date string Timestamp of the most recent NoSidewalk label on this side, in ISO 8601 format. null when there are none.

CSV Format

If filetype=csv is specified, the response body will be CSV data. The first row contains the headers, corresponding to the fields in the GeoJSON properties object, plus geometry representation. CRS is WGS84 (EPSG:4326).

street_edge_id,street_side,osm_way_id,region_id,region_name,way_type,status,presence,presence_basis,no_sidewalk_label_count,no_sidewalk_user_count,label_count,audit_count,first_no_sidewalk_label_date,last_no_sidewalk_label_date,start_point,end_point
10425,left,6479562,44,Highland Park,residential,open,absent,no_sidewalk_labels,3,2,5,2,2019-11-04T22:31:07Z,2023-02-18T17:05:44Z,"-122.3546715,47.5309889","-122.3546693,47.5319025"
10425,right,6479562,44,Highland Park,residential,open,present,audited_no_labels,0,0,2,2,,,"-122.3546715,47.5309889","-122.3546693,47.5319025"
...

Note: The complete LineString geometry is simplified to start and end points in the CSV format due to the tabular nature of CSV. For full geometry data, use the GeoJSON format.

Shapefile Format

If filetype=shapefile is specified, the response body will be a ZIP archive containing the Shapefile components (.shp, .shx, .dbf, .prj). The attribute table (.dbf) contains fields corresponding to the GeoJSON properties object, with names abbreviated to the format's ten-character limit (streetId, side, status, presence, basis, nsLabels, nsUsers, labelCount, auditCount, firstNsLbl, lastNsLbl). The included .prj file defines the Coordinate Reference System (CRS), WGS84 (EPSG:4326).

GeoPackage Format

If filetype=geopackage is specified, the response body will be a GeoPackage (.gpkg) file containing every street side with full geometry and the same field names as the GeoJSON properties. GeoPackage is a modern, open standard geospatial format that supports complex geometries and is widely supported by GIS software.

Error Responses

If an error occurs, the API will return an appropriate HTTP status code and a JSON response body containing details about the error.

  • 400 Bad Request: Invalid parameter values (e.g., malformed bounding box, invalid region ID, an unrecognized presence or wayType value).
  • 404 Not Found: The requested resource does not exist (e.g., incorrect base URL path).
  • 500 Internal Server Error: An unexpected error occurred on the server.

Error Response Body

All errors are returned as RFC 7807 “problem details” with the application/problem+json content type and the following structure:

{
  "type": "about:blank",          // RFC 7807 problem-type URI ("about:blank" means no type beyond the status)
  "title": "Invalid Parameter",   // Short, human-readable summary of the problem type (stable for a given code)
  "status": 400,                  // HTTP status code (also repeated in the body)
  "detail": "Invalid value for the bbox parameter. Expected format: minLng,minLat,maxLng,maxLat.", // This occurrence
  "code": "INVALID_PARAMETER",    // Stable, machine-readable error code you can branch on
  "parameter": "bbox"             // Extension member: the specific parameter at fault (omitted when not applicable)
}

Best Practices

When working with the Sidewalk Presence API, consider these recommendations:

  • Read unknown as unknown: it means nobody has audited the street, not that it has no sidewalk. Pass presence=present,absent to work with audited sides only.
  • Pick a confidence tier: a single NoSidewalk label is right about 7 times in 10; when precision matters more than coverage, filter with minNoSidewalkLabels=2 or weight by no_sidewalk_label_count and no_sidewalk_user_count yourself.
  • Sides are relative to the geometry: left and right follow the coordinate order of the LineString, so draw each side by offsetting the line in that frame (Mapbox GL's line-offset, for instance, is positive to the right of the line's direction) rather than by compass direction.
  • Treat divided roads with care: arterials with medians are the weakest class for this inference, since a label placed from the median can read as a missing sidewalk on the far side. Use wayType to set them aside if your analysis is sensitive to that.
  • Filter by status if you are joining on regions: the response covers every street, including those in neighborhoods that are closed or not yet opened. Those streets' region_id values are not among the ones the Regions API returns, so pass status=open when the two have to line up.
  • Combine with other APIs: the Raw Labels API returns the NoSidewalk labels behind each call, with their own street_side, tags, and validation results; the Streets API carries the street's audit history.

Contribute

Project Sidewalk is an open-source project created by the Makeability Lab and hosted on GitHub. We welcome your contributions! If you found a bug or have a feature request, please open an issue on GitHub.

You can also email us at sidewalk@cs.uw.edu

Project Sidewalk in Your City!

If you are interested in bringing Project Sidewalk to your city, please read our Wiki page.

On This Page