PlazaQL: Query Geospatial Data Without the Overhead
If you’ve ever tried to pull specific geographic data from OpenStreetMap, you’ve probably hit infrastructure walls. The public overpass-api.de has aggressive rate limits, and self-hosting an Overpass instance means downloading 70GB+ and managing your own server. Neither option is fun when you just want location data in your app.
PlazaQL is Plaza’s query language for geospatial data. It lets you query billions of features — every pharmacy within 500 meters, all parks in a city, every bike shop with a repair stand — through a single HTTP endpoint that returns GeoJSON.
This article covers PlazaQL itself and how Plaza removes the infrastructure headache so you can query geospatial data with one POST request.
What Is PlazaQL?
Section titled “What Is PlazaQL?”PlazaQL is a read-only query language designed for geospatial data. Think of it as SQL for geographic places. You can query OpenStreetMap nodes, ways, and relations, Plaza-curated datasets, and your own custom data — all with the same syntax.
Features have tags and properties. An OpenStreetMap pharmacy is tagged amenity=pharmacy. A park is leisure=park. A vegan restaurant has amenity=restaurant plus diet:vegan=yes. PlazaQL lets you filter by any combination of tags or properties, apply geographic constraints like bounding boxes or radius searches, and return the results — whether the data comes from OSM, a curated dataset, or your own uploads.
The syntax is clean and readable. Once you see a few examples, you can pull almost any real-world geographic dataset you can think of.
Why PlazaQL Is So Powerful
Section titled “Why PlazaQL Is So Powerful”Plaza gives you direct access to billions of features — the full OpenStreetMap planet, curated open datasets, and any custom data you upload.
Google Maps and Mapbox expose curated POI data through their own APIs. You get what they decide to surface, in the format they choose, under their licensing terms. With PlazaQL, you query the raw data yourself. You can filter by obscure tags, combine conditions, mix data sources, and retrieve data that simply does not exist in commercial APIs.
A few examples of what you can do that you can’t easily do with a standard geocoding API:
- Find every public drinking fountain in Berlin
- List all ATMs that are wheelchair accessible within a city
- Pull every road with a specific surface type for a cycling app
- Get all buildings taller than 10 floors in a bounding box
- Filter roads by computed length (
length() > 1000) - Aggregate data — average building height by type, total restaurant capacity by neighborhood
- Use expression filters with arithmetic on tag values (
number(t["capacity"]) > 50)
PlazaQL is useful for data-heavy applications, urban planning tools, accessibility apps, and anything beyond “find a coffee shop near me.”
The Problem: Running Your Own OSM Query Server Is a Chore
Section titled “The Problem: Running Your Own OSM Query Server Is a Chore”To query OSM data in production, you historically had two realistic options.
You can use the public Overpass API at overpass-api.de. It’s free, but it’s shared infrastructure. Rate limits kick in fast. Heavy queries get rejected. You can’t rely on it for anything user-facing because you have no SLA and no control over availability.
Or you run your own Overpass instance. This means downloading a full OSM planet file (over 70GB compressed), setting up the server, keeping the data synced, and managing the infrastructure yourself. It works, but it’s a lot of ops work before you’ve written a single line of application code.
Neither option is a good fit if you’re a developer who just wants to query geographic data and ship something.
Plaza: One Endpoint, PlazaQL Support
Section titled “Plaza: One Endpoint, PlazaQL Support”Plaza is a geospatial data API that handles all of this for you. It supports geocoding, reverse geocoding, routing, and POI search. But PlazaQL support is probably the most relevant part if you want raw query power.
You send your PlazaQL query to POST /api/v1/query. Plaza runs it against its full dataset — OpenStreetMap, curated sources, and any custom data you’ve uploaded — and returns a GeoJSON FeatureCollection. No infrastructure to manage, no caching restrictions.
For large result sets, Plaza returns chunked responses so your client can process features as they arrive.
How It Works
Section titled “How It Works”You make a standard HTTP request to the Plaza API with your PlazaQL query in a JSON body. Plaza handles the query execution and returns the response. No special client library required — if you can make an HTTP request, you can use Plaza.
Real Code Examples
Section titled “Real Code Examples”Some real examples using cURL. All of these work against the Plaza endpoint and return GeoJSON.
Find All Pharmacies Near a Coordinate
Section titled “Find All Pharmacies Near a Coordinate”This query finds every pharmacy within 500 meters of a point in central Paris.
curl -X POST "https://plaza.fyi/api/v1/query" \ -H "x-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "query": "$$ = search(node, amenity: \"pharmacy\").around(distance: 500, geometry: point(48.8566, 2.3522));" }'You get back a GeoJSON FeatureCollection with each pharmacy as a feature, including its name, address tags, and coordinates.
Find All Parks in London
Section titled “Find All Parks in London”This query finds every park in the City of London by looking up the area by name — no coordinates needed.
curl -X POST "https://plaza.fyi/api/v1/query" \ -H "x-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "query": "$london = boundary(name: \"City of London\"); $$ = search(way, leisure: \"park\").within(geometry: $london);" }'PlazaQL returns the full geometry of each way, so you get polygon outlines for the parks, not just centroid points. Useful if you’re rendering them on a map or doing area calculations.
Find All Cafes With Outdoor Seating
Section titled “Find All Cafes With Outdoor Seating”This one combines two tag conditions to find cafes with outdoor seating across all of Paris.
curl -X POST "https://plaza.fyi/api/v1/query" \ -H "x-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "query": "$paris = boundary(name: \"Paris\"); $$ = search(node, amenity: \"cafe\", outdoor_seating: \"yes\").within(geometry: $paris);" }'You can’t do this through the Mapbox geocoding API or Google Places. You’re querying raw tags, which means you can filter on any attribute in the dataset.
Why PlazaQL Is a Natural Fit for AI Agents
Section titled “Why PlazaQL Is a Natural Fit for AI Agents”PlazaQL has an interesting property for anyone building LLM-powered tools: the language is structured enough for an AI to generate, but expressive enough to handle queries that no pre-built API category system covers.
When you give a Google Places API to an LLM agent, the agent picks from predefined categories — “restaurant,” “hospital,” “gas_station.” That works for common searches. But what happens when the query is “find all buildings with solar panels within 1km of this school” or “show me every road segment with a speed limit under 30km/h in this neighborhood”? Google’s category system has no answer.
An LLM can generate PlazaQL for those queries directly:
User prompt: “Find all wheelchair-accessible ATMs in Berlin”
LLM-generated PlazaQL:
$berlin = boundary(name: "Berlin");$$ = search(node, amenity: "atm", wheelchair: "yes").within(geometry: $berlin);User prompt: “Show me every building taller than 10 floors near Times Square”
LLM-generated PlazaQL:
$ts = search(node, name: "Times Square", place: "square");$$ = search(way, building: *) .around(distance: 500, geometry: $ts) .filter(is_number(t["building:levels"]) && number(t["building:levels"]) >= 10);Expression filters let the LLM do numeric comparisons on tag values — something regex hacks can’t handle cleanly.
User prompt: “Find a pharmacy on my way to work”
LLM-generated PlazaQL:
$r = route(origin: point(40.748, -73.993), destination: point(40.755, -73.970));$$ = search(node, amenity: "pharmacy").around(distance: 200, geometry: $r).sort(distance($r));That last one computes a route, finds pharmacies within 200m of it, and sorts by distance — all in a single query. With traditional APIs, that’s 3 separate calls across 2 different services.
User prompt: “What’s the average restaurant capacity by cuisine in Manhattan?”
LLM-generated PlazaQL:
$manhattan = boundary(name: "Manhattan");$$ = search(amenity: "restaurant") .within(geometry: $manhattan) .filter(is_number(t["capacity"])) .group_by(t["cuisine"]) .avg(number(t["capacity"]));Aggregation queries return structured JSON — no post-processing needed. The LLM gets the answer in one call.
Send any of these to POST /api/v1/query and you get back GeoJSON. The LLM doesn’t need to know what categories exist ahead of time. It writes the query based on the tag system, which covers millions of attribute combinations.
If you’re building an AI agent that needs flexible geospatial queries, point it at this endpoint. Plaza also ships an MCP server (@plazafyi/mcp) with PlazaQL support built in, so Claude, GPT, or any MCP-compatible agent can run these queries directly.
Plaza vs Mapbox: Why This Matters for Your Stack
Section titled “Plaza vs Mapbox: Why This Matters for Your Stack”Mapbox is a solid product. The map rendering and geocoding work well. But pricing scales quickly, you can’t freely cache and store results, and you’re limited to the POI data Mapbox chooses to expose.
If you’re building something that needs flexible geographic queries, open data access, or lower per-request cost at scale, Plaza is worth evaluating. PlazaQL alone covers use cases that Mapbox simply does not offer. Plaza has no caching restrictions — store query results in your own database, build offline-capable features, whatever you need.
Try it free — no credit card needed.
What is PlazaQL used for? PlazaQL is a query language for geospatial data. Developers use it to retrieve geographic features filtered by tags and properties — finding all hospitals in a city, all bike lanes in a bounding box, or all restaurants with a specific cuisine type. It works across OpenStreetMap data, Plaza-curated datasets, and custom uploads.
Do I need to run my own server to query geospatial data? Not if you use Plaza. Plaza exposes a hosted PlazaQL endpoint so you can send queries directly via HTTP and get GeoJSON back without managing any infrastructure.
How is Plaza different from the public Overpass API? The public Overpass API at overpass-api.de is shared infrastructure with rate limits and no SLA. Plaza is a managed API with consistent availability, a cleaner query language, and no caching restrictions on the data you retrieve.
Is Plaza a good Mapbox alternative for geocoding?
Yes. Plaza supports geocoding, reverse geocoding, routing, and POI search alongside PlazaQL queries, all through one unified API at https://plaza.fyi/api/v1/. It’s designed as a drop-in replacement for Mapbox or Google Maps at a lower cost.
Can I use PlazaQL with LLM agents?
Yes. LLMs can generate PlazaQL from natural language prompts, which makes it a good fit for AI tool use and function calling. Plaza also ships an MCP server (@plazafyi/mcp) that exposes PlazaQL as a tool for any compatible AI agent.
Can I cache Plaza results for RAG or training data? Yes. You can cache, store, and reuse query results in vector databases, training pipelines, or any other system. OpenStreetMap data is open (ODbL), and other datasets carry their own license terms.
Can I use Plaza for commercial projects? Yes. Plaza is built for production use. Check plaza.fyi/pricing for current pricing tiers.
What response formats does Plaza support?
Most endpoints support three formats via the format parameter: geojson (default), json, and csv. The PlazaQL endpoint returns GeoJSON by default. See Streaming & Response Formats for details.
Is the data accurate enough for production apps? OpenStreetMap data quality varies by region but is generally strong in urban areas and improving globally. Plaza also curates additional open datasets to fill gaps. For many use cases — especially those requiring tag-level specificity — open data covers things that commercial datasets do not.