API Reference
All endpoints return JSON and are CORS-enabled. Base URL: https://lotlyze.com. API access is included with a Pro subscription. Upgrade at lotlyze.com/sign-up to receive your API key. For Chicago addresses and Cook County PINs, use /api/chicago-units; the other property endpoints cover NYC. Response examples are shortened, and their values are illustrative; field names match the live API.
Authentication
Pass your API key in the Authorization header on every request. Free accounts have no API access. Requests without a valid Pro key return 401.
curl "https://lotlyze.com/api/lookup?query=3016070023" \
-H "Authorization: Bearer YOUR_API_KEY"const API_KEY = "YOUR_API_KEY"; // from lotlyze.com/account
const res = await fetch(
"https://lotlyze.com/api/lookup?query=3016070023",
{ headers: { Authorization: `Bearer ${API_KEY}` } }
);
const data = await res.json();import httpx
API_KEY = "YOUR_API_KEY" # from lotlyze.com/account
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
data = httpx.get(
"https://lotlyze.com/api/lookup",
params={"query": "3016070023"},
headers=HEADERS,
).json()Where to find your key
- Sign in at lotlyze.com/sign-in
- Go to My Account
- Copy the key from the API Key section
- Use it in the
Authorization: Bearer <key>header
Error responses
| Status | Meaning | Action |
|---|---|---|
400 | Missing or invalid parameter | Check the parameter format for the endpoint |
401 | Missing or invalid API key | Upgrade at lotlyze.com/sign-up for Pro API access |
404 | No property matches the query (lookup, property) | Check the address, BBL, or BIN |
429 | Request volume temporarily limited | Retry after a short delay |
500 / 502 | A public data source failed or timed out | Retry after a short delay |
503 | Auth service temporarily unavailable | Retry after a short delay |
/api/lookupResolve any NYC address, BBL, or BIN to canonical identifiers.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
query | string | Yes | Address, 10-digit BBL, hyphenated BBL, or 7-digit BIN |
Example
curl "https://lotlyze.com/api/lookup?query=250+Broadway+Manhattan" \
-H "Authorization: Bearer YOUR_API_KEY"const res = await fetch(
"https://lotlyze.com/api/lookup?query=250+Broadway+Manhattan",
{ headers: { Authorization: "Bearer YOUR_API_KEY" } }
);
const { bbl, bin, label } = await res.json();Response
{
"type": "address",
"bbl": "1001247502",
"bin": "1001408",
"label": "250 B'WAY, New York, NY, USA",
"source": "geosearch"
}For a BBL or BIN query, type is bbl or bin, source is pad, and there is no label. The bin field can be null when no building is on file for the lot. An unknown BIN or address returns 404.
/api/chicago-unitsLook up the best public evidence of a Chicago 2–6 unit residential building's dwelling-unit count, plus building facts, the owner of record, the Assessor's value, the last permit for each building system, permits, violations, and sales history. Zoning, nearby district classes, parcel coordinates, and 2021 parcel outlines are available for all Chicago property classes, including those with an unsupported unit count. Optionally compare user-entered listing figures. Requires a Pro API key.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
query | string | Yes | Chicago street address, 14-digit Cook County PIN (dashes accepted), or a Chicago Redfin/Zillow property URL. Only the address in the URL is read; no listing is fetched. Resolved query maximum: 200 characters. |
price | number | No | Asking price ($). 1–1,000,000,000, increments of 0.01. Blank means unknown. |
units | number | No | Listing units. 1–1,000, increments of 1. Blank means unknown. |
bedrooms | number | No | Listing bedrooms. 0–1,000, increments of 1. Blank means unknown. |
baths | number | No | Listing baths (half = 0.5). 0–1,000, increments of 0.5. Blank means unknown. |
buildingSqft | number | No | Listing building sq ft. 1–10,000,000, increments of 0.01. Blank means unknown. |
landSqft | number | No | Listing lot sq ft. 1–100,000,000, increments of 0.01. Blank means unknown. |
rent1–rent6 | number | No | Legacy listing-comparison assumptions: 0–100,000 dollars/month, increments of 0.01. Blank is unknown, not zero. Use unitRent1–unitRent6 for return calculations. |
investmentPrice | number | No | Purchase-price assumption in dollars, greater than zero and at most 1 billion. Defaults to Assessor market value if available. |
unitRent1–unitRent6 | number | No | Monthly gross-rent assumptions, 0–100,000 dollars. Explicit zero is preserved. Blank uses HUD for selected bedrooms, then ACS tract median gross rent if available. |
rentBedrooms1–rentBedrooms6 | integer | No | 0–4 bedrooms per unit; 0 means studio. Used only when that unit's entered rent is absent, with the latest baked HUD ZIP SAFMR. No unit mix is inferred from total building bedrooms. |
vacancyPct | number | No | 0–99.99 percent; defaults to the township low-rise apartment model when available. |
expensePct | number | No | 0–100 percent of collected rent for non-tax operating expenses. When absent, model total expenses are split into tax and non-tax portions to avoid double-counting tax. |
annualTax | number | No | 0–10,000,000 dollars; replaces the rough public tax estimate. All underwriting inputs accept at most two decimal places; duplicates, signs, commas, and exponents are rejected. |
Real example: 2121 N Laporte Ave, Chicago
curl "https://lotlyze.com/api/chicago-units?query=2121+N+Laporte+Ave,+Chicago" \
-H "Authorization: Bearer YOUR_API_KEY"curl "https://lotlyze.com/api/chicago-units?query=13332200130000" \
-H "Authorization: Bearer YOUR_API_KEY"Listing comparison example
/api/chicago-units?query=13233210110000&price=799000&units=2&bedrooms=6&baths=3&landSqft=6250&rent1=1800&rent2=1800These are user assumptions, not verified listing data. Listing inputs do not alter the shared report snapshot. Numeric inputs use plain decimal numbers without currency signs, commas, or exponents; duplicate inputs are rejected. Website listing comparison is currently paused; this API contract remains available. Query strings may appear in access logs; do not include private tenant information.
Unlevered return example
/api/chicago-units?query=13233210110000&investmentPrice=600000&unitRent1=2000&unitRent2=2000&vacancyPct=5&expensePct=30&annualTax=10000These assumptions yield $48,000 gross rent/year, $45,600 collected rent, $13,680 non-tax expenses, $10,000 tax, $21,920 NOI, 3.6533% cap rate, and 12.5 GRM. Underwriting is separate from listing comparison and never saved in the shared public snapshot. Missing inputs or benchmarks producestatus: incomplete with explicit missing reasons; unknown is not zero. Blank price uses Assessor market value. Blank unit rents use HUD when bedrooms are specified, otherwise the ACS tract median gross rent if available; no unit bedroom mix is inferred. Blank tax, vacancy, and expenses use the report's public estimates/model. Results identify applied price and rent sources; entered values (including zero where allowed) take precedence. No debt, capital repairs, closing costs, or income taxes are included.
Response excerpt
Public source records checked October 19, 2026. Permit 101073592, issued April 7, 2026, states a total of 3 dwelling units; the Assessor lists 2. The permit takes precedence and mismatch: true flags the disagreement. Owner fields are placeholders here; geography is an illustrative shape and its polygon features are omitted for brevity. Live results may change as source records are updated. An issued permit does not prove the work was completed or establish legal occupancy.
{
"status": "ok",
"pin": "13332200130000",
"pins": [
"13332200130000"
],
"address": "2121 N LAPORTE AVE 1",
"assessorClass": "211",
"units": 3,
"source": "permit",
"assessorUnits": 2,
"mismatch": true,
"permit": {
"units": 3,
"permitNumber": "101073592",
"issueDate": "2026-04-07",
"text": "SRP 2019 CBRC: INTERIOR & EXTERIOR ALTERATIONS IN EXISTING 2-STORY BRICK MULTI-UNIT RESIDENCE (2DU) IN ORDER TO CONVERT EXISTING UNFINISHED FIRST FLOOR LEVEL INTO NEW DWELLING UNIT FOR TOTAL OF 3 DWELLING UNITS. MECHANICAL, ELECTRICAL & PLUMBING, CONVERT EXISTING REAR OPEN WOOD PORCH TO REAR ENCLOSED WOOD PORCH PER PLANS.OCCUPANCY CLASSIFICATION: R-5 CONSTRUCTION TYPE: III-B"
},
"facts": {
"yearBuilt": 1914,
"buildingSqft": 2405,
"landSqft": 3780,
"bedrooms": 4,
"fullBaths": 2,
"halfBaths": 0,
"heat": "Warm Air Furnace",
"airConditioning": "No Central A/C",
"roof": "Shingle + Asphalt",
"basement": "Full, unfinished",
"attic": "None",
"porch": "None",
"garage": "2 cars, detached, frame",
"exteriorWall": "Masonry",
"condition": "Average"
},
"owner": {
"name": "OWNER NAME",
"mailingAddress": "MAILING ADDRESS, BOLINGBROOK, IL 60490",
"likelyOwnerOccupied": false
},
"assessment": {
"year": 2026,
"stage": "mailed",
"assessedValue": 38000,
"marketValue": 380000
},
"lastPermitBySystem": {
"roof": null,
"porch": {
"permitNumber": "101073592",
"issueDate": "2026-04-07"
},
"masonry": null,
"electrical": {
"permitNumber": "101073592",
"issueDate": "2026-04-07"
},
"plumbing": {
"permitNumber": "101073592",
"issueDate": "2026-04-07"
},
"heating": {
"permitNumber": "101073592",
"issueDate": "2026-04-07"
},
"windows": null
},
"checkedAt": "2026-10-19T13:07:15.000Z",
"listing": null,
"comparison": [],
"location": {
"latitude": 41.9198,
"longitude": -87.7406,
"sourceYear": 2026
},
"geography": {
"status": "available",
"zoning": {
"districts": [
{
"code": "RT-4",
"description": "Residential two-flat / townhome"
}
],
"nearbyDistricts": [
"RS-3",
"RT-4"
],
"nearbyRadiusMeters": 402.336,
"density": {
"lotSqftPerUnit": 1000,
"approximateUnits": 3
},
"sourceUrl": "https://data.cityofchicago.org/d/dj47-wfun",
"rulesUrl": "https://www.chicago.gov/city/en/depts/dcd/supp_info/zoning_ordinance.html"
},
"parcelOutlines": {
"year": 2021,
"sourceUrl": "https://datacatalog.cookcountyil.gov/d/77tz-riq7",
"missingPin10s": [],
"geojson": {
"type": "FeatureCollection",
"features": []
}
},
"errors": []
},
"disclaimer": "Best public evidence, not a certified legal unit count.",
"verifyUrl": "https://www.chicago.gov/city/en/depts/dcd/supp_info/legal-unit-count.html"
}Response fields
| Field | Description |
|---|---|
status | ok, unsupported (outside Chicago, or not a 2–6 unit residential building), or not_found. |
pin | 14-digit Cook County key PIN of the property. A tied side lot returns its key PIN's report. |
pins | Every PIN in the property, key PIN first. Tied PINs (such as a side lot) share one building. |
address | Street address from the Cook County Assessor. |
city | Municipality from the Assessor, e.g. CHICAGO. |
assessorClass | Current Assessor class; 211 is a 2–6 unit apartment building. |
classDescription | Plain-English building type for the class, or null. |
units | Best public evidence of the dwelling-unit count, or null. |
source | Where units came from: permit or assessor; null when unknown. |
assessorUnits | Apartment count recorded by the Assessor, or null. |
permit | Newest permit stating a unit total ({units, permitNumber, issueDate, text}), or null. |
mismatch | true when the permit and Assessor counts disagree. |
facts | Assessor building facts for the key PIN's first building ({yearBuilt, buildingSqft, landSqft, bedrooms, fullBaths, halfBaths, heat, airConditioning, roof, basement, attic, porch, garage, exteriorWall, condition}), or null. landSqft is summed across pins. |
owner | Assessor owner of record and tax-bill mailing address ({name, mailingAddress, likelyOwnerOccupied}), or null. likelyOwnerOccupied is true when bills are mailed to the property. |
assessment | Latest Assessor value summed across pins ({year, stage, assessedValue, marketValue}), or null. stage is board, certified, or mailed; marketValue is assessedValue ÷ 10% for residential classes, else null. |
permits | Up to 200 most recent City building permits at the street address. |
lastPermitBySystem | Newest permit whose wording mentions each building system ({roof, porch, masonry, electrical, plumbing, heating, windows}: {permitNumber, issueDate} or null). A keyword match; no permit on record doesn't mean no work was done. |
violations | Up to 200 most recent City building violations at the street address. |
sales | Up to 20 most recent Assessor-recorded sales for the key PIN. |
location | Parcel-point coordinates from the Cook County parcel universe ({latitude, longitude, sourceYear}), or null. |
context | All-class Chicago location context: sourced transit distances/approximate walking times, bus stops, noise/flood indicators, CMAP walkability, community/ward/TIF, distress/development, and building 311 requests. Includes crime: {status,communityArea,years:[{year,areaCount,cityCount}],comparison,errors}. Crime is reported property-crime record counts for five completed calendar years (FBI codes 05/06/07/09), with a same-year population-normalized comparison when all 77 ACS area estimates are valid. comparison includes year, populationPeriod, areaPopulation, cityPopulation, areaRate, cityRate (per 1,000 residents), percentDifference. City population is the sum of the 77 estimates. No safety score or temporal-trend claim; CPD warns against comparisons over time. Context null outside Chicago. |
market | Class-211 neighborhood comps (18 months) and 12-calendar-year sale trend, 2024-rate tax estimate, and township 7+-unit low-rise income-model assumptions. Includes status/errors, source links, period, sample counts/truncation, pricePerUnit/pricePerSqft {count,median,q1,q3}, weightedPricePerUnit (recency-weighted average), ten similar comps with coordinates, trend {year,medianPrice,sales,partialYear}, tax {annual,assessmentYear,assessedValue,year,equalizer,rate,equalizerUrl,rateUrl}, and assumptions {year,township,samples,vacancy,expenseRatio,capRate,sourceUrl}. Not an appraisal, tax bill, or small-building operating forecast. |
rentBenchmarks | Class-211 baked HUD ZIP SAFMR and Census ACS 5-year tract rents: {zip,tract,status,safmr,acs}. Each source has status, source and latest/history records, or an explicit missing reason. SAFMR records are {year,byBedrooms} (studio–4BR); ACS records are {year,medianGrossRent,byBedrooms} (studio–5+BR). Monthly gross-rent benchmarks, not live asking/lease comps. Null for unsupported reports; missing while provider data has not been baked. |
underwriting | Request-only {inputs,results} unlevered return estimate. Results include status/missing, grossAnnualRent, effectiveGrossIncome, nonTaxExpenses, taxes, noi, capRate (fraction), grm, pricePerUnit, pricePerUnitVsMedian (dollars), monthlyRents, rentSources, vacancyPct, nonTaxExpensePct, modelExpenseRatio. Unknown stays null. Inputs and results are never saved in the public snapshot. |
geography | Zoning and map context for all Chicago property classes: {status, zoning, parcelOutlines, errors}. status is available, partial, unavailable, or outside_chicago. zoning contains districts ({code, description}), nearbyDistricts within about 1/4 mile, nearbyRadiusMeters, density ({lotSqftPerUnit, approximateUnits} or null), sourceUrl, rulesUrl. Density is a base lot-area screening ratio, not permitted/legal units. parcelOutlines contains year (2021), sourceUrl, missingPin10s, and a GeoJSON FeatureCollection keyed by PIN10. Boundaries may be outdated. |
listing | User inputs ({price, units, bedrooms, baths, buildingSqft, landSqft, monthlyRents}), or null when omitted. Each figure can be null; monthlyRents has six nullable entries. Not part of the shared snapshot. |
comparison | One entry per supplied comparable figure: {field, label, listed, recorded, delta, status, source, explanation}. delta is listing minus record; status is matches, differs, or unavailable. Price compares to Assessor market value, not an appraisal. Empty when no listing figures are supplied or status is not ok. |
checkedAt | When Lotlyze last checked the public sources (ISO 8601). Reports refresh after 24 hours. |
disclaimer | Reminder that this is public evidence, not a certified legal unit count. |
verifyUrl | City page for requesting a certified unit count. |
City permits and violations match the street address and may miss other addresses on the parcel. A property can span several Cook County PINs: a tied side-lot PIN returns its key PIN's report, and pins lists them all. Reports refresh after 24 hours; checkedAt shows when the sources were last checked. This is not a certified legal unit count: request City verification before relying on it for a purchase or zoning decision.
Geography is evaluated at the Assessor's parcel point, not every boundary of a split-zoned lot. The density screen uses base lot area per dwelling unit for RS-1, RS-2, RS-3, RT-3.5, RT-4, RM-4.5, and RM-5 only; other or multiple districts return density: null. It is not an allowed/legal-unit count or ADU determination. Tied tax PINs need not be one zoning lot.geography.errors identifies missing sources, coordinates, or outdated/missing outlines. Failed geography sources produce an explicit partial/unavailable result rather than removing the core report.
context is available for every Chicago class. Transit distances are straight-line; walking estimates assume 3 mph, not a walking route. CMAP bands split the 10–130 range into thirds, not Walk Score. Traffic, rail, and airport data are noise proxies, not measured building sound. FEMA/First Street indicators are not insurance advice. Building-related 311 requests are address-matched allegations, not confirmed violations; the latest 50 are returned with a truncation flag. Each metric retains its source vintage; some are older than the report check.
market is for class 211. Comps use the same Assessor neighborhood and the preceding 18 months, exclude multi-parcel and Assessor-flagged sales, remove tied buildings, and keep one latest sale per PIN. Quartiles use linear interpolation; weightedPricePerUnit weights each sale linearly from 0.5 (oldest) to 1 (newest). Ten properties are ranked by unit-count match, then building area. Statistics cover all joined eligible properties (at most 1,000 input sales, with truncated flagged). Current Assessor facts may differ from sale-date facts. The 12-calendar-year median sale trend is not a repeat-sales index; the current year is partial. Tax estimates multiply the property's latest AV by the 2024 equalizer 3.0355 and Chicago average composite rate 6.619%, before exemptions. They mix assessment/rate years and are not actual bills or forecasts; check the Treasurer for each PIN. Income defaults are township medians for 7+-unit low-rise apartments, not observed 2–6-flat operations.
rentBenchmarks comes from an offline annual bake, not per-request provider calls. HUD SAFMR is a ZIP gross-rent benchmark, not asking rent; ACS is a lagged tract median from overlapping five-year samples on 2020 tract boundaries. Nominal histories retain each fiscal/vintage year. HUD fallback requires an explicit per-unit bedroom count and includes tenant-paid utilities. Provider data not yet baked returns explicit missing statuses rather than estimated rents. The Assessor model expense ratio is treated as all-in: non-tax expense defaults to max(0, model ratio × collected rent − taxes). A supplied expensePct instead means non-tax expenses, with taxes deducted separately.
status is ok, unsupported (outside the supported residential class or outside Chicago), or not_found. These outcomes return HTTP 200; a unit count can be null when evidence is unavailable. Missing or overlong queries, unsupported listing URLs, and invalid listing inputs return 400; upstream data failures return 502. Without a valid Pro key, requests return 401.
/api/propertyNYC all-in-one: resolves an address, BBL, or BIN, then returns its identifiers, ACRIS records, and DOB records in one request.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
query | string | Yes | Address, 10-digit BBL, hyphenated BBL, or 7-digit BIN |
Example
curl "https://lotlyze.com/api/property?query=534+Kosciuszko+St+Brooklyn" \
-H "Authorization: Bearer YOUR_API_KEY"Response
{
"lookup": {
"address": "534 KOSCIUSZKO STREET, Brooklyn, NY, USA",
"bbl": "3016070023",
"bbl_formatted": "3-01607-0023",
"bin": "3043452",
"borough": "Brooklyn",
"block": "01607",
"lot": "0023",
"latitude": 40.6926,
"longitude": -73.932574
},
"acris": {
"records": [
{
"id": "2019061400456001",
"date": "2019-06-14",
"type": "DEED",
"description": "DEED",
"party1": "SELLER NAME",
"party2": "BUYER NAME",
"amount": 1250000,
"formatted_amount": "$1,250,000"
}
],
"count": 1
},
"dob": {
"permits": [],
"jobFilings": [],
"dobNow": [],
"violations": [],
"complaints": []
}
}address, latitude, and longitude are only filled for address queries. ACRIS records here have no category and use formatted_amount. Each DOB list holds up to 20 raw NYC Open Data rows since January 1, 2020, newest first. An unknown address or BIN returns 404.
/api/acrisFetch ACRIS deed and document records for a property.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
bbl | string | Yes | 10-digit Borough-Block-Lot |
Example
curl "https://lotlyze.com/api/acris?bbl=1000477501" \
-H "Authorization: Bearer YOUR_API_KEY"Response
{
"bbl": "1000477501",
"records": [
{
"id": "2023012700123456",
"date": "2023-01-27",
"type": "DEED",
"description": "DEED",
"category": "deed",
"party1": "SELLER NAME",
"party2": "BUYER NAME",
"amount": 4500000,
"formattedAmount": "$4,500,000"
}
],
"count": 1
}Records are newest first. category is deed, mortgage, lien, ucc, satisfaction, or other. A BBL with no ACRIS records returns {"bbl": "…", "records": []} without a count.
/api/dobFetch DOB permits, job filings, violations, and complaints for a building.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
bin | string | Yes | 7-digit Building ID Number |
Example
curl "https://lotlyze.com/api/dob?bin=1001074" \
-H "Authorization: Bearer YOUR_API_KEY"Response
{
"bin": "1001074",
"permits": [
{
"job__": "102657000",
"permit_type": "SG",
"issuance_date": "2000-10-20",
"source_system": "DOB_Socrata"
}
],
"jobFilings": [
{
"job__": "140641321",
"job_type": "A3",
"latest_action_date": "12/06/2018",
"source_system": "DOB_Socrata"
}
],
"dobNow": [
{
"job_filing_number": "M00001019-I1",
"work_permit": "M00001019-I1-FN",
"approved_date": "2017-10-30T12:13:00.000",
"source_system": "DOB_NOW"
}
],
"violations": [],
"complaints": [
{
"complaint_number": "1411462",
"status": "CLOSED",
"date_entered": "12/03/2015",
"source_system": "DOB_Socrata"
}
]
}Each list holds up to 20 raw NYC Open Data rows, newest first, using the source dataset's field names, plus a source_system tag. Rows are shortened above.
/api/hpdHPD housing-code violations and complaints for a property.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
bbl | string | Yes | 10-digit or hyphenated Borough-Block-Lot |
Example
curl "https://lotlyze.com/api/hpd?bbl=3016070023" \
-H "Authorization: Bearer YOUR_API_KEY"Response
{
"bbl": "3016070023",
"violations": [
{
"orderId": "12345678",
"class": "B",
"description": "§ 27-2026 ADM CODE REPAIR THE LEAKY FAUCET IN THE BATHROOM",
"inspectionDate": "2024-05-02",
"issuedDate": "2024-05-03",
"status": "NOV SENT OUT",
"apartment": "2",
"source": "HPD"
}
],
"complaints": [
{
"complaintId": "3447477",
"type": "EMERGENCY",
"status": "CLOSE",
"openedDate": "2006-09-13",
"closedDate": "2006-09-17",
"source": "HPD"
}
]
}Up to 50 violations, newest inspection first. Complaint problem rows are grouped by complaint, so one complaint can list several types; closedDate is empty until the complaint closes.
/api/ecbECB/OATH violations for a building, with the total unpaid balance.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
bin | string | Yes | 7-digit Building ID Number |
Example
curl "https://lotlyze.com/api/ecb?bin=3043452" \
-H "Authorization: Bearer YOUR_API_KEY"Response
{
"bin": "3043452",
"violations": [
{
"violationId": "34847088Z",
"respondent": "OWNER NAME",
"description": "FAILURE TO MAINTAIN BLDG IN CODE COMPLIANT MANNER.",
"violationType": "Construction",
"agency": "DOB",
"issueDate": "20100423",
"hearingDate": "20100614",
"penaltyTotal": 5000,
"balanceDue": 0,
"status": "RESOLVE",
"source": "ECB"
}
],
"totalBalanceDue": 0
}Up to 50 violations, newest first. Dates are YYYYMMDD strings, as published, and totalBalanceDue is the sum of balanceDue across the returned violations.
/api/taxNYC Department of Finance assessment for a property.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
bbl | string | Yes | 10-digit or hyphenated Borough-Block-Lot |
Example
curl "https://lotlyze.com/api/tax?bbl=3016070023" \
-H "Authorization: Bearer YOUR_API_KEY"Response
{
"bbl": "3016070023",
"assessment": {
"bbl": "3016070023",
"taxClass": "1",
"marketValue": 1355000,
"assessedValue": 81300,
"exemptValue": 0,
"taxableAssessedValue": 21919,
"annualTax": 4349.39,
"annualTaxIsEstimate": true,
"assessmentYear": "2027",
"taxRateYear": "25/26",
"taxRatePercent": 19.843,
"has421a": null,
"stabilizationIndicator": null,
"source": "DOF"
}
}assessment is null when Finance has no record for the BBL. The annual tax is an estimate: the latest published rate for the tax class is applied to the DOF taxable assessed value, and does not account for property-specific credits. The current assessment dataset does not identify 421-a exemptions, so has421a and stabilizationIndicator are null.
/api/summaryNYC full summary: ACRIS, DOB, HPD, ECB, and Finance tax data in a single request. Resolves BBL to BIN automatically.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
bbl | string | Yes | 10-digit or hyphenated Borough-Block-Lot |
Example
curl "https://lotlyze.com/api/summary?bbl=3016070023" \
-H "Authorization: Bearer YOUR_API_KEY"import httpx
API_KEY = "YOUR_API_KEY"
data = httpx.get(
"https://lotlyze.com/api/summary",
params={"bbl": "3016070023"},
headers={"Authorization": f"Bearer {API_KEY}"},
).json()
print(data["acris"][0]["date"]) # most recent deed date
print(len(data["dob"]["violations"]))Response
{
"bbl": "3016070023",
"bin": "3043452",
"borough": "Brooklyn",
"acris": [
{
"id": "2019061400456001",
"date": "2019-06-14",
"type": "DEED",
"description": "DEED",
"category": "deed",
"party1": "SELLER NAME",
"party2": "BUYER NAME",
"amount": 1250000,
"formattedAmount": "$1,250,000"
}
],
"hpd": {
"violations": [],
"complaints": [
{
"complaintId": "3447477",
"type": "EMERGENCY",
"status": "CLOSE",
"openedDate": "2006-09-13",
"closedDate": "2006-09-17",
"source": "HPD"
}
]
},
"ecb": {
"violations": [],
"totalBalanceDue": 0
},
"tax": {
"bbl": "3016070023",
"taxClass": "1",
"marketValue": 1355000,
"assessedValue": 81300,
"exemptValue": 0,
"taxableAssessedValue": 21919,
"annualTax": 4349.39,
"annualTaxIsEstimate": true,
"assessmentYear": "2027",
"taxRateYear": "25/26",
"taxRatePercent": 19.843,
"has421a": null,
"stabilizationIndicator": null,
"source": "DOF"
},
"dob": {
"permits": [
{
"job__": "321234567",
"issuance_date": "2021-03-02",
"source_system": "DOB_Socrata"
}
],
"jobFilings": [],
"dobNow": [],
"violations": [],
"complaints": []
}
}Unlike the single-source endpoints, acris is a plain array of records, HPD violations omit issuedDate, ECB violations omit status, and tax is the flat assessment plus bbl (or null). Each DOB list holds up to 20 rows, newest first, tagged with source_system.
/api/bulkPro onlyLook up to 50 NYC BBLs in a single request: identifiers, ACRIS records, and DOB records for each. Send a JSON body with POST, or a comma-separated bbls parameter with GET.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
bbls | string[] (POST body) or comma-separated string (GET) | Yes | 10-digit or hyphenated BBLs. Max 50. |
Example
curl -X POST "https://lotlyze.com/api/bulk" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"bbls": ["3016070023", "1004770001", "4015670023"]}'curl "https://lotlyze.com/api/bulk?bbls=3016070023,1004770001" \
-H "Authorization: Bearer YOUR_API_KEY"Response
{
"count": 1,
"results": [
{
"bbl": "3016070023",
"ok": true,
"data": {
"bbl": "3016070023",
"bbl_formatted": "3-01607-0023",
"bin": "3043452",
"borough": "Brooklyn",
"block": "01607",
"lot": "0023",
"acris": {
"records": [
{
"id": "2019061400456001",
"date": "2019-06-14",
"type": "DEED",
"description": "DEED",
"party1": "SELLER NAME",
"party2": "BUYER NAME",
"amount": 1250000,
"formatted_amount": "$1,250,000"
}
],
"count": 1
},
"dob": {
"permits": [],
"jobFilings": [],
"dobNow": [],
"violations": [],
"complaints": []
}
}
}
]
}Every result has ok. Successful results carry data; a BBL whose lookup failed carries error instead, without failing the whole request. ACRIS records use formatted_amount, and each DOB list holds up to 20 raw NYC Open Data rows since January 1, 2020. A missing or malformed list, more than 50 BBLs, or any invalid BBL returns 400.
Rate limits & tiers
| Tier | Price | API access | Bulk endpoint |
|---|---|---|---|
| Free | $0 / mo | No API access | No |
| Pro | $1 / mo | Unlimited API access | Yes (50 BBLs/req) |
Include your API key in the Authorization: Bearer <key> header. Keys are provisioned automatically on upgrade — visit your account.