The LandBankSearch API
Every land bank and municipal-surplus listing in America — 50+ sources, normalized, refreshed nightly — behind one REST endpoint. Available on the Investor plan.
Authentication
Create keys under Account → API keys. Pass the key as a bearer token. Keys are shown once at creation and can be revoked instantly; canceling the Investor plan revokes all keys automatically.
curl -H "Authorization: Bearer lbs_live_..." \
"https://www.landbanksearch.com/api/v1/parcels?state=OH&max_price=10000"List parcels
GET /api/v1/parcelsReturns active listings ordered by id, with keyset pagination — request the next page by passing next_cursor as after. All filters combine with AND.
| Parameter | Type | Description |
|---|---|---|
| limit | int | Page size, 1–1000 (default 100). |
| after | uuid | Keyset cursor — pass the previous page's next_cursor. |
| state | string | 2-letter state code, e.g. OH. |
| min_price / max_price | number | Asking-price band in USD. |
| min_acres / max_acres | number | Lot-size band in acres. |
| auction | boolean | Only auction (true) or non-auction (false) listings. |
| has_structure | boolean | true = has a building; false = vacant land. |
| tag | string | Program tag: side_lot, development_ready, opportunity_zone, adjoining_owner_only. |
| first_seen_since | ISO date | Only parcels first seen on/after this date — poll with this for new inventory. |
Response
{
"data": [
{
"id": "0c1de…", "address": "4142 Lawton St", "city": "Detroit", "state": "MI",
"price": 4500, "acres": 0.11, "auction": false, "has_structure": true,
"tags": ["side_lot"], "listing_url": "https://…", "source": "detroit_dlba",
"assessed_value": 12000, "assessed_value_year": 2025,
"first_seen": "2026-07-01T07:12:03Z",
"page_details": { "beds": 3, "baths": 1 },
"lng": -83.10, "lat": 42.35
}
],
"next_cursor": "0c1de…" // null on the last page
}Bulk download
GET /api/v1/export/latestThe entire active dataset as one file, regenerated nightly. Returns a signed URL valid for 15 minutes; ?format=csv (default) or ?format=ndjson. 4 downloads per day per key.
curl -H "Authorization: Bearer lbs_live_..." \
"https://www.landbanksearch.com/api/v1/export/latest?format=ndjson"
{ "url": "https://…signed…", "file": "parcels-2026-07-04.ndjson.gz", "expires_in": 900 }Webhook alerts
PUT /api/v1/webhookRegister one https endpoint per account; after each nightly refresh, every saved search with new matches POSTs them to it as JSON. Verify deliveries by recomputing HMAC-SHA256 of the raw body with your signing secret (returned once at registration) against the X-LandBankSearch-Signature header. Five consecutive failures disable the endpoint; re-register to re-enable. GET shows status, DELETE unregisters.
curl -X PUT -H "Authorization: Bearer lbs_live_..." \
-d '{"url":"https://hooks.example.com/landbank"}' \
"https://www.landbanksearch.com/api/v1/webhook"
{ "url": "https://hooks.example.com/landbank", "secret": "…shown once…" }
# each delivery:
# X-LandBankSearch-Signature: sha256=<hmac_sha256(body, secret)>
{ "event": "saved_search.matches", "search_id": "…", "matches": [ … ] }Limits & freshness
- • 600 requests per minute and 100,000 per calendar month per key; 429 with a clear message beyond either. Month-to-date usage shows on your account page.
- • Data refreshes nightly from every source — poll once a day with
first_seen_sincefor new inventory. - • Errors are named: 401 bad key, 400 bad filter (with the reason), 429 rate.
- • OpenAPI spec: /api/v1/openapi