OpenStreetMap's ODbL Licence Explained for Python Users
On this page
Problem statement
OpenStreetMap data is free to use, including commercially, but not free of conditions. It is licensed under the Open Database License (ODbL) 1.0, which requires attribution and asks that databases derived from OSM and used publicly are shared under the same licence. People building maps, analyses and products from OSM in Python regularly ask the same questions. What counts as a map and what as a database? Does joining OSM to my own data make my data open? What exactly must the attribution say? And what about data that came into OSM from official sources?
This page explains the licence in practical terms and uses the Washington, D.C. extract of 1 January 2026 to show where licensing questions meet real data: how much of a city's map came from imported official data, what attribution a map built from it needs, and which outputs of a typical workflow are databases and which are produced works. It is an explanation, not legal advice.
Quick answer
The attribution OSM requires is short; put it on every map and dataset built from OSM:
ATTRIBUTION = "Β© OpenStreetMap contributors"
LICENCE_URL = "https://www.openstreetmap.org/copyright"
print(f"map credit: '{ATTRIBUTION}', linked to {LICENCE_URL}")
print(f"data licence for shared derivative databases: ODbL 1.0 ({'https://opendatacommons.org/licenses/odbl/1-0/'})")
map credit: 'Β© OpenStreetMap contributors', linked to https://www.openstreetmap.org/copyright
data licence for shared derivative databases: ODbL 1.0 (https://opendatacommons.org/licenses/odbl/1-0/)
Two lines cover the obligations most users meet: the credit on anything shown, and the licence for databases shared publicly.
Where the data came from, produced work or database, substantial extracts
1. Where the data came from
Much of OSM in many cities came from imports of official data, recorded in source tags and import-specific keys. Count them in the D.C. extract:
con = duckdb.connect(); con.sql("INSTALL spatial; LOAD spatial")
src = con.sql(f"""SELECT tags['source'] AS source, count(*) AS n FROM ST_ReadOSM('{PBF}')
WHERE tags['source'] IS NOT NULL GROUP BY 1 ORDER BY 2 DESC LIMIT 6""").df()
tagged = con.sql(f"SELECT count(*) FROM ST_ReadOSM('{PBF}') WHERE cardinality(tags) > 0").fetchone()[0]
dcgis = con.sql(f"SELECT count(*) FROM ST_ReadOSM('{PBF}') WHERE len(list_filter(map_keys(tags), k -> k LIKE 'dcgis:%')) > 0").fetchone()[0]
print(src.to_string(index=False))
print(f"elements with dcgis:* tags from the District's GIS: {dcgis:,} of {tagged:,} tagged elements ({dcgis / tagged:.0%})")
source n
dcgis 104398
dcgis dataset buildings 1023
USGS Ortho 929
USGS Geonames 698
survey 574
Bing 499
elements with dcgis:* tags from the District's GIS: 171,472 of 372,977 tagged elements (46%)
source=dcgis is on 104,398 elements, far ahead of the next sources: USGS orthophotos, USGS place names, field survey and Bing imagery. Counting import-specific keys, 171,472 of the 372,977 tagged elements, 46%, carry dcgis: tags from the District's GIS. Much of the map came from that import.
2. Produced work or derivative database?
The ODbL treats a map image differently from a dataset. Classify the outputs of a typical workflow on this data:
outputs = [("PNG map of parks", "produced work", "attribution"),
("GeoPackage of D.C. parks extracted from OSM", "derivative database", "ODbL if shared publicly"),
("table of park area per ward, computed from OSM", "derivative database", "ODbL if shared publicly"),
("OSM parks and your own survey data in separate layers", "collective database", "ODbL applies to the OSM part"),
("a sentence in a report quoting the park total", "insubstantial extract", "attribution is good practice")]
for what, kind, obligation in outputs:
print(f"{what:>52}: {kind:<22} -> {obligation}")
PNG map of parks: produced work -> attribution
GeoPackage of D.C. parks extracted from OSM: derivative database -> ODbL if shared publicly
table of park area per ward, computed from OSM: derivative database -> ODbL if shared publicly
OSM parks and your own survey data in separate layers: collective database -> ODbL applies to the OSM part
a sentence in a report quoting the park total: insubstantial extract -> attribution is good practice
The line falls between pictures and data. A map image is a produced work. An extract or a table computed from OSM is a derivative database. Keeping OSM in its own layer beside your data makes a collective database.
3. How substantial is an extract?
Share-alike applies to a substantial part of the database. The OSM Foundation's guideline treats fewer than 100 features, used for one purpose, as insubstantial. Check a few extracts of this file against it:
fp = (osmium.FileProcessor(str(PBF)).with_filter(osmium.filter.TagFilter(("amenity", "charging_station"), ("railway", "station")))
.with_filter(osmium.filter.GeoInterfaceFilter(tags=["amenity", "railway"])))
small = gpd.GeoDataFrame.from_features(fp, crs=4326)
for label, n in (("charging stations", (small.amenity == "charging_station").sum()), ("railway stations", (small.railway == "station").sum()),
("all buildings", con.sql(f"SELECT count(*) FROM ST_ReadOSM('{PBF}') WHERE tags['building'] IS NOT NULL").fetchone()[0])):
print(f"{label:>18}: {n:>7,} features -> {'under' if n < 100 else 'over'} the 100-feature guideline")
charging stations: 36 features -> under the 100-feature guideline
railway stations: 52 features -> under the 100-feature guideline
all buildings: 162,241 features -> over the 100-feature guideline
Extracting D.C.'s 36 charging stations or 52 railway stations stays under the guideline's 100 features. Extracting all 162,241 buildings is clearly substantial, so a dataset built on it and used publicly falls under share-alike.
Attribution on a matplotlib map
The data used on this page
The Geofabrik OpenStreetMap extract for the District of Columbia dated 1 January 2026, Β© OpenStreetMap contributors, available under the Open Database License.
from pathlib import Path
import duckdb
import geopandas as gpd
import osmium
import requests
Path("data").mkdir(exist_ok=True)
PBF = Path("data/district-of-columbia-260101.osm.pbf")
if not PBF.exists():
r = requests.get("https://download.geofabrik.de/north-america/us/district-of-columbia-260101.osm.pbf", timeout=600)
r.raise_for_status()
PBF.write_bytes(r.content)
print(f"{PBF.name} ready")
district-of-columbia-260101.osm.pbf ready
The dated D.C. extract is ready.
Example 1: attribution on a matplotlib map
A produced work needs the credit where viewers see it. Put it on the figure itself:
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
fp = (osmium.FileProcessor(str(PBF)).with_areas().with_filter(osmium.filter.EntityFilter(osmium.osm.AREA))
.with_filter(osmium.filter.TagFilter(("leisure", "park"))).with_filter(osmium.filter.GeoInterfaceFilter()))
parks = gpd.GeoDataFrame.from_features(fp, crs=4326).to_crs(32618)
fig, ax = plt.subplots(figsize=(6, 6)); parks.plot(ax=ax, color="#14b8a6", lw=0); ax.set_axis_off()
fig.text(0.99, 0.01, ATTRIBUTION, ha="right", va="bottom", fontsize=7, color="#64748b")
fig.savefig("data/parks_attributed.png", dpi=120); plt.close(fig)
print(f"{len(parks)} park areas drawn; credit '{ATTRIBUTION}' placed on the image")
736 park areas drawn; credit 'Β© OpenStreetMap contributors' placed on the image
The 736 park areas are drawn with the credit on the figure itself, where every viewer sees it.
The database separated from what is made with it
The ODbL separates the database from what is made with it. A produced work, such as a map image, a chart or a printed figure, can be released under any terms the maker likes, provided it credits OpenStreetMap so that people know where the data came from and that it is available under the ODbL. A derivative database is a modified or extended copy of the data, such as an extract converted to GeoPackage, OSM roads with speeds added, or a table computed from OSM features. If it is used publicly, through publishing it, offering it through a service, or making a public produced work from it, it must be offered under the ODbL too, or the means to recreate it must be shared. A collective database keeps OSM and other data side by side without merging them. Then only the OSM part carries the licence, which is why the OSM Foundation's guidelines on horizontal layers and geocoding matter for products that combine data.
Imports complicate provenance but not the licence. Under the import guidelines, data from official sources may enter OSM only when its own licence allows it to be used under the ODbL, and once in OSM it is used under OSM's terms. In D.C. a large share of the map, most visibly the buildings, came from the District's GIS, as the dcgis: tags record. Its original source may have its own, sometimes looser, terms, but data taken from OSM is used under the ODbL. Nothing here is legal advice. The OSMF's licence guidelines and its legal FAQ are the place to check specific cases.
Tiles, placement and machine learning
- Tiles: map tiles rendered from OSM are produced works; the tile servers' own usage policies are separate from the data licence.
- Attribution placement: the OSMF attribution guideline asks for the credit where viewers will see it, such as the map corner, not only in a separate credits page.
- Trivial transformations: format conversion does not create a new work; a GeoPackage of OSM data is still OSM data.
- Machine learning: models trained on OSM raise questions the guidelines address only partly; check the current OSMF position.
Internal links
- Attribution requirements explained β OSM, Copernicus and national data side by side
- How to export OpenStreetMap data to GeoPackage or shapefile β exports carry the licence
- How to analyse OpenStreetMap history with the ohsome API β when the imports happened
FAQ
Can I use OpenStreetMap data commercially?
Yes; the ODbL allows commercial use, provided you credit OpenStreetMap and share derivative databases that you use publicly under the same licence.
What attribution does OpenStreetMap require?
"Β© OpenStreetMap contributors", with a link to openstreetmap.org/copyright where possible, placed where viewers of the map or data will see it.
Do I have to release my own data if I combine it with OSM?
Not if the two stay as separate layers (a collective database); merging them into one database used publicly makes it a derivative database under the ODbL.
Is a map made from OSM data covered by share-alike?
A map image is a produced work: it needs attribution but can be licensed as you choose.