Distance from your coordinates to the matched place
coordinates
object
The lat/lng you sent, echoed back
is_open
bool | null
true if currently open, false if closed. null if the place has no hours data in OSM.
opens_at
string | null
Next opening time as HH:MM. Populated when the place is currently closed so you know when it reopens. null when open or unknown.
closes_at
string | null
Today's closing time as HH:MM. Populated when the place is open. null when closed or unknown.
opening_hours
string | null
Raw OpenStreetMap opening_hours string (e.g. Mo-Fr 09:00-18:00; Sa 10:00-17:00). null if not set in OSM.
cached
bool
true if served from 10-minute in-memory cache. Note: is_open, opens_at, and closes_at are always recalculated live against the current time, even on cache hits.
struct LabelResponse: Decodable {
let place: String?
let label: String
let category: String?
let distanceMeters: Double?
let isOpen: Bool?
let opensAt: String?
let closesAt: String?
let openingHours: String?
let cached: Bool
enum CodingKeys: String, CodingKey {
case place, label, category, cached
case distanceMeters = "distance_meters"case isOpen = "is_open"case opensAt = "opens_at"case closesAt = "closes_at"case openingHours = "opening_hours"
}
}
var components = URLComponents(string: "https://api.geolabel.dev/label")!
components.queryItems = [
URLQueryItem(name: "lat", value: "41.8827"),
URLQueryItem(name: "lng", value: "-87.6233"),
]
var request = URLRequest(url: components.url!)
request.setValue("your_key_here", forHTTPHeaderField: "X-API-Key")
let (data, _) = try await URLSession.shared.data(for: request)
let result = try JSONDecoder().decode(LabelResponse.self, from: data)
print(result.category ?? "") // → "gym"
── Step 1 ──────────────────────────────────────
Action: Get Current Location
Output: Current Location (lat + lng)
── Step 2 ──────────────────────────────────────
Action: Get Contents of URL
URL: https://api.geolabel.dev/label
Method: GET
Headers: X-API-Key → your_key_here
Params: lat → Latitude (from step 1)
lng → Longitude (from step 1)
── Step 3 — category (for logic) ───────────────
Action: Get Dictionary Value
Key: category
From: Contents of URL (step 2)
── Step 4 — label (for display) ────────────────
Action: Get Dictionary Value
Key: label
From: Contents of URL (step 2)
── Step 5 — hours ──────────────────────────────
Action: Get Dictionary Value
Key: is_open ← "true", "false", or empty
From: Contents of URL (step 2)
Action: Get Dictionary Value
Key: closes_at ← "23:00" when open, empty when closed
From: Contents of URL (step 2)
Action: Get Dictionary Value
Key: opens_at ← "09:00" when closed, empty when open
From: Contents of URL (step 2)
── Step 6 ──────────────────────────────────────
Action: If [category] equals "gym"
→ your actions here
End If
── Tip: use "Stop and Output" + Dictionary ─────
Build a Dictionary of all values, then
"Stop and Output" → Dictionary.
Calling shortcuts receive a clean object
with label, category, is_open, closes_at, etc.
Rate limit headers
Every response includes these headers so you always know where you stand.