Uman Map Public API

Read-only REST access to the data published on the public Uman map: border crossing status, points of interest, routes, flights, zmanim and travel content.

Base URLhttps://api-pub.umanmap.eu/v1
AuthNone. Every resource here is already public on the map.
MethodsGET, OPTIONS. Writes are not accepted.
CORSAccess-Control-Allow-Origin: * — browser calls work directly.
Rate limit120 requests per rolling 60 seconds, per client IP. See X-RateLimit-Limit, -Remaining, -Reset, -Policy and Retry-After.

GET /v1 returns a machine-readable index of every resource, so a client can discover the surface without reading this page.

Response shape

Every JSON response is an envelope with two keys. data is the payload; meta describes it.

{
  "data": { … },
  "meta": {
    "resource":     "borders",
    "generated_at": "2026-08-09T18:52:47+00:00",
    "age_seconds":  0,
    "ttl_seconds":  60,
    "stale":        false,
    "attribution":  [ { "name": "granica.gov.pl · CC BY 4.0", "url": null } ],
    "license":      "…"
  }
}

When the upstream source is briefly unreachable the last known good copy is served with meta.stale: true and a real age_seconds, rather than an error — a map being read at a border crossing is more useful slightly late than not at all. Check meta.stale if freshness matters to you.

Attribution is a licence condition, not a courtesy. Border readings come from national border services — among them granica.gov.pl, published under CC BY 4.0. Whatever appears in meta.attribution for a response must be shown wherever you display that data. Dropping the credit line is a licence breach.

Resources

Borders and geography

EndpointReturns
/v1/bordersComputed crossing status per crossing: congestion level, wait minutes, feed, verified flag, age. Keyed by crossing id.
/v1/crossingsCrossing catalogue: names, coordinates, countries, opening hours, vehicle limits.
/v1/countriesCountry list with flags and colours.
/v1/airportsAirport catalogue.
/v1/routesRoute definitions, overrides and waypoints — without geometry.
/v1/routes/{id}/geometryOne route's polyline. Use this instead of pulling all geometry.
/v1/geometryEvery route polyline in one object, keyed by route id. ~3.5 MB — see the size table below before reaching for it.
/v1/road-conditionsIncidents and traffic-flow readings, with per-feed credits.
/v1/directionCurrent travel direction of the pilgrimage (to Uman / from Uman).

Places — search and proximity

These two share one filter set. Use /v1/nearby when you have a coordinate (a chat user sharing their location, say) and /v1/places when you have words. Both search all 15 layers at once — about 685 points.

EndpointReturns
/v1/nearbyPoints around a coordinate, nearest first, each with distance_m. Requires lat and lng.
/v1/placesThe same filters without a location; ordered by name. Pass lat/lng anyway and it orders by distance too.
ParameterMeaning
lat, lngOrigin. Required for /v1/nearby, optional for /v1/places.
radiusMetres, 1–500000. Default 5000 on nearby; uncapped on places unless given.
layersComma-separated layer codes, e.g. uman_shuls,mikvah.
categoryComma-separated categories: religious, food, services, safety.
qFree text, matched case-insensitively against name, address, city, layer label and attribute values. Works in Hebrew.
hasOnly points carrying these attributes, e.g. has=phone.
scopeall (default), global (wider region) or uman (inside the city).
limit, offsetPage size 1–200 (default 20) and offset. meta.total_matched gives the full count.

Each result carries name, name_en, address, city, lat, lng, its layer with the layer's Hebrew layer_name, icon and category, an attrs object (phone, hours, kashrut, website, subtype where the operator supplied them), and a ready maps_url.

distance_m is straight-line, not driving distance. It is a haversine calculation. Turning it into a road distance would mean a metered routing call per result, which this API deliberately does not expose. Sort and filter by it; do not present it as travel distance.

Layers and overlays

EndpointReturns
/v1/layersAll 15 layers with code, Hebrew and English names, icon, colour, category, scope and item_count. Accepts ?scope=all|global|uman.
/v1/layers/{code}/itemsEvery approved public point in one layer, unfiltered.
/v1/layers/{code}/polygonsPolygon overlays attached to a layer, if any.
/v1/eruvThe Shabbat eruv map. Returns application/pdf, not JSON.

