REST API v1Production

Building Health Intelligence API

Programmatic access to building distress scores, event histories, and property intelligence for 445,000+ NYC habitational buildings. Built on 25+ public data sources and 90 million+ events, updated daily.

View Documentation
445K+ Buildings
Every habitational building in NYC, scored and graded from A to F.
Multi-Component Model
Living conditions, complaint burden, building safety, financial distress, legal enforcement, maintenance quality.
Confidence Scoring
Coverage, freshness, and corroboration dimensions on every grade.
Daily Updates
25+ data sources refreshed daily. Scores recalculated on every update.

Validated to predict risk

The grade isn't descriptive — it's predictive. In a point-in-time, leakage-controlled backtest (grade as of a fixed date vs. what happened to each building afterward), the score strongly separates which buildings will have serious problems — the chronic, maintenance-driven conditions that drive attritional loss.

~100×

An F-graded building is ~100× more likely than an A to have a serious building problem (hazardous violation, eviction, emergency repair) in the following quarter.

0.87

AUC (Gini 0.74) — “strong-to-excellent” discrimination by standard risk-model benchmarks.

64%

The worst ~6% of buildings (grades D/F) capture ~64% of all serious adverse events — concentrated, actionable risk.

5/5

Separates risk within every borough (18–358×) and every building-size class — it reads the building, not the neighborhood.

Validated across 11 independent outcomes and government distress lists (HPD Underlying Conditions, CONH, AEP). The score predicts chronic, maintenance-driven distress (water damage, habitability) — not acute catastrophes or financial default. Full methodology available to API clients.

Quick Start

Authenticate with your API key via the Authorization: Bearer header. All responses return JSON with a consistent envelope.

Request
curl -H "Authorization: Bearer sk_live_your_key_here" \
  https://openstoop.com/api/v1/buildings/1004700039
Response
{
  "data": {
    "bbl": "1004700039",
    "address": "120 ELIZABETH STREET",
    "city": "New York",
    "zipcode": "10013",
    "borough": 1,
    "borough_name": "Manhattan",
    "residential_units": 22,
    "total_units": 24,
    "year_built": 1900,
    "building_class": "C7",
    "owner_name": "JING CHENG REALTY INC.",
    "latitude": 40.7192123,
    "longitude": -73.9952489,
    "scores": {
      "total_score": 83,
      "health_score": 17,
      "grade": "F",
      "label": "Distressed",
      "scorer_id": "distress_v10_2",
      "peer_group": "large-pre-war",
      "data_quality": "corroborated",
      "components": {
        "living_conditions":    { "score": 44.2, "grade": "C" },
        "building_safety":      { "score": 53.1, "grade": "D" },
        "complaint_burden":     { "score": 22.1, "grade": "B" },
        "management_quality":   { "score": 20.0, "grade": "B" },
        "financial_distress":   { "score":  0.0, "grade": "A" },
        "deferred_maintenance": { "score":  0.0, "grade": "A" },
        "legal_enforcement":    { "score": 21.9, "grade": "B" }
      },
      "flags": ["fdny-vacate-active"]
    },
    "counts": {
      "hpd_violations_total": 82,
      "hpd_violations_open": 43,
      "hpd_class_c_open": 11,
      "dob_violations_total": 11,
      "complaints_311": 17,
      "permits": 2,
      "total_events": 303
    },
    "confidence": {
      "score": 78.03,
      "tier": "corroborated",
      "flags": [],
      "dimensions": {
        "coverage": 68.06,
        "freshness": 98.49,
        "corroboration": 71.43
      },
      "primary_sources": 8,
      "active_families": 5
    }
  },
  "meta": {
    "request_id": "req_70fb907e8223",
    "api_version": "v1",
    "timestamp": "2026-04-03T15:53:55.286Z"
  },
  "pagination": null,
  "_links": {
    "self": "/api/v1/buildings/1004700039",
    "events": "/api/v1/buildings/1004700039/events",
    "trajectory": "/api/v1/buildings/1004700039/trajectory"
  }
}

Authentication

API keys use the format sk_live_... for client keys. The playground below uses a public read-only sk_demo_... key. Keys are SHA-256 hashed before storage and never stored in plaintext. All traffic is encrypted via TLS 1.3.

Bearer authentication (recommended)
curl -H "Authorization: Bearer sk_live_..." \
  https://openstoop.com/api/v1/buildings/1004700039
Header authentication (also supported)
curl -H "X-API-Key: sk_live_..." \
  https://openstoop.com/api/v1/buildings/1004700039

Key Security

SHA-256 hashed at rest. Cannot be retrieved after generation. Scoped permissions per key.

Transport Security

HTTPS only with TLS 1.3. HSTS enabled. All API traffic encrypted in transit.

Key Management

Keys can be revoked instantly. Revoked keys return 401 immediately. Contact us for rotation.

Try It

Test the API live. A public, read-only demo key is pre-filled and rate-limited — or use your own.

API Playground

Public demo key: read-only, rate-limited, and safe for testing. Replace it with your own key for production integrations.

GET
GET https://openstoop.com/api/v1/buildings/1004700039

API Reference

Base URL: https://openstoop.com/api/v1

Live Endpoints

GET/health

System health check. No authentication required.

Public
GET/buildings/:bbl

Single building lookup. Returns distress score, component breakdown, confidence metrics, event counts, and building metadata.

