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 URL | https://api-pub.umanmap.eu/v1 |
|---|---|
| Auth | None. Every resource here is already public on the map. |
| Methods | GET, OPTIONS. Writes are not accepted. |
| CORS | Access-Control-Allow-Origin: * — browser calls work directly. |
| Rate limit | 120 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.
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.
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.
| Endpoint | Returns |
|---|---|
/v1/borders | Computed crossing status per crossing: congestion level, wait minutes, feed, verified flag, age. Keyed by crossing id. |
/v1/crossings | Crossing catalogue: names, coordinates, countries, opening hours, vehicle limits. |
/v1/countries | Country list with flags and colours. |
/v1/airports | Airport catalogue. |
/v1/routes | Route definitions, overrides and waypoints — without geometry. |
/v1/routes/{id}/geometry | One route's polyline. Use this instead of pulling all geometry. |
/v1/geometry | Every route polyline in one object, keyed by route id. ~3.5 MB — see the size table below before reaching for it. |
/v1/road-conditions | Incidents and traffic-flow readings, with per-feed credits. |
/v1/direction | Current travel direction of the pilgrimage (to Uman / from Uman). |
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.
| Endpoint | Returns |
|---|---|
/v1/nearby | Points around a coordinate, nearest first, each with distance_m. Requires lat and lng. |
/v1/places | The same filters without a location; ordered by name. Pass lat/lng anyway and it orders by distance too. |
| Parameter | Meaning |
|---|---|
lat, lng | Origin. Required for /v1/nearby, optional for /v1/places. |
radius | Metres, 1–500000. Default 5000 on nearby; uncapped on places unless given. |
layers | Comma-separated layer codes, e.g. uman_shuls,mikvah. |
category | Comma-separated categories: religious, food, services, safety. |
q | Free text, matched case-insensitively against name, address, city, layer label and attribute values. Works in Hebrew. |
has | Only points carrying these attributes, e.g. has=phone. |
scope | all (default), global (wider region) or uman (inside the city). |
limit, offset | Page 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.
| Endpoint | Returns |
|---|---|
/v1/layers | All 15 layers with code, Hebrew and English names, icon, colour, category, scope and item_count. Accepts ?scope=all|global|uman. |
/v1/layers/{code}/items | Every approved public point in one layer, unfiltered. |
/v1/layers/{code}/polygons | Polygon overlays attached to a layer, if any. |
/v1/eruv | The 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.
| Endpoint | Parameters |
|---|---|
/v1/flights | airport — IATA or ICAO code, required. |
/v1/zmanim | lat, lng required; date (YYYY-MM-DD) defaults to today UTC. |
/v1/weather | lat, lng — both required. |
/v1/study-calendar | date — YYYY-MM-DD. |
/v1/fx | None. Exchange rates. |
| Endpoint | Returns |
|---|---|
/v1/announcements | Active public announcements. |
/v1/contacts | Curated public hotline list — only entries explicitly published by the operator. |
/v1/about | About / informational content. |
/v1/content/uman | Uman city guide content. |
/v1/bundle | Everything above in one call. ?scope=global|uman, ?include=geometry. |
/v1/health | Liveness of this host. Does not touch the data source. |
Route geometry is roughly 98% of the total data. /v1/bundle therefore omits it
unless you ask:
| Request | Uncompressed | gzip |
|---|---|---|
/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}/geometry | 75–95 KB | 23–29 KB |
Send Accept-Encoding: gzip. Prefer a single /v1/bundle over
fifteen catalogue calls.
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.
{ "error": "bad_param", "detail": "Invalid value for 'lat'." }
| Status | Meaning |
|---|---|
400 | Bad or missing parameter. |
404 | Unknown path, or the resource genuinely does not exist upstream. |
405 | Write method attempted. This API is read-only. |
429 | Rate 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. |
502 | Data source unreachable and no cached copy exists. |
# 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
/v1 is stable. Breaking changes will appear under a new version prefix.