Open data
The numbers behind the a11y-Score are open data. Every bar of every chart on this website — one score for one combination of a region, an accessibility topic and a type of place — is a row in a table you can download, analyse and reuse. The files are regenerated regularly.
A complete, runnable example — a citizen-facing accessibility summary for the city of Mainz, computed from these files — is available on GitHub: sozialhelden/a11yscore-opendata-example.
Download
File | Contents |
|---|---|
The same rows as gzipped CSV (UTF-8, comma-separated, with a header row; timestamps in UTC, an empty field means no value). Unpack it to open it in a spreadsheet. | |
Every computed chart row: scores, five-number summaries, place counts and coverage, with readable names and Wikidata IDs of the regions involved. | |
Machine-readable metadata for both files in DCAT-AP.de, the format of the Mobilithek and of open-data portals such as GovData. |
The Parquet file uses the Apache Parquet format: compressed, column-oriented and typed, so numbers stay numbers and dates stay dates. Parquet opens directly in DuckDB, pandas, polars, R (arrow), Apache Spark, QGIS and most other data tools. For spreadsheets, take the CSV file, or convert the Parquet file to Excel (see below).
- Updated daily at around 06:00 (Europe/Berlin, at the time this article is written, in 2026. This might change.). Both files come from the same run; the Parquet file records its export time in the metadata key exported_at.
- Stable URLs: everything under /v1/ keeps its URL. New columns or files may be added at any time, so select columns by name rather than by position. A change that breaks existing columns gets a new prefix (/v2/).
License
The a11y-Score is computed from OpenStreetMap data, © OpenStreetMap contributors, which is available under the Open Database License (ODbL) 1.0. These exports are a derived database and are published under the ODbL, too: you may use, share and adapt them, provided that you attribute “a11y-Score by Sozialhelden e.V., based on data © OpenStreetMap contributors” and publish adapted databases under the same license. Region names and Wikidata IDs come from Wikidata (CC0).
How the data is organised
The a11y-Score organises everything in three trees of dimensions. Each dimension has a numeric ID and a slug (the name used in this website’s URLs):
- Region/Geography — where? Continents, countries, states, districts and so on. Regions carry their Wikidata ID.
- Accessibility — what is scored? Topics like mobility or vision, down to single criteria such as an accessible toilet.
- Place categories — which places? Education, health, food and drink and their sub-categories.
A chart combines a dimension with a grouping dimension whose direct children become the bars, within a geographic scope. Every chart is stored as one parent row (the chart’s total, is_parent_row = true) plus one row per bar. The column chart_kind says which of the three chart types a row belongs to:
chart_kind | dimension | grouping dimension | bars | answers |
|---|---|---|---|---|
category | accessibility topic | place category | its sub-categories | How accessible are cafés? |
criteria | place category | accessibility topic | its sub-criteria | Which accessibility features do cafés report? |
region | accessibility topic | region | its sub-regions, optionally only for one place category | How accessible is each district? |
The table holds the charts that have been computed for this website — the ones its pages show and the ones visitors have opened — not every theoretically possible combination. A row’s a11yscore is a number from 0 to 1; the website shows it multiplied by 100. How a score is calculated is explained in How is the a11y-Score calculated?.
Columns of dimension-combination-metrics
Which chart a row belongs to:
Column | Type | Meaning |
|---|---|---|
metric_id | BIGINT | Row ID. Unique within one file, but not stable between exports — rows get a new ID whenever they are recomputed. |
chart_kind | VARCHAR | category, criteria or region (see above). |
dimension_id, dimension_slug | INTEGER, VARCHAR | The chart’s dimension: the accessibility topic that is scored (category, region), or the place category whose places are examined (criteria). |
grouping_dimension_id, grouping_dimension_slug | INTEGER, VARCHAR | The chart’s grouping dimension. Its direct children are the bars. |
filter_dimension_id, filter_dimension_slug | INTEGER, VARCHAR | region charts only: the place category the places are restricted to; tree-root-use, the root of the place-category tree, means all places. Empty (NULL) for the other chart kinds. |
is_parent_row | BOOLEAN | true for the chart’s total, false for a bar. |
The three dimensions of a row. dim0 is the geographic scope, dim1 the chart’s dimension (always the same node as dimension_id), dim2 the bar — or the grouping dimension itself on the parent row:
Column | Type | Meaning |
|---|---|---|
dim0_id, dim1_id, dim2_id | INTEGER | Numeric dimension IDs. Stable as long as the trees are not regenerated; prefer slugs and Wikidata IDs for joining data over time. |
dim0_slug, dim1_slug, dim2_slug | VARCHAR | Slugs, as in the URLs of this website — for example /scores/<dim0_slug> for a region. |
dim0_tree_slug, dim1_tree_slug, dim2_tree_slug | VARCHAR | Slug of the tree the dimension belongs to. There is more than one geography tree (with different levels of detail), so the same region can appear several times — with different IDs and slugs but the same Wikidata ID. Filter on one tree before comparing regions. |
dim0_name_en, dim0_name_de, … dim2_name_de | VARCHAR | Display names in English and German. |
dim0_wikidata_id, dim2_wikidata_id | VARCHAR | Wikidata item ID (Q…) of the region, if it has one — the most reliable way to link the data to other sources. dim0 is the scope; for a region chart it is the grouping region, for a worldwide chart the root of the geography tree. |
dim0_wof_placetype, dim2_wof_placetype | VARCHAR | Administrative level of the region in Who’s On First terms, e.g. country, region, county, locality. |
Scores and counts:
Column | Type | Meaning |
|---|---|---|
a11yscore | DOUBLE | The score, 0 (not accessible) to 1 (fully accessible): the mean of the per-place scores of all places in the scope that belong to the bar and have data for the dimension. Empty (NULL) when there are no such places. |
score_min, score_q1, score_median, score_q3, score_max | DOUBLE | Five-number summary (minimum, lower quartile, median, upper quartile, maximum) of the per-place scores behind a11yscore, 0 to 1 — the box plots on this website. |
d0_x_d1_x_d2_count | BIGINT | Number of places the score is based on: places in the scope (dim0) that match the bar (dim2) and have data for the dimension (dim1). |
d0_x_d1_count | BIGINT | The same count without the bar’s restriction: places in the scope with data for the dimension. |
n_total | BIGINT | All places in the scope that belong to the row’s place category, whether or not they have accessibility data. Coverage = d0_x_d1_x_d2_count / n_total. |
sum_of_branch_products, normalized_sum_of_branch_products, dim1_branch_product, dim2_branch_product | DOUBLE | Intermediate values of the weighted mean (a branch product is the product of the weights along a dimension’s path in its tree). Included for reproducibility; most analyses do not need them. |
updated_at | TIMESTAMP WITH TIME ZONE | When the row was computed. |
is_stale | BOOLEAN | true when the underlying map data has changed since the row was computed and the row is queued for recomputation. The website shows such rows until the new values are ready. |
Converting to CSV, Excel or JSON
DuckDB is a small, free command-line tool that reads and writes all of these formats:
1# Download once, then convert with the DuckDB CLI (https://duckdb.org)2curl -O https://sozialhelden-opendata.fra1.digitaloceanspaces.com/a11yscore/v1/latest/dimension-combination-metrics.parquet34# CSV, e.g. for Excel, LibreOffice or Google Sheets5duckdb -c "COPY (FROM 'dimension-combination-metrics.parquet') TO 'dimension-combination-metrics.csv' (HEADER)"67# Excel workbook8duckdb -c "INSTALL excel; LOAD excel; COPY (FROM 'dimension-combination-metrics.parquet') TO 'dimension-combination-metrics.xlsx' (FORMAT xlsx, HEADER true)"910# Newline-delimited JSON11duckdb -c "COPY (FROM 'dimension-combination-metrics.parquet') TO 'dimension-combination-metrics.ndjson' (FORMAT json)"
Querying with SQL
DuckDB can also query the file straight from its URL and only downloads the parts a query needs. This lists the mobility scores of the 20 regions directly below Germany that have the most places:
1-- Query the file in place, without downloading it first (DuckDB CLI or any DuckDB client)2SELECT dim2_name_en AS region,3 round(a11yscore * 100) AS score,4 d0_x_d1_x_d2_count AS places_with_data,5 n_total AS places,6 round(100.0 * d0_x_d1_x_d2_count / n_total) AS coverage_percent7FROM 'https://sozialhelden-opendata.fra1.digitaloceanspaces.com/a11yscore/v1/latest/dimension-combination-metrics.parquet'8WHERE chart_kind = 'region'9 AND dim0_wikidata_id = 'Q183' -- regions directly below Germany …10 AND dim0_tree_slug = 'geography-6-levels' -- … in one geography tree11 AND dimension_slug = 'mobility' -- scored for mobility12 AND filter_dimension_slug = 'tree-root-use' -- all place categories13 AND NOT is_parent_row14ORDER BY places DESC15LIMIT 20;
Python
1# pip install duckdb pandas pyarrow2import duckdb3import pandas as pd45URL = "https://sozialhelden-opendata.fra1.digitaloceanspaces.com/a11yscore/v1/latest/dimension-combination-metrics.parquet"67# Either load everything into pandas …8df = pd.read_parquet(URL)9df["coverage"] = df["d0_x_d1_x_d2_count"] / df["n_total"]1011# … or let DuckDB filter before anything is loaded12bars = duckdb.sql(f"""13 SELECT chart_kind, dim0_name_en, dim1_name_en, dim2_name_en, a11yscore14 FROM '{URL}'15 WHERE NOT is_parent_row16""").df()
R
1# install.packages("arrow")2library(arrow)34url <- "https://sozialhelden-opendata.fra1.digitaloceanspaces.com/a11yscore/v1/latest/dimension-combination-metrics.parquet"5download.file(url, "dimension-combination-metrics.parquet", mode = "wb")6df <- read_parquet("dimension-combination-metrics.parquet")7df$coverage <- df$d0_x_d1_x_d2_count / df$n_total
Questions and feedback
Found something odd in the data, or need another table? Tell us — we are happy to hear what you build with it.