Scope: buildings:read · Cached
POST/buildings/batch

Batch lookup for up to 500 BBLs in a single request. Returns the same data as single lookup for each building.

Scope: buildings:read
GET/buildings/search

Search by address, owner name, zip code, or building class. Filter by grade range, score range, and flags.

Scope: buildings:query · Paginated
GET/buildings/:bbl/events

Paginated event history with filtering by source, category, severity, and date range. Covers HPD violations, DOB complaints, 311 calls, permits, litigation, and more.

Scope: events:read · Paginated · Filterable

Coming Soon

These endpoints are defined in the API surface and return structured responses, but are not yet fully implemented.

GET/buildings/:bbl/trajectory

Historical score trajectory over time. Shows how a building's grade has changed across scoring versions and data updates.

Scope: buildings:read · Q2 2026
POST/portfolio/analyze

Portfolio risk analysis. Submit up to 10,000 BBLs and receive grade distribution, worst buildings, aggregate risk metrics, and flag summary.

Scope: buildings:read · Q2 2026
POST/portfolio/monitor

Configure monitoring alerts for a building portfolio. Receive webhook notifications when buildings cross grade thresholds.

Scope: buildings:read · Q2 2026
POST/export/csv

Export building data as CSV for up to 10,000 buildings.

Scope: export:csv · Q2 2026

Response Envelope

Every response uses a consistent envelope. All field names are snake_case.

FieldTypeDescription
dataobjectResponse payload
meta.request_idstringUnique request identifier — include in support requests
meta.api_versionstringAPI version
meta.timestampstringISO 8601 UTC response timestamp
meta.rate_limitobjectCurrent rate limit status (limit, remaining, reset_at)
paginationobject | nullCursor-based pagination for list endpoints
_linksobjectRelated resource URLs

Errors

Errors use the same envelope with a machine-readable code. No internal details are exposed.

Error response
{
  "error": {
    "code": "building_not_found",
    "message": "Building 1000000000 not found",
    "status": 404
  },
  "meta": {
    "request_id": "req_abc123",
    "timestamp": "2026-03-30T12:00:00Z"
  }
}
StatusCodeWhen
400invalid_bblBBL is not a valid 10-digit number
400invalid_requestMalformed request body or parameters
401missing_api_keyNo API key provided
401invalid_api_keyKey is invalid, expired, or revoked
403insufficient_scopeKey lacks required permission scope
404building_not_foundBBL not in database
429rate_limit_exceededRate limit exceeded — see Retry-After header
500internal_errorServer error — include request_id when contacting support

Rate Limiting

Rate limits are per API key. Every response includes rate limit headers so your integration can adapt automatically.

HeaderDescription
X-RateLimit-LimitMaximum requests per window
X-RateLimit-RemainingRequests remaining in current window
X-RateLimit-ResetWindow reset time (ISO 8601)
Retry-AfterSeconds to wait before retrying (429 responses only)

Scoring

Each building receives a proprietary distress score (0-100) derived from multiple dimensions of building health. The model analyzes patterns across 25+ public data sources to produce a single grade from A (excellent) to F (distressed). Detailed methodology is available to API clients under NDA.

A
Excellent
B
Fair
C
Watch
D
Poor
F
Distressed

Data Sources

Scores are derived from 25+ NYC public data sources, cross-referenced and updated daily. The /sources endpoint is planned for source-level freshness data.

HPD Violations
HPD Complaint Problems
HPD Litigations
HPD Registrations
HPD Building Contacts
HPD Bedbug Reports
DOB Violations
DOB Complaints
DOB Permits
DOB Approved Permits
DOB NOW Inspections
DOB Facade (FISP)
DOB Elevator Inspections
DOB Certificate of Occupancy
311 Service Requests
ECB/OATH Violations
DOF Tax Liens
DOF Tax Rolls
FDNY Vacate Orders
Boiler Inspections
Water Tank Inspections
DHCR Rent Stabilization
ACRIS Property Transactions
PLUTO Property Records
Census Building Data
Housing Court Cases

Integration Examples

The API returns standard JSON over HTTPS. No SDK required.

Python
import requests

API_KEY = "sk_live_your_key_here"
BASE = "https://openstoop.com/api/v1"

# Look up a building
r = requests.get(f"{BASE}/buildings/1004700039",
    headers={"Authorization": f"Bearer {API_KEY}"})

building = r.json()["data"]
print(f"{building['address']}: Grade {building['scores']['grade']}")
# → 120 ELIZABETH STREET: Grade F

# Check components
for name, comp in building["scores"]["components"].items():
    print(f"  {name}: {comp['score']} ({comp['grade']})")

# Check confidence
conf = building["confidence"]
print(f"Confidence: {conf['score']} ({conf['tier']})")
print(f"  Coverage: {conf['dimensions']['coverage']}")
print(f"  Freshness: {conf['dimensions']['freshness']}")

Versioning

The API is versioned via URL path (/v1/). Breaking changes will only be introduced in new major versions. Existing versions remain supported with a minimum 12-month deprecation notice.

Changelog

v1.0March 2026

Initial release. Single building lookup, health endpoint, API index, confidence scoring, 7-component distress model (distress_v10_2).

Get Started

API Access

Contact us for API credentials, integration support, and custom data requirements.

Methodology

Detailed documentation of our scoring model, data sources, component weights, and grade system.

View methodology