NYC building data · REST API
One API for DOB BIS, DOB NOW, FDNY, HPD, LPC and OATH/ECB records. Ask how fresh any building is, trigger an on-demand refresh straight from the source agencies, then pull the structured data — paged just like Socrata, but current.
We pull from the agencies' own systems — DOB NOW's portal, FDNY's building-profile PDFs — which land days-to-weeks before the NYC Open Data mirrors catch up.
Don't wait for a nightly ETL. Ask for a refresh of a specific building and we re-fetch it now, within a 12-hour courtesy window so we never hammer the city sites.
Every building carries a single last-refreshed time. Poll it, decide if it's fresh enough for you, and only refresh when you actually need to.
Grab a key, then try the three core calls right here in the browser.
Free trial key, delivered instantly. Rate-limited and capped per day — enough to build and test.
Shown once at creation — stored only in this browser. Send it as Authorization: Bearer …
Runs against this API with your key. Enter a BIN or an address.
# 1. Sign up for a key
curl -s -X POST https://developers.citybuilder.nyc/api/v1/keys \
-H 'content-type: application/json' \
-d '{"email":"you@company.com"}'
# 2. How fresh is this building? (BIN or address)
curl -s https://developers.citybuilder.nyc/api/v1/freshness?bin=1001780 \
-H 'authorization: Bearer cb_live_…'
# 3. Not fresh enough? Ask for a refresh, then poll freshness again.
curl -s -X POST https://developers.citybuilder.nyc/api/v1/refresh \
-H 'authorization: Bearer cb_live_…' \
-H 'content-type: application/json' \
-d '{"address":"1 Centre St, Manhattan"}'
# 4. Pull the data for an agency (paged, max 1000/page)
curl -s 'https://developers.citybuilder.nyc/api/v1/data?bin=1001780&agency=DOB%20BIS&limit=100&offset=0' \
-H 'authorization: Bearer cb_live_…'Base URL https://developers.citybuilder.nyc/api/v1. Authenticate every request (except signup) with Authorization: Bearer <key> or X-API-Key.
/keysCreate a trial API key. Body: { "email": "you@company.com" }. The key is returned once.
/freshness?bin= | address= | q=Returns the building's last-refresh time and per-agency status, or found: false if we don't hold it yet. Pass a bin, an address, or q (auto-detected).
{
"found": true,
"bin": "1001780",
"address": "1 CENTRE STREET, MANHATTAN",
"lastRefreshedAt": "2026-07-08T18:20:11.004Z",
"ageSeconds": 512,
"canRefresh": false,
"cooldownRemainingSeconds": 42688,
"agencies": [
{ "id": "bis_jobs", "label": "BIS Jobs", "status": "ok", "count": 143, "source": "opendata" }
]
}/refreshKick off a refresh from the source agencies. Body: { "bin": "…" } or { "address": "…" }. Returns status: "ok" when started. Refusing with 429 refresh_cooldown means it was refreshed within the last 12h — keep reading it from /freshness. Then poll /freshness until the timestamp is new enough for you.
/data?bin= | address= &agency= &limit= &offset=Returns the stored records for one agency. agency is a dataset id (e.g. bis_jobs, fdny) or a group name (e.g. DOB BIS, HPD) which expands to all its datasets. Row datasets page with limit (max 1000) + offset.
/agenciesLists every dataset id, its label, and its group — the values /data accepts. No auth required.
/healthLiveness probe. No auth required.
bis_jobsbis_violationsnow_jobsnow_violationsnow_sooecb_violationscofofdnyhpd_violationshpd_complaintslpc_violationslpc_permits500 requests/day per key on the free trial. Response headers carry X-RateLimit-Remaining-Day and the reset time.
60 requests/minute per key. A 429 with Retry-After tells you when to resume.
A given building can only be refreshed once every 12 hours — shared across all clients, to protect the city's sites.