Introduction
The LocalityBiz API exposes the same business directory that powers the public site. Four endpoints:
- Locations — country / region / city directory used to build
regioncodes for Search. Free — never counts against either monthly quota. - Categories — two-level taxonomy used to build the
categoryfilter for Search. Free. - Search — full-text search inside a directory
regionOR a(lat, lng, radius_km)circle. - Business detail — full profile (hours, phones, websites, photos, amenities, services, reviews).
The base URL is https://localitybiz.at/api/v1. All responses are JSON, UTF-8. The API never makes write requests; it is read-only.
Authentication
Every request needs an API key. Pass it as a Bearer token in the Authorization header:
curl "https://localitybiz.at/api/v1/search?q=pizza&lat=40.7128&lng=-74.0060&radius_km=2" \
-H "Authorization: Bearer lk_a3f9b1c7XXXXXXXXXXXXXXXXXXXXXXXX"
Or as a query parameter (handy for quick tests; never use this in production code):
curl "https://localitybiz.at/api/v1/search?api_key=lk_a3f9b1c7XXXXXXXXXXXXXXXXXXXXXXXX&q=pizza&lat=40.7128&lng=-74.0060&radius_km=2"
search, business or all endpoints, and optionally restricted to up to 20 source IPs.
Quotas & rate limits
Each subscription has two monthly quotas — one for search, one for business detail. They reset at the start of every Stripe billing period. The current usage is mirrored on every response inside a quota object:
"quota": {
"limit": 5000,
"used": 342,
"remaining": 4658,
"resets_at": "2026-07-01T00:00:00+00:00",
"type": "search"
}
When a quota is exhausted, the API returns HTTP 429 Too Many Requests with a Retry-After header in seconds. There is no per-second rate limit beyond the monthly quota.
Error handling
Every error has a paired HTTP status and a machine-readable JSON error.code:
| HTTP | error.code | Cause |
|---|---|---|
| 400 | bad_request | Missing or invalid parameter. details lists the offending fields. |
| 401 | unauthorized / invalid_key | No key, or key not recognised / revoked. |
| 402 | subscription_inactive | Account has no active subscription (canceled, past_due, etc.). |
| 403 | ip_not_whitelisted / scope_denied | IP not in this key's whitelist, or the endpoint type is outside the key's scope. |
| 404 | not_found | Business id unknown. |
| 429 | quota_exceeded | Monthly quota for this endpoint type hit. Retry-After header points at the next reset. |
Example 429 body:
{
"success": false,
"error": {
"code": "quota_exceeded",
"message": "Monthly request limit exceeded for your plan.",
"details": {
"limit": 5000,
"used": 5000,
"remaining": 0,
"resets_at": "2026-07-01T00:00:00+00:00",
"type": "search"
}
}
}
Response envelope
Every successful response has the shape:
{
"success": true,
"data": /* the payload — object or array */,
"meta": /* pagination / query echo (search only) */,
"quota": /* usage snapshot — see "Quotas" */
}
Every error response has the shape:
{
"success": false,
"error": { "code": "...", "message": "...", "details": { ... } },
"quota": /* present only when the error is quota-related */
}
Locations directory
GET /api/v1/locations
Three-level country / region / city tree. Any region or city code returned here can be passed verbatim to Search as the region parameter. Free: requires an API key but never counts against either monthly quota. Cached server-side for 24 hours.
Example request
curl "https://localitybiz.at/api/v1/locations" \
-H "Authorization: Bearer lk_YOUR_KEY_HERE"
Example response
{
"success": true,
"data": [
{
"country": "United States",
"regions": [
{
"code": "605",
"name": "Arizona",
"cities": [
{ "code": "605_1322", "name": "Buckeye" },
{ "code": "605_1419", "name": "Phoenix" }
]
},
{
"code": "612",
"name": "Colorado",
"cities": [
{ "code": "612_1707", "name": "Denver" }
]
}
]
},
{
"country": "Poland",
"regions": [
{
"code": "812",
"name": "Mazowieckie",
"cities": [
{ "code": "812_2031", "name": "Warszawa" }
]
}
]
}
]
}
code:
- Region-wide search: pass
region=605(whole Arizona). - City-narrowed search: pass
region=605_1322(only Buckeye, AZ). - Country code is omitted — you cannot search by country directly. Pick a region inside it.
Categories directory
GET /api/v1/categories
Hierarchical schema.org-style taxonomy (up to three levels deep). Each entry carries a code that you pass to Search as category, and a human-readable name. Children appear inside a nested children array; leaf nodes omit that field entirely. Free: requires an API key but never counts against either monthly quota. Cached server-side for 24 hours.
Example request
curl "https://localitybiz.at/api/v1/categories" \
-H "Authorization: Bearer lk_YOUR_KEY_HERE"
Example response
{
"success": true,
"data": [
{
"code": "FoodEstablishment",
"name": "Food & drink",
"children": [
{
"code": "Restaurant",
"name": "Restaurant",
"children": [
{ "code": "PizzaShop", "name": "Pizza shop" },
{ "code": "FastFoodRestaurant", "name": "Fast food restaurant" }
]
},
{ "code": "CafeOrCoffeeShop", "name": "Café & coffee shop" },
{ "code": "BarOrPub", "name": "Bar & pub" }
]
},
{
"code": "MedicalBusiness",
"name": "Medical services",
"children": [
{ "code": "Dentist", "name": "Dentist" },
{ "code": "Physician","name": "Doctor / physician" }
]
}
]
}
code: pass it verbatim as the category filter on /search — e.g. category=Restaurant. Any code at any level works: pick a top-level code for a broad match, a deeper one for a narrow match.
Search
GET /api/v1/search
Full-text business search by EITHER a directory region code OR a (lat, lng, radius_km) circle. Exactly one of the two location modes is required — if region is provided, the geo parameters are ignored. Counts against the search monthly quota.
Up to 30 results per page. When more pages exist the response carries a meta.next_page URL ready to follow; on the last (or only) page that field is omitted. The meta.page_size value reports how many items are actually in data for the current response — full pages, partial last page, or zero on no match.
Parameters
| Name | Type | Description |
|---|---|---|
qrequired | string | Search query. Max 200 characters. |
region | string | Region or region+city code from /locations. " for the whole region, " for one city inside it. When present, lat/lng/radius_km are ignored. |
lat | number | Latitude of centre, decimal degrees, -90 to 90. Required when region is omitted. |
lng | number | Longitude of centre, decimal degrees, -180 to 180. Required when region is omitted. |
radius_km | number | Search radius in kilometres. Max 50. Required when region is omitted. |
page | integer | 1-based page. 30 results per page. |
category | string | Filter by schema.org type code (e.g. Restaurant, Dentist, NailSalon). |
min_rating | number | 0–5. Only businesses rated at or above this value. |
has_phone | boolean | If true, drops records that have no phone number. |
Example: search inside a region
curl "https://localitybiz.at/api/v1/search?q=pizza®ion=605_1322&min_rating=4" \
-H "Authorization: Bearer lk_YOUR_KEY_HERE"
Example: search inside a circle
curl "https://localitybiz.at/api/v1/search?q=pizza&lat=40.7128&lng=-74.0060&radius_km=2&min_rating=4" \
-H "Authorization: Bearer lk_YOUR_KEY_HERE"
Example response
{
"success": true,
"data": [
{
"id": 33597009,
"name": "Joe's Pizza Greenwich Village",
"address": "7 Carmine St, New York, NY 10014",
"lat": 40.7305,
"lng": -74.0027,
"distance_km": 2.124,
"phone": "+1 212-366-1182",
"rating": 4.6,
"ratings_count": 18421,
"main_category": "Restaurant",
"details_url": "https://localitybiz.at/api/v1/business/33597009"
}
/* … up to 30 items */
],
"meta": {
"page": 1,
"page_size": 30, // count of items actually in `data` (0 .. 30)
"query": {
"q": "pizza",
"lat": 40.7128,
"lng": -74.006,
"radius_km": 2,
"filters": { "category": null, "min_rating": 4, "has_phone": null }
},
"next_page": "https://localitybiz.at/api/v1/search?q=pizza&lat=40.7128&lng=-74.006&radius_km=2&min_rating=4&page=2"
},
"quota": {
"limit": 5000,
"used": 343,
"remaining": 4657,
"resets_at": "2026-07-01T00:00:00+00:00",
"type": "search"
}
}
Business detail
GET /api/v1/business/{id}
Full business profile by id (the same id returned in the search response). Counts against the business monthly quota. Returns up to 5 photos and 5 reviews.
Example request
curl "https://localitybiz.at/api/v1/business/33597009" \
-H "Authorization: Bearer lk_YOUR_KEY_HERE"
Example response
{
"success": true,
"data": {
"id": 33597009,
"name": "Joe's Pizza Greenwich Village",
"rating": 4.6,
"ratings_count": 18421,
"phones": [
{ "value": "+1 212-366-1182", "primary": true, "note": null }
],
"websites": [
{ "url": "https://joespizzanyc.com", "primary": true, "note": null }
],
"emails": [],
"address": {
"full": "7 Carmine St, New York, NY 10014, USA",
"street": "7 Carmine St",
"locality": "New York",
"sub_locality": "Greenwich Village",
"region": "New York",
"postal_code": "10014",
"country_code": "US"
},
"coords": { "lat": 40.7305, "lng": -74.0027 },
"categories": [
{ "code": "Restaurant", "name": "Restaurant" },
{ "code": "PizzaShop", "name": "Pizza shop" }
],
"description": "Joe's Pizza has served classic NY slices since 1975 …",
"photos": [
{ "url": "https://cdn.localitybiz.com/photo1.webp" }
],
"hours": [
{ "day_of_week": 1, "open": "10:00", "close": "22:00", "pause_from": null, "pause_till": null, "notes": null }
],
"services": [ { "name": "Delivery" }, { "name": "Takeout" } ],
"amenities": [
{ "code": "accepts_credit_cards", "name": "Accepts credit cards", "category": "payment", "icon": "💳" }
],
"reviews": [
{ "author": "Anna K.", "rating": 5, "text": "Best slice in NYC.", "published_at": "2026-04-12T18:34:00+00:00" }
],
"urls": { "public": "https://localitybiz.com/33597009/joes-pizza-greenwich-village" }
},
"quota": {
"limit": 5000,
"used": 11,
"remaining": 4989,
"resets_at": "2026-07-01T00:00:00+00:00",
"type": "business"
}
}
Pricing & plans
Monthly subscription, billed by Stripe in EUR. Plan changes (upgrades only) and cancellations happen in the Stripe-hosted Customer Portal accessible from your dashboard.
Basic
- 5,000 search requests/mo
- 5,000 business detail requests/mo
Pro
- 50,000 search requests/mo
- 50,000 business detail requests/mo
Premium
- 150,000 search requests/mo
- 150,000 business detail requests/mo
Enterprise
- 1,000,000 search requests/mo
- 1,000,000 business detail requests/mo
Subscribe / manage your plan →
OpenAPI spec
The machine-readable specification is at https://localitybiz.at/developers/openapi.json. Drop the URL into Postman, Insomnia, or OpenAPI Generator to scaffold a client library in your language of choice.
Changelog
v1.0.0 — initial public release. Four endpoints: /locations, /categories, /search, /business/{id}. EUR-billed monthly subscriptions via Stripe Checkout + Customer Portal.