Quickstart
Five minutes from zero to a page of listings. You need a key from the sign-in page (one email click; the Free plan needs no card).
1. First request
export LF_KEY=lf_live_…
curl -s -H "Authorization: Bearer $LF_KEY" \
"https://listingsfeed.com/v1/listings?state=TX&property_type=industrial&min_sf=50000&limit=5" | jq .
The response has three parts: data (the listings), meta (count, cursor, what you were billed, your quota) and links.next (the next page URL, or null).
2. Python
import os, requests
BASE = "https://listingsfeed.com/v1"
H = {"Authorization": f"Bearer {os.environ['LF_KEY']}"}
def listings(**params):
"""Yield every listing matching params, following cursors."""
while True:
r = requests.get(f"{BASE}/listings", headers=H, params=params, timeout=30)
r.raise_for_status()
body = r.json()
yield from body["data"]
cursor = body["meta"]["next_cursor"]
if not cursor:
return
params = {**params, "cursor": cursor}
for row in listings(state="TX", property_type="industrial", min_sf="50k", limit=100):
print(row["hash_id"], row["city"], row["building_sf"], row["sale_ask_total"])
3. JavaScript / TypeScript
const BASE = "https://listingsfeed.com/v1";
const headers = { Authorization: `Bearer ${process.env.LF_KEY}` };
async function* listings(params) {
let cursor;
do {
const qs = new URLSearchParams({ ...params, ...(cursor ? { cursor } : {}) });
const res = await fetch(`${BASE}/listings?${qs}`, { headers });
if (!res.ok) throw new Error(`${res.status}: ${(await res.json()).error.message}`);
const body = await res.json();
yield* body.data;
cursor = body.meta.next_cursor;
} while (cursor);
}
for await (const l of listings({ state: "TX", property_type: "industrial", limit: "100" })) {
console.log(l.hash_id, l.city, l.building_sf);
}
4. Keep a local copy in sync
Store updated_at from your last run and ask for changes only. Include inactive rows (Team plan and above) so removals reach you too.
curl -s -H "Authorization: Bearer $LF_KEY" \
"https://listingsfeed.com/v1/listings?updated_since=2026-09-18T00:00:00Z&include_inactive=1&sort=updated_at&order=asc&limit=1000"
5. CSV and GeoJSON
# CSV, one page per call (plan-sized), next page in the X-Next-Cursor header
curl -s -D - -H "Authorization: Bearer $LF_KEY" \
"https://listingsfeed.com/v1/listings?state=OR&format=csv&limit=500" -o oregon.csv
# GeoJSON FeatureCollection — drop straight into QGIS, Mapbox, Leaflet
curl -s -H "Authorization: Bearer $LF_KEY" \
"https://listingsfeed.com/v1/listings?bbox=-97.6,32.5,-96.9,33.1&format=geojson&limit=1000" -o dfw.geojson
For a one-off file without code, use the builder.
6. From an AI assistant
Add the MCP server and ask in plain language: "find industrial buildings over 100k SF for sale within 30 miles of Dallas and give me the brokers." Setup for Claude, ChatGPT and Cursor is on the MCP page.
7. Generate a client
npx @openapitools/openapi-generator-cli generate -i https://listingsfeed.com/openapi.json -g typescript-fetch -o ./listingsfeed
# or
openapi-python-client generate --url https://listingsfeed.com/openapi.json