OSMPID (OpenStreetMap Persistent ID) is an open, decentralized identifier for OpenStreetMap (OSM) objects — state-bound, change-aware, human-readable, and based solely on public OSM data.
OSMPID provides stable references to OpenStreetMap objects from a given point in time. It can be generated without a central registry, relies only on the community-based OSM data model, and avoids vendor lock-in.
Unlike registry-based identifiers, OSMPID does not define persistence semantics globally. Instead, applications remain in control of how references are interpreted, resolved, and preserved over time.
The OSMPID specification and reference implementation are maintained as a community commons. There is no vendor lock-in, proprietary control or external state.
The identifier is computed purely from properties of that OpenStreetMap object. OpenStreetMap stays the single source of truth.
The specification and an OSM data source (OSM-API, OSM-dump) is all you need to generate and validate OSMPIDs — no external database, service or entity is required. We provide a reference implementation and API service, but you are free to operate your own and still be fully compatible.
OSMPID lets you capture the meaning and specify exactly what you are referring to in your
application. For example, one OSM object could simultaneously represent a building
(building=true) and a business (amenity=restaurant), which would lead
to ambiguity if something changes (e.g. the restaurant goes out of business). OSMPID solves this
problem.
The OSMPID is human-readable rather than a cryptic hash or opaque number. This improves transparency and trust in the identifier, as users can easily understand, create and verify an OSMPID.
Resolve the current OSM element, compare the stored version, newest child timestamp and pinned tags, then return one clear verdict.
The stored version must still match the current object version.
Ways and relations compare the newest timestamp found below the referenced object.
Pinned tag keys or values must still be present on the object.
| Result | Status | Reason |
|---|---|---|
| Unchanged | 200 OK | Version, children and tags all match. |
| Changed | 200 OK | Version, a child element or a tag changed. A new OSMPID is returned. |
| Deleted | 200 OK | The object is no longer visible. |
| Unknown | 200 OK | This type and id never existed. |
| Malformed | 422 | The string failed to parse. |
osmpid is a typed Python library for parsing, serializing, generating and
validating OSMPIDs. Requires Python 3.11+.
pip install osmpid --index-url https://gitlab.com/api/v4/projects/83207967/packages/pypi/simple from osmpid import OverpassClient, parse, validate pid = parse("node/2641352539@7?amenity=bar") with OverpassClient() as client: result = validate(pid, client) print(result.status) print(result.changed_reason)
OSMPID was inspired by Simon Poole's OpenStreetMap diary entry on persistent references to OSM objects. His write-up framed the problem and motivated this work.