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

AccessScore: Spotlight API

The AccessScore: Spotlight API returns the highest- and lowest-scoring neighborhoods, or streets, in Amsterdam, Netherlands — the feed behind the AccessScore Spotlight module on the home page and on /cities. It answers from a snapshot written once a night, at the end of the label-clustering run, so asking for it never sets a whole city's AccessScore recomputing.

This endpoint returns JSON only. It is a page feed rather than a data export: the scores it ranks are downloadable in every format from the AccessScore: Regions API and the AccessScore: Streets API.

One method, not the method. There is no single correct way to measure street- and neighborhood-level accessibility. AccessScore implements one experimental algorithm, and a ranking built on it reflects what volunteers have found so far rather than an official assessment. Read qualifying and total alongside the lists: in most cities only part of the map has enough data to be ranked at all.

Endpoint

GET /v3/api/accessScoreSpotlight

Examples

/v3/api/accessScoreSpotlight The top and bottom 5 neighborhoods in this city

/v3/api/accessScoreSpotlight?unit=streets The top and bottom 5 streets

/v3/api/accessScoreSpotlight?unit=regions&n=10 Ten rows in each list

/v3/api/accessScoreSpotlight?scope=cities The same ranking across every publicly launched Project Sidewalk city

What gets ranked

A score only describes the part of a place that volunteers have actually looked at, so a unit has to clear a bar before it is ranked anywhere.

  • Neighborhoods need a score and at least min_completion of their street length explored — the same distance-based completion the home page's choropleth colors, published as min_region_completion by the AccessScore configuration. The AccessScore tool applies the same floor, so the two can never disagree about who is ranked.
  • Streets are grouped by OSM way within a neighborhood, because a street edge is one block of a way and a list of edges would print the same street name a dozen times. Each row is that named stretch: its score is the length-weighted mean of its explored edges, and its street_edge_id is the longest edge in the group. A stretch is ranked once it has been explored, is at least 100 m long, and carries either three or more label clusters or none at all — a confirmed absence of problems is a finding, while one or two clusters on a long street says little either way.

Streets that score alike are ordered by how many validations their labels have received (the best-checked first), then by a random number drawn once per nightly run, so a list of equal scores stays in one order for the day rather than reshuffling between two page loads.

Query Parameters

All parameters are optional.

ParameterTypeDescription
unit string What to rank: regions (default) or streets.
n integer How many rows each list holds, 1–25. Default: 5.
scope string cities ranks across every publicly launched Project Sidewalk deployment and stamps each row with the city it came from. Omitted, the ranking covers this city alone.

Responses

Success Response (200 OK)

{
  "unit": "regions",
  "min_completion": 0.8,
  "min_street_length_m": 100,
  "highest_min_score": 0.5,
  "lowest_max_score": 0.5,
  "qualifying": 66,
  "total": 79,
  "computed_at": "2026-09-16T03:14:22Z",
  "top": [
    {
      "region_id": 281,
      "name": "Capitol Hill",
      "score": 0.842,
      "completion_rate": 0.97,
      "audited_distance_m": 128411.2,
      "total_distance_m": 132382.7,
      "cluster_count": 6120
    }
  ],
  "bottom": [
    {
      "region_id": 304,
      "name": "South Park",
      "score": 0.313,
      "completion_rate": 0.88,
      "audited_distance_m": 41220.7,
      "total_distance_m": 46841.7,
      "cluster_count": 1493
    }
  ],
  "nearest": []
}

Field Descriptions

Field PathTypeDescription
unitstringWhich unit was ranked: regions or streets.
min_completionnumberThe share of a neighborhood's street length that must be explored before it is ranked, in [0, 1].
min_street_length_mnumberThe length a stretch of street must reach before it is ranked, in meters.
highest_min_scorenumberThe score a ranked unit needs to appear in top, in [0, 1].
lowest_max_scorenumberThe score a ranked unit must be under to appear in bottom, in [0, 1]. The two lists never overlap; a unit between the two bars, if they differ, is in neither.
qualifyingintegerHow many units cleared every bar and are therefore ranked.
totalintegerHow many units the city has in all.
computed_atstringThe nightly run that produced these rows, as the timestamp it stamped on every row it wrote (ISO 8601). null before the first run. Under scope=cities this is the oldest of the contributing cities' runs, so it is true of every row rather than only the freshest one.
toparrayWith n or more units ranked: the best of those scoring at least highest_min_score, best first — fewer than n rows when fewer clear it, and empty when none does. With fewer than n ranked there is no highest-and-lowest to show, so this holds every ranked unit, best first.
bottomarrayWith n or more units ranked: the worst of those scoring under lowest_max_score, worst first; empty otherwise. Never overlaps top.
nearestarrayNeighborhoods closest to the completion floor, best-explored first — the "help the next one across the line" list. Populated only when fewer than n units qualify, and only for unit=regions without scope=cities; empty otherwise.

Neighborhood Row

Field PathTypeDescription
region_idintegerProject Sidewalk's identifier for the neighborhood.
namestringThe neighborhood's name.
scorenumberIts AccessScore in [0, 1]; null when none of its streets has been explored (only ever seen in nearest).
completion_ratenumberThe share of its street length explored, in [0, 1].
audited_distance_mnumberHow much of that street length has been explored, in meters.
total_distance_mnumberIts whole street length in meters — the neighborhood's size, which the module prints under the name so a score can be weighed against it.
cluster_countintegerHow many label clusters the score is built from, on its streets and at its intersections: the evidence behind the number.

Street Row

Field PathTypeDescription
osm_way_idintegerThe OSM way the stretch belongs to.
street_edge_idintegerThe longest street edge in the group, which is what the AccessScore tool's ?sel= opens on.
region_idintegerThe neighborhood the stretch lies in.
region_namestringThat neighborhood's name.
namestringThe way's OSM name; null for an unnamed way.
scorenumberLength-weighted AccessScore of its explored edges, in [0, 1].
length_mnumberThe whole stretch's length in meters, explored or not.
cluster_countintegerScored label clusters along it, the evidence behind the score.
validation_countintegerValidations cast on its labels.

Cross-city Rows

With scope=cities, every row additionally carries city_id, city_name, and city_url — the deployment it came from and its public address. Only publicly launched cities are listed, and qualifying and total are the sums across them.

Error Responses

  • 400 Bad Request: An unknown unit, or an n outside 1–25.
  • 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

  • Print qualifying of total beside the lists. A top five drawn from six ranked neighborhoods means something quite different from one drawn from sixty.
  • Say when it was computed. These rows change once a night, so a label placed today moves them tomorrow — computed_at is what tells a reader that.
  • Drill down: use the AccessScore: Regions API and AccessScore: Streets API for the full, unranked scores and the per-type breakdowns behind them.

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