Ship geospatial features on OpenStreetMap
Query for buildings, streets, parks, and more, get GeoJSON back, and start building in minutes. We run the infrastructure.
Everything on the map, available via API
OpenStreetMap contains the world's most detailed geographic dataset. We help you build geospatial features without running complex infrastructure yourself.
Live map fetching data from the OSM Features API for the selected tags preset and basemap style. For the complete dataset explorer and more about how this works, see the API Playground.
Features
- Planet-scale OpenStreetMap data in PostGIS, ready for production workloads.
- Weekly updates to keep map features current.
- Authenticated API access with low latency and production SLAs.
- Query with the OSM tags you already know: filter by
amenity=cafe,building=yes, or anykey=valuetag. Nodes, ways, and relations included. No proprietary schema. - Output as GeoJSON, FlatGeobuf, GeoParquet, or CSV. Works with Leaflet, MapLibre, OpenLayers, or plain JavaScript.
- No need to run your own OSM ingestion pipeline.
We offer support, collaboration, and consulting when you need it! Simply contact us.
A planet-scale Overpass alternative
Public Overpass servers are shared community infrastructure: great for prototypes, but they hit timeouts and latency spikes at production traffic. MapLark runs the same OSM tag semantics on dedicated PostGIS infrastructure, at full planet scale.
- Geometry you can compute on: Features arrive as full polygons, points, and lines with vertex rings you can use.
- Filter by tags: building footprints, charging stations within 500 m, or vegan cafes open after 4pm.
- Measured against public Overpass: consistent response times where Overpass swings widely under shared load, sometimes timing out.
Read the full write-up in Building the New OSM Features API: A Planet-Scale Overpass Alternative
Open standards vs proprietary platforms
Most map platforms help you draw a map. MapLark helps you query what is on it: buildings, roads, cafes, and the rest of OpenStreetMap, as GeoJSON you can use in code. Plenty of apps use both.
See how it is different from vector tiles in the blog post about our OSM Features API vs Vector Tiles article.
Built with MapLark
Real applications running on our platform. Want to list your app? Contact us.
Read the case study on how Urban Sun Finder scores sunlight using OSM building footprints.
Get Started
Try the curl command immediately with the free demo API key.
Want to see real implementations? The examples section walks through real map scenarios - from placing map markers to building Dijkstra routing on a live OSM network. Use the Python or npm osmfeatures package on to get started quickly .
curl "https://api.maplark.com/v2/osm_features?bbox=18.06,59.33,18.08,59.34&tags=building=yes&limit=50" \
-H "Authorization: Bearer swHAvOmreIm_uew6eqbn1UbIsVQT6p8PRohmqmAJiu4"# pip install osmfeatures
from osmfeatures import OSMFeaturesClient
with OSMFeaturesClient(api_key="swHAvOmreIm_uew6eqbn1UbIsVQT6p8PRohmqmAJiu4") as client:
fc = client.query(bbox="18.06,59.32,18.09,59.34", tags=["building"])
print(len(fc.features), "buildings found")// npm install osmfeatures
import { OSMFeatures } from 'osmfeatures';
const client = new OSMFeatures('swHAvOmreIm_uew6eqbn1UbIsVQT6p8PRohmqmAJiu4');
const page = await client.query({
bbox: '18.06,59.33,18.08,59.34',
tags: ['amenity=cafe'],
});
console.log(page.data.features.length);req, _ := http.NewRequest("GET",
"https://api.maplark.com/v2/osm_features", nil)
q := req.URL.Query()
q.Add("bbox", "18.06,59.33,18.08,59.34")
q.Add("tags", "amenity=cafe")
req.URL.RawQuery = q.Encode()
req.Header.Set("Authorization", "Bearer swHAvOmreIm_uew6eqbn1UbIsVQT6p8PRohmqmAJiu4")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
var geojson map[string]any
json.NewDecoder(resp.Body).Decode(&geojson)require "uri"
require "net/http"
require "json"
uri = URI("https://api.maplark.com/v2/osm_features")
uri.query = URI.encode_www_form(
bbox: "18.06,59.33,18.08,59.34",
tags: "amenity=cafe"
)
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer swHAvOmreIm_uew6eqbn1UbIsVQT6p8PRohmqmAJiu4"
res = Net::HTTP.start(uri.host, 443, use_ssl: true) { |h| h.request(req) }
data = JSON.parse(res.body)HttpClient client = HttpClient.newHttpClient();
String url = "https://api.maplark.com/v2/osm_features" +
"?bbox=18.06,59.33,18.08,59.34&tags=amenity%3Dcafe";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Authorization", "Bearer swHAvOmreIm_uew6eqbn1UbIsVQT6p8PRohmqmAJiu4")
.build();
HttpResponse<String> response =
client.send(request, HttpResponse.BodyHandlers.ofString());
JsonObject geojson = Json.createReader(
new StringReader(response.body())).readObject();var components = URLComponents(string:
"https://api.maplark.com/v2/osm_features")!
components.queryItems = [
URLQueryItem(name: "bbox", value: "18.06,59.33,18.08,59.34"),
URLQueryItem(name: "tags", value: "amenity=cafe"),
]
var request = URLRequest(url: components.url!)
request.setValue("Bearer swHAvOmreIm_uew6eqbn1UbIsVQT6p8PRohmqmAJiu4", forHTTPHeaderField: "Authorization")
let (data, _) = try await URLSession.shared.data(for: request)
let geojson = try JSONSerialization.jsonObject(with: data)Ready to query the world?
Generous free forever tier available with no payment method required.
Create free account