AccessScore: Streets API #
The AccessScore: Streets API returns an accessibility score in the range (0, 1) for each street — higher is more accessible. A street's score combines three things: its own segment, scored from the obstacles, surface problems, and missing sidewalks along it, and the intersections at its two ends, scored from the curb ramps, crosswalks, and signals pooled at each corner (see the AccessScore: Intersections API). Each piece weights every clustered feature by its type, its severity/quality rating, and its tags, then squashes the total with a logistic function.
AccessScore extends the method introduced in Li et al., A Pilot Study of Sidewalk Equity in Seattle (Urban Access 2022). It is experimental: the weights are deliberately simple and subject to change. For full control you can compute your own index from the Label Clusters API.
AccessScore: Streets Preview #
Below is a live preview of street AccessScores from a sample region in Walla Walla, WA, retrieved directly from the API. Streets are colored from red (low accessibility) to green (high); gray streets have not yet been audited. Hover or click a street to see its score and the accessibility features that produced it.
One method, not the method. There is no single correct way to measure street-level accessibility—researchers and practitioners use many different approaches. AccessScore implements just one such algorithm, and it is experimental: the weighting is deliberately simple and subject to change. Treat these scores as one lens rather than a definitive measure, and compute your own index from the Label Clusters API if a different method suits your needs better.
Endpoint#
Returns a street segment and its AccessScore for each street in the queried area, optionally filtered by the Query Parameters below.
GET /v3/api/accessScoreStreets
Examples#
/v3/api/accessScoreStreets?filetype=geojson Get AccessScores for all streets in GeoJSON (default)
/v3/api/accessScoreStreets?filetype=geojson&inline=true Same, but opened in the browser
/v3/api/accessScoreStreets?filetype=csv Get AccessScores for all streets in CSV
/v3/api/accessScoreStreets?regionId=8 Get scores for streets in a single region
How the score is computed#
Project Sidewalk clusters proximal labels of the same type, and scores two kinds of unit from them: a street's segment and an intersection. Four of the seven scored label types are corner features — CurbRamp, NoCurbRamp, Crosswalk, Signal — so each of their clusters is attributed to the nearest intersection within 25 m (on whichever street it sits) and scores that intersection, pooled with the corner features of every other street meeting there. The rest of the street's clusters score its segment: the along-length types (Obstacle, SurfaceProblem, NoSidewalk), plus any corner-type cluster too far from an intersection to belong to one (a mid-block crosswalk and the curb ramps serving it), which counts as an ordinary point feature.
A street's headline score is the plain mean of its segment_score and the scores of its start and end intersections, over whichever of the three exist — a trip along a street includes getting on and off it. An end with no intersection (a dead end, a street split at a region boundary) or a grade-separated one contributes nothing, and an unaudited street between two scored crossings still gets a headline from them. All three components are reported, so you can recombine them your own way.
Scoring a segment. Each scored label type contributes a signed term; the segment's score is the logistic (sigmoid) of the sum of those terms, mapped to (0, 1). An audited street with nothing on it scores the neutral 0.5.
Most types are scored per cluster. Each cluster contributes base(type) × ratingMultiplier + Σ tagAdjustments, and the type's term is the sum over its clusters on the street:
- Positive, quality-rated (CurbRamp, Crosswalk): rated Good / Okay / Bad → multiplier
+1.0 / +0.5 / −1.0. A Bad feature therefore lowers the score. - Negative, severity-rated (NoCurbRamp, Obstacle, SurfaceProblem): rated Low / Medium / High → magnitude
0.33 / 0.67 / 1.0of the (negative) base. - Presence-only (Signal): no rating; each cluster adds the base weight as-is.
- Tags adjust a cluster's weight when present on at least half of its labels — e.g. a Signal tagged hard to reach buttons counts negatively, while APS (accessible signal) counts positively.
- Length normalization (Obstacle, SurfaceProblem): these describe problems along a street, so their terms are scaled to a density per 100 m —
term × 100 / max(length_meters, 25). Three obstacles on a 300 m street score as one on a 100 m street; a long street is not penalized for having more room for problems. The 25 m floor keeps a stub of a street from multiplying one problem without bound, so the factor never exceeds 4.
NoSidewalk is scored once per street, as a street condition, rather than per cluster. A missing sidewalk is a stretch, not a point: labelers pin it repeatedly along the street and it is clustered at 10 m, so a per-cluster weight would measure how many pins were dropped instead of whether the street has a sidewalk. All of a street's NoSidewalk clusters pool into a single term, which is what score_no_sidewalk reports:
score_no_sidewalk = base × min(1, n / 3) + Σ tagAdjustments
nis the street's NoSidewalk cluster count (n_no_sidewalk). The extent factormin(1, n / 3)saturates at 3 clusters: one stray pin counts1 / 3of the base weight, and 3 or more count the full weight however many more there are.- Known limitation. A cluster count is a proxy for coverage, and NoSidewalk clusters at 10 m, so how readily a street reaches 3 clusters depends on how long it is. A very short street without a sidewalk can be structurally unable to saturate, and so scores somewhat higher than a long street in the same condition. Pooling removes this effect above saturation but not below it.
- Street-wide tags are judged over the street's pooled NoSidewalk labels: a tag adjusts the term when at least half of those labels carry it. street has no sidewalks and street has a sidewalk (the other side of the street has one) are mutually exclusive, so at most one is active unless the labels split exactly in half, in which case they cancel.
- ends abruptly marks the point where a sidewalk stops, so it is active when any single cluster carries it on at least half of that cluster's labels. It aggravates the score: a pedestrian on the sidewalk is stranded in the roadway where it ends.
- Worked example (current weights, before the street's other features): a street with eight NoSidewalk clusters and no tags scores
sigmoid(-2.00) ≈ 0.12; tagged street has no sidewalks it drops tosigmoid(-3.00) ≈ 0.05; tagged street has a sidewalk it rises tosigmoid(-1.00) ≈ 0.27. A single NoSidewalk cluster with no tags issigmoid(-0.67) ≈ 0.34.
The base weights and tag adjustments below are read directly from the scoring engine, so they always match what the API computes:
| Label type | Base weight | Rating | Tag adjustments |
|---|---|---|---|
CurbRamp |
+0.75 |
Quality (Good / Okay / Bad) |
missing tactile warning
-0.25narrow
-0.25points into traffic
-0.25steep
-0.25 |
NoCurbRamp |
-1.00 |
Severity (Low / Medium / High) |
alternate route present
+0.25no alternate route
-0.50 |
Obstacle |
-1.00 |
Severity (Low / Medium / High) | — |
SurfaceProblem |
-1.00 |
Severity (Low / Medium / High) | — |
Crosswalk |
+0.75 |
Quality (Good / Okay / Bad) |
level with sidewalk
+0.25no pedestrian priority
-0.25paint fading
-0.25 |
Signal |
+0.50 |
Presence only, per cluster |
APS
+0.25button waist height
+0.15hard to reach buttons
-0.25 |
NoSidewalk |
-2.00 |
Street condition: one pooled term per street |
covered walkway
+0.50ends abruptly
-1.00gravel/dirt road
-0.25pedestrian lane marking
+0.50shared pedestrian/car space
+0.25street has a sidewalk
+1.00street has no sidewalks
-1.00 |
The per-type cluster_counts and sub_scores in each response let you see exactly how a street's segment was composed: the sub_scores sum to logit(segment_score). A corner type appearing there is a mid-block cluster; the ones at the corners are on the intersections. Other label types (Occlusion, Other) do not affect the score.
Note: Region scores (see the AccessScore: Regions API) are the length-weighted mean of their streets' headline scores, alongside a plain mean of their intersections.
Recomputing the score under your own weights#
Every street carries the inputs to its score, so you can re-weight it yourself. GET /v3/api/accessScoreConfig returns the engine's configuration — the scored types in order, each type's base weight and scoring mode, the rating multipliers per bucket, the tag adjustments, the street-condition saturation count, and a few named weight presets — as JSON:
GET /v3/api/accessScoreConfig
Then, per street, each type's segment term is rebuilt from severity_counts, tag_adjustments, and length_meters:
- Per-cluster types (
positive_quality,negative_severity,presence_only):term = weight × Σbucket severity_counts[type][bucket] × multiplier(bucket) + tag_adjustments[type], where the multiplier comes fromquality_multiplierorseverity_multiplierby scoring mode, and is1forpresence_only. - Street-condition types (
street_condition):term = weight × min(1, n / street_condition_saturation_count) + tag_adjustments[type], withnthe type's total cluster count. - Length-normalized types (
length_normalizedis true): multiply the whole term bylength_normalization.per_meters / max(length_meters, length_normalization.min_length_meters). segment_score = sigmoid(Σtype term + grade_term). With the engine's ownbase_weightfor everyweight, the terms equalsub_scoresand, with the street's publishedgrade_term, the result equalssegment_score. To score the labels alone, drop thegrade_term.- An intersection is rebuilt the same way from its own
severity_countsandtag_adjustments, with no length factor; the street's headlinescoreis then the mean ofsegment_scoreand the scores ofstart_intersection_idandend_intersection_id, over those that are notnull.
Its grade object is what reads the grade fields: the two limits (walking_surface_limit, ramp_limit), the grades a map of them is classed at (map_class_breaks), and under sources the credit for each elevation model this city's streets were sampled from, with how many streets each covers.
The grade_scoring object publishes the settings the served scores were computed under, as defaults: a weight of 1.0 on max_grade, ramping between the two limits. That is the grade_term each street carries. To apply settings of your own, recompute the term and put it in that one's place in the sum above, grade_term = −weight × units:
- Which streets take part. A street with no grade at all (a bridge, a gap, an unsampled street) takes no grade term. Neither does one whose grade is approximate, meaning
grade_confidenceis"low"orgrade_qualityis"suspect"(both are a straight line between the street's ends), unlessinclude_approximateis set. The same gate applies to the barrier. mean_gradeandmax_gradestatistics:units = clamp((grade − low_threshold) / (high_threshold − low_threshold), 0, 1), wheregradeis that field, or|net_grade|on any street where the field isnullandnet_gradeis not. Ifhigh_threshold ≤ low_thresholdthere is no ramp between them andunitsis a step:1whengrade > low_threshold, else0.meters_over_limitstatistic:units = clamp((meters_over_5pct + meters_over_8pct) / (2 × length_meters), 0, 1), with anulllength counted as0. The thresholds do not move it: those lengths were measured against the two fixed limits when the street was sampled.- Barrier: with
barrier_enabled, a street whosemax_grade(or|net_grade|where that isnull) is greater thanbarrier_thresholdhas asegment_scoreof0outright. Its headlinescorestill averages that0with its end intersections.
statistics lists the statistic ids, and weight_range and threshold_range what a control may sensibly offer. An unaudited street has a grade and still has no score.
The response also carries clusters_updated_at: when the nightly clustering run that every score is computed from last finished (ISO 8601, or null before the first run). Labels added after that moment are not in any cluster yet and cannot have changed a score until the next run.
The presets object holds named weight vectors (magnitudes; a type's sign is fixed by its base weight): default is the engine's own weights, barriers weighs problem types half again as much, infrastructure does the same for feature types, and missing_ramps doubles missing curb ramps. They are named by what they change, not by whom they are for — a weighting that claims to represent a disability community would need that community's involvement and the literature behind it — and every value is published, so a lens hides nothing.
Street grade#
This API says grade for a street's steepness along its length, the running grade of its centerline, and never slope, which accessibility standards also use for a sidewalk's cross slope: that tilt across the walking surface cannot be measured from a centerline and is not reported.
Every street also carries its running grade, sampled along its centerline from a bare-earth elevation model. Grade needs no labeling, so it is there for unaudited streets too, and it is part of the score: a street steep enough to pass the walking-surface limit carries a negative grade_term, which is the one part of segment_score that sub_scores does not explain. A street with no sampled grade — including every street in a city whose grades have not been imported — carries a grade_term of 0 and is scored from its labels alone. Recomputing the score says how to weigh grade differently, or out. The street is the right thing to measure: PROWAG R302.4.1 caps a pedestrian route at 5% except where the adjacent street is steeper, in which case the sidewalk may match the street. Cross slope cannot be recovered from a centerline sample and is not reported.
A bare-earth model removes bridges and knows nothing of tunnels, so a street on a structure reports grade_quality: "structure" and no grade, not the grade of the ravine beneath it. The grade of a bridge deck is out of reach of any such model. One street's elevation profile, the one grade field too heavy for a city-wide file, is served by the Street Grade API.
Elevation model credits#
Each street names the model it was sampled from in dem_source. If you publish the grade fields, credit the model as below, and cite it where you would cite data; /v3/api/accessScoreConfig lists the ones this city uses under grade.sources, with the same credit lines and citations. How the grades are sampled from the model, and how accurate they are, is on the Street Grade API page. A city sampled from rasters that are not in this table yet is credited by its dem_source alone.
dem_source | Elevation model | Credit | Licence | Citation |
|---|---|---|---|---|
usgs-3dep-10m |
USGS 3DEP 1/3 arc-second seamless DEM | Elevation: U.S. Geological Survey, 3D Elevation Program | Public domain | U.S. Geological Survey, 2024, 1/3rd arc-second Digital Elevation Models (DEMs) - USGS National Map 3DEP Downloadable Data Collection: U.S. Geological Survey. |
Quick Download #
Download street AccessScore data directly in your preferred format:
Note: This downloads scores for all streets. For filtered data, use the API Query Parameters described below.
Query Parameters#
All parameters are optional.
Note: When multiple location filters are provided (bbox, regionId, and regionName), bbox takes precedence over region filters, and regionId takes precedence over regionName. A region filter is resolved to the region's bounding box, and the streets are then trimmed back to that region.
| Parameter | Type | Description |
|---|---|---|
bbox |
string |
Filter by bounding box, as minLongitude,minLatitude,maxLongitude,maxLatitude (e.g., -74.04,40.88,-74.00,40.91), WGS84 (EPSG:4326). If omitted, the city's default bounding box is used. |
regionId |
integer |
Score only streets within the region with this id. Takes precedence over regionName; bbox takes precedence over both. |
regionName |
string |
Score only streets within the region with this name. Used only when bbox and regionId are absent. |
filetype |
string |
Output format. Options: geojson (default), csv, shapefile, geopackage. |
inline |
boolean |
Whether to display the file inline rather than as an attachment. Default: false. |
Responses#
Success Response (200 OK)#
On success, the API returns 200 OK and the requested data in the specified filetype format.
GeoJSON Format (Default) #
Returns a GeoJSON FeatureCollection where each feature is a street segment (LineString, WGS84 / EPSG:4326).
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [[-74.0243, 40.8839], [-74.0245, 40.8836]]
},
"properties": {
"street_edge_id": 766,
"osm_way_id": 11584845,
"region_id": 8,
"score": 0.6444,
"segment_score": 0.263,
"start_intersection_id": 412,
"end_intersection_id": 415,
"start_intersection_score": 0.8176,
"end_intersection_score": 0.8525,
"audit_count": 2,
"length_meters": 142.7,
"label_count": 4,
"mean_grade": 0.0412,
"max_grade": 0.0687,
"net_grade": -0.0398,
"total_climb_meters": 0.2,
"total_descent_meters": 5.9,
"meters_over_5pct": 48.0,
"meters_over_8pct": 0.0,
"grade_confidence": "high",
"grade_quality": "measured",
"dem_source": "usgs-3dep-10m",
"grade_term": -0.561,
"cluster_counts": {
"CurbRamp": 0, "NoCurbRamp": 0, "Obstacle": 0, "SurfaceProblem": 1,
"Crosswalk": 1, "Signal": 0, "NoSidewalk": 0
},
"sub_scores": {
"CurbRamp": 0.0, "NoCurbRamp": 0.0, "Obstacle": 0.0, "SurfaceProblem": -0.4695,
"Crosswalk": 0.0, "Signal": 0.0, "NoSidewalk": 0.0
},
"severity_counts": {
"CurbRamp": {"1": 0, "2": 0, "3": 0, "null": 0},
"NoCurbRamp": {"1": 0, "2": 0, "3": 0, "null": 0},
"Obstacle": {"1": 0, "2": 0, "3": 0, "null": 0},
"SurfaceProblem": {"1": 0, "2": 1, "3": 0, "null": 0},
"Crosswalk": {"1": 0, "2": 0, "3": 1, "null": 0},
"Signal": {"1": 0, "2": 0, "3": 0, "null": 0},
"NoSidewalk": {"1": 0, "2": 0, "3": 0, "null": 0}
},
"tag_adjustments": {
"CurbRamp": 0.0, "NoCurbRamp": 0.0, "Obstacle": 0.0, "SurfaceProblem": 0.0,
"Crosswalk": 0.0, "Signal": 0.0, "NoSidewalk": 0.0
}
}
},
...
]
}
GeoJSON Field Descriptions #
| Field Path | Type | Description |
|---|---|---|
geometry.coordinates | array[number] | Coordinate pairs forming the street's path, in [longitude, latitude] (WGS84 / EPSG:4326). |
properties.street_edge_id | integer | Project Sidewalk's unique identifier for this street segment. |
properties.osm_way_id | integer | OpenStreetMap Way ID for the street, if available. |
properties.street_name | string | The street's name, from its OpenStreetMap way's name tag; null for an unnamed way. |
properties.region_id | integer | Identifier for the region the street belongs to. |
properties.score | number | Headline AccessScore in (0, 1); higher is more accessible. The mean of segment_score, start_intersection_score, and end_intersection_score over those that are not null; null when all three are. |
properties.segment_score | number | The street's own segment score in (0, 1), from the clusters in cluster_counts. null when the street has not been audited. |
properties.start_intersection_id | integer | The intersection at the start of the street's geometry (see the Intersections API); null when that end is a dead end or a mere way split. |
properties.end_intersection_id | integer | The intersection at the end of the street's geometry; null likewise. |
properties.start_intersection_score | number | That intersection's score; null when there is none, it is unscored, or it is grade-separated. |
properties.end_intersection_score | number | That intersection's score; null likewise. |
properties.audit_count | integer | Number of completed (high-quality) audits of this street. |
properties.length_meters | number | Street length in meters (geodesic). Length-weights region scores and normalizes the along-length terms. |
properties.label_count | integer | Number of labels contributing to this street's segment clusters. |
properties.mean_grade | number | The street's mean absolute running grade over every 10 m baseline, as a fraction (0.05 is a 5% grade). Like every grade field it comes from an elevation model, not from labels, so an unaudited street has it too; see Street grade. null where the street has not been sampled or has no usable profile (grade_quality says which). |
properties.max_grade | number | The steepest absolute grade over any 30 m baseline (any 10 m baseline on a street shorter than 30 m). Never below mean_grade. |
properties.net_grade | number | End-to-end grade, signed in the direction of the street's geometry: negative where the street runs downhill from its first coordinate to its last. The one grade field a coarse (30 m) elevation model supports, so it can be set while the others are null. |
properties.total_climb_meters | number | Summed rise along the street in the direction of its geometry, in meters. |
properties.total_descent_meters | number | Summed fall along the street in the same direction, in meters. |
properties.meters_over_5pct | number | Meters of the street steeper than 5% (1:20), the ADA / PROWAG running-slope limit for a walking surface. |
properties.meters_over_8pct | number | Meters of the street steeper than 8.33% (1:12), the limit for a ramp; the field is named for the round figure. Never more than meters_over_5pct. |
properties.grade_confidence | string | high for an elevation model at 10 m or finer, medium to 20 m, low beyond. null where the street has not been sampled. |
properties.grade_quality | string | measured; structure (a bridge, tunnel, or covered way, which a bare-earth model cannot see, so every grade is null); suspect (the sampled profile was implausible, so the grades come from a straight line between the street's ends, or are null); or no_data (the model has nothing under the street). |
properties.dem_source | string | The elevation model the street was sampled from, which is what its credit is keyed on. null where the street has not been sampled. |
properties.grade_term | number | What the street's grade adds to the segment's pre-sigmoid total under the engine's grade settings; never positive, and 0 on a street with no sampled grade or one gentler than the walking-surface limit. Grade is not a label type, so it has no sub_scores entry; it is published separately so that logit(segment_score) = Σ sub_scores + grade_term holds, and so that subtracting it recovers the label-only score. |
properties.cluster_counts | object | Number of clusters of each label type scoring the segment, keyed by label-type name: the along-length types, plus any corner-type cluster not attributed to an intersection. |
properties.sub_scores | object | Contribution of each label type to the segment's pre-sigmoid total, keyed by label-type name; with grade_term the values sum to logit(segment_score), so they explain how it was composed. Per-cluster types report the sum over their clusters, length-normalized where the type is; NoSidewalk reports the street's single pooled term (see How the score is computed), which does not scale with cluster_counts.NoSidewalk. |
properties.severity_counts | object | Number of segment clusters of each label type in each rating bucket ("1", "2", "3", or "null" for unrated clusters), keyed by label-type name. The buckets of a type sum to its cluster_counts entry. |
properties.tag_adjustments | object | The summed adjustment of the active tags of each label type, keyed by label-type name: the part of sub_scores that no weight scales, before length normalization. With severity_counts, length_meters, and the scoring configuration, enough to recompute the segment score under your own weights. |
CSV Format #
If filetype=csv, the first row is the header. The per-type objects are flattened into one column per label type, each named for its path through the JSON: cluster_counts.<type>, sub_scores.<type>, severity_counts.<type>.1 through .3 plus .null, and tag_adjustments.<type>; the geometry is simplified to start/end points.
street_edge_id,osm_way_id,street_name,region_id,score,segment_score,start_intersection_id,end_intersection_id,start_intersection_score,end_intersection_score,audit_count,length_meters,label_count,mean_grade,max_grade,net_grade,total_climb_meters,total_descent_meters,meters_over_5pct,meters_over_8pct,grade_confidence,grade_quality,dem_source,grade_term,cluster_counts.CurbRamp,…,cluster_counts.NoSidewalk,sub_scores.CurbRamp,…,sub_scores.NoSidewalk,severity_counts.CurbRamp.1,severity_counts.CurbRamp.2,severity_counts.CurbRamp.3,severity_counts.CurbRamp.null,…,severity_counts.NoSidewalk.null,tag_adjustments.CurbRamp,…,tag_adjustments.NoSidewalk,start_point,end_point
766,11584845,Queen Anne Road,8,0.6444,0.263,412,415,0.8176,0.8525,2,142.7,4,0.0412,0.0687,-0.0398,0.2,5.9,48.0,0.0,high,measured,usgs-3dep-10m,-0.561,0,…,0,0.0,…,0.0,0,0,0,0,…,0,0.0,…,0.0,"-74.0243,40.8839","-74.0245,40.8836"
...
The full header, in order: the thirteen leading columns, the ten grade columns (mean_grade through dem_source) and grade_term, then cluster_counts.<type> for each of the 7 scored types, sub_scores.<type> for each, the four severity_counts.<type>.* buckets for each, tag_adjustments.<type> for each, then start_point and end_point. Types are always in the order CurbRamp, NoCurbRamp, Obstacle, SurfaceProblem, Crosswalk, Signal, NoSidewalk.
Shapefile Format #
If filetype=shapefile, the response is a ZIP archive of Shapefile components (.shp, .shx, .dbf, .prj, .cpg). Text longer than 254 bytes is truncated. Because the DBF format truncates column names at 10 characters, the columns use short codes: segScore, sIntId / eIntId, and sIntScore / eIntScore for the headline's components, meanGrade, maxGrade, netGrade, climbM, descentM, mOver5pct, mOver8pct, gradeConf, gradeQual, demSource and gradeTerm for grade, and per type cluster count nCRamp, sub-score sCRamp, cluster count per rating bucket n1CRamp, n2CRamp, n3CRamp and n0CRamp (unrated), and tag adjustment tCRamp; the GeoJSON, CSV, and GeoPackage formats keep the full names.
GeoPackage Format #
If filetype=geopackage, the response is a GeoPackage (.gpkg) file with full geometry and the same fields, in the same order, as the GeoJSON properties. The per-type columns are named as in the CSV but with each dot turned into an underscore, since ArcGIS doesn't allow dots in column names: cluster_counts_CurbRamp, sub_scores_CurbRamp, severity_counts_CurbRamp_1 through _3 plus _null, and tag_adjustments_CurbRamp.
Error Responses#
400 Bad Request: Invalid parameter values (e.g., malformed bounding box, non-positive or unknown region id).429 Too Many Requests: The same file is already being built for an earlier request; waitRetry-Afterseconds and try again. AHEADrequest gets the same answer without building anything.500 Internal Server Error: An unexpected error occurred on the server.503 Service Unavailable: A whole-city request (nobboxor region filter) found the city's scores not yet cached — after a deploy, or in a long-idle city — and they are still being computed. WaitRetry-Afterseconds (30) and repeat the request; the body'scodeisSTILL_COMPUTING.
Response Headers#
X-File-Size: On a Shapefile, GeoPackage or zipped-CSV download, the file's size in bytes. Sent alongsideContent-Length, and still present when the response is gzipped, which drops it — use it to show download progress.
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#
- Treat the score as relative, not absolute: the weights are experimental. Use scores to compare streets, not as a calibrated index.
- Read the breakdown:
segment_scoreand the two intersection scores show which part of a trip along the street is the problem, andcluster_countsandsub_scoresexplain the segment. - Mind audit coverage: a
nullsegment_scoremeans the street has not been audited — absence of data, not poor accessibility. Its headline may still carry its crossings' scores. - Roll up to neighborhoods: use the AccessScore: Regions API for length-weighted, region-level scores.
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.