Layers split across two scopes: the wider region (mikvah, tombs, kosher_food, gas, bus_parking, emergency, layer) and Uman city itself (hotels, uman_shuls, uman_mikvahs, uman_kosher, uman_grocery, uman_atm, uman_banks, uman_medical). Search endpoints cover both by default. Read /v1/layers rather than hard-coding this list.

Some points appear in both a regional and an Uman layer — the same mikvah can be listed twice with different ids. Deduplicate on coordinates if that matters to you.

Travel and time

EndpointParameters
/v1/flightsairport — IATA or ICAO code, required.
/v1/zmanimlat, lng required; date (YYYY-MM-DD) defaults to today UTC.
/v1/weatherlat, lng — both required.
/v1/study-calendardate — YYYY-MM-DD.
/v1/fxNone. Exchange rates.

Content

EndpointReturns
/v1/announcementsActive public announcements.
/v1/contactsCurated public hotline list — only entries explicitly published by the operator.
/v1/aboutAbout / informational content.
/v1/content/umanUman city guide content.
/v1/bundleEverything above in one call. ?scope=global|uman, ?include=geometry.
/v1/healthLiveness of this host. Does not touch the data source.

Payload sizes

Route geometry is roughly 98% of the total data. /v1/bundle therefore omits it unless you ask:

RequestUncompressedgzip
/v1/bundle~66 KB~11 KB
/v1/bundle?include=geometry~3.6 MB~1.1 MB
/v1/geometry~3.5 MB~1.1 MB
/v1/routes/{id}/geometry75–95 KB23–29 KB

Send Accept-Encoding: gzip. Prefer a single /v1/bundle over fifteen catalogue calls.

Caching

Responses carry ETag and Cache-Control. Send the ETag back as If-None-Match to get 304 Not Modified and no body. X-Cache reports HIT or MISS.

Border status has a 60-second TTL; catalogues 5 minutes; geometry and the eruv PDF far longer. Polling faster than the TTL only spends your rate limit — it cannot return fresher data.

For change detection, /v1/bundle exposes poll_version: an opaque digest that changes when the underlying data changes. Compare it, do not parse it.

Errors

{ "error": "bad_param", "detail": "Invalid value for 'lat'." }
StatusMeaning
400Bad or missing parameter.
404Unknown path, or the resource genuinely does not exist upstream.
405Write method attempted. This API is read-only.
429Rate limit exceeded. Honour Retry-After. The window is rolling, so pacing below 2 requests per second never trips it, and throttled requests are not counted against you — the bucket drains on schedule.
502Data source unreachable and no cached copy exists.

Examples

# Discover the surface
curl https://api-pub.umanmap.eu/v1

# Border status, compressed
curl -H 'Accept-Encoding: gzip' --compressed \
     https://api-pub.umanmap.eu/v1/borders

# A chat user shared their location — what is within 1 km?
curl 'https://api-pub.umanmap.eu/v1/nearby?lat=48.7519&lng=30.2158&radius=1000&limit=8'

# Kosher food near them, only entries that list a phone number
curl 'https://api-pub.umanmap.eu/v1/nearby?lat=48.7519&lng=30.2158&category=food&has=phone'

# Nearest synagogues, two specific layers
curl 'https://api-pub.umanmap.eu/v1/nearby?lat=48.7519&lng=30.2158&layers=uman_shuls,mikvah&limit=5'

# Text search, no location needed
curl 'https://api-pub.umanmap.eu/v1/places?q=hotel&limit=10'

# What can I filter by?
curl https://api-pub.umanmap.eu/v1/layers

# Zmanim for Uman today
curl 'https://api-pub.umanmap.eu/v1/zmanim?lat=48.75&lng=30.22'

# Everything except geometry, in one call
curl 'https://api-pub.umanmap.eu/v1/bundle?scope=uman'

# The eruv map (PDF)
curl -o eruv.pdf https://api-pub.umanmap.eu/v1/eruv

Notes and limits