SPARQL

By the end of this guide, you'll be able to query OSM data through Plaza's SPARQL endpoint using RDF triples and GeoSPARQL predicates.

Fair warning: if you don't already know SPARQL, you'll probably find Overpass QL or the REST API easier to work with. This endpoint exists for people coming from the linked data world who want to query OpenStreetMap the same way they'd query Wikidata or DBpedia.

Running a query

curl -X POST "https://plaza.fyi/api/v1/sparql" \
-H "x-api-key: pk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "PREFIX osm: <https://plaza.fyi/ns/osm#> SELECT ?s WHERE { ?s osm:amenity \"cafe\" } LIMIT 10"}'

The response is a JSON object with a results array of GeoJSON features.

Prefixes

Plaza defines these namespaces. Declare them with PREFIX or write full IRIs -- your call.

Prefix Namespace Covers
osm: https://plaza.fyi/ns/osm# OSM tag keys (amenity, name, etc.)
osmm: https://plaza.fyi/ns/osm/meta# Meta properties (type)
osmnode: https://www.openstreetmap.org/node/ Node IRIs by ID
osmway: https://www.openstreetmap.org/way/ Way IRIs by ID
osmrel: https://www.openstreetmap.org/relation/ Relation IRIs by ID
geo: http://www.opengis.net/ont/geosparql# GeoSPARQL (lat, long)
rdf: http://www.w3.org/1999/02/22-rdf-syntax-ns# RDF vocabulary

How OSM maps to RDF

Plaza maps OSM tags directly to RDF predicates under the osm: namespace. An element tagged amenity=cafe in OSM becomes the triple ?s osm:amenity "cafe".

That's the whole mental model. If the OSM tag key is highway, the predicate is osm:highway. If the value is residential, the object is "residential".

Filtering by element type

Two ways to do it:

# With rdf:type
PREFIX osm: <https://plaza.fyi/ns/osm#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT ?s WHERE {
?s rdf:type osm:Node .
?s osm:amenity "cafe" .
}
LIMIT 10
# With osmm:type
PREFIX osm: <https://plaza.fyi/ns/osm#>
PREFIX osmm: <https://plaza.fyi/ns/osm/meta#>
SELECT ?s WHERE {
?s osmm:type "node" .
?s osm:amenity "cafe" .
}
LIMIT 10

Valid types: osm:Node, osm:Way, osm:Relation (or strings "node", "way", "relation" with osmm:type).

Checking if a tag exists

Bind the tag to a variable. If the element doesn't have that tag, it won't match:

PREFIX osm: <https://plaza.fyi/ns/osm#>
SELECT ?s ?name WHERE {
?s osm:amenity "restaurant" .
?s osm:name ?name .
}
LIMIT 20

This returns only restaurants that have a name tag set.

Spatial queries

Use GeoSPARQL predicates with FILTER for bounding box queries:

PREFIX osm: <https://plaza.fyi/ns/osm#>
PREFIX geo: <http://www.opengis.net/ont/geosparql#>
SELECT ?s WHERE {
?s osm:amenity "cafe" .
?s geo:lat ?lat .
?s geo:long ?lng .
FILTER(?lat > 48.85 && ?lat < 48.87 && ?lng > 2.33 && ?lng < 2.36)
}
LIMIT 50

You need all four bounds for the filter to take effect. If you only specify two, Plaza ignores the partial filter entirely.

Examples

All pubs

PREFIX osm: <https://plaza.fyi/ns/osm#>
SELECT ?s WHERE {
?s osm:amenity "pub" .
}
LIMIT 25

Restaurants with cuisine tags in Manhattan

PREFIX osm: <https://plaza.fyi/ns/osm#>
PREFIX geo: <http://www.opengis.net/ont/geosparql#>
SELECT ?s ?cuisine WHERE {
?s osm:amenity "restaurant" .
?s osm:cuisine ?cuisine .
?s geo:lat ?lat .
?s geo:long ?lng .
FILTER(?lat > 40.7 && ?lat < 40.8 && ?lng > -74.0 && ?lng < -73.9)
}
LIMIT 50

IDs only (faster for bulk queries)

If you only select the subject variable, Plaza returns IDs without geometry or tags:

PREFIX osm: <https://plaza.fyi/ns/osm#>
SELECT ?s WHERE {
?s osm:shop "bicycle" .
}
LIMIT 100

Residential roads only

PREFIX osm: <https://plaza.fyi/ns/osm#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT ?s WHERE {
?s rdf:type osm:Way .
?s osm:highway "residential" .
}
LIMIT 50

Dataset scoping

If you've created a named dataset, scope your query to it:

PREFIX osm: <https://plaza.fyi/ns/osm#>
SELECT ?s
FROM <dataset:my-city-extract>
WHERE {
?s osm:building "yes" .
}
LIMIT 100

Limitations

Be upfront about what this endpoint can't do yet:

  • No OPTIONAL, UNION, or subqueries. Each query compiles to a single element scan with filters.
  • No ORDER BY or OFFSET.
  • Only SELECT queries. CONSTRUCT and DESCRIBE are not supported.
  • LIMIT caps at 10,000 results.
  • Query timeout is 30 seconds.

If you need set operations or recursive traversals, Overpass QL is the better tool. SPARQL works well for tag-based filtering and bounding box queries where you prefer the RDF data model.