NYC Business Licenses - Inspections, Violations, Complaints avatar

NYC Business Licenses - Inspections, Violations, Complaints

Pricing

from $0.06 / 1,000 nyc dcwp records

Go to Apify Store
NYC Business Licenses - Inspections, Violations, Complaints

NYC Business Licenses - Inspections, Violations, Complaints

NYC DCWP's licensing ecosystem (public open data): 72.5K licences, 65.9K applications, 278K field inspections, 137K violations with their Admin Code charge and hearing outcome, and 76.5K consumer complaints - all linked by business id, so one lookup returns a business's whole regulatory record.

Pricing

from $0.06 / 1,000 nyc dcwp records

Rating

0.0

(0)

Developer

Wenhao Yang

Wenhao Yang

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

5 days ago

Last modified

Categories

Share

Low cost

From $0.0001 per record, down to $0.00006 at Gold - pay per record delivered, and nothing for the query. Cost scales with what you pull, not with the size of the register.

New York City's Department of Consumer and Worker Protection licensing ecosystem. Not just a licence list: the applications behind the licence, the inspections of the premises, the charges that came out of those inspections, and the consumer complaints filed against the business - five tables, all resolved on one business id.

What you get

TableRowsWhat it holds
licenses72,452current licences: status, category, licence type, address with BIN/BBL/community board
applications65,932new and renewal applications: intake channel, submission and closure, temporary-operation letters
inspections277,976field inspections: type (patrol, tobacco sale-to-minor, scale, sweep), status, outcome
violations137,316the charge itself - the Admin Code or Public Health Law section cited - with the hearing outcome and disposition flags
complaints76,527consumer complaints: 311 channel, result, and any refund or contract-cancellation amount

Modes

  • licenses (default) / applications / inspections / violations / complaints
  • business - everything above for one business id, in one response
  • aggregate - counts by status, category, charge, outcome

A business query turns five separate datasets into one answer: this business holds these licences, applied on these dates, was inspected here, was charged under these sections, and had these complaints - with the outcome of each.

Example inputs

One business, all five tables - mode=business resolves the id across licences, applications, inspections, violations and complaints in one response.

{ "mode": "business", "businessId": "BA-1786461-2026" }

Active tobacco licences in one borough - category and borough are substring matches; licenseStatus is the exact published value.

{ "licenseStatus": "Active", "category": "Tobacco",
"borough": "Brooklyn", "maxResults": 100 }

Charges that were pleaded - mode=violations with the exact hearing outcome.

{ "mode": "violations", "outcome": "Pleaded", "maxResults": 100 }

What the city inspects most - mode=aggregate counts one row per group.

{ "mode": "aggregate", "corpus": "inspections", "groupBy": "inspectionType" }

Why this is hard

The five tables spell the same facts differently. The building number is address_building on one, building_number on the next, building_no on the third and building_nbr on the fourth; ZIP is address_zip / zip / zip_code / postcode. Nothing joins unless you know each table's spelling. Expiry dates carry sentinel rows dated 2100 - and because an expiry date in the future is the normal state of an active licence (44,099 of them), a naive date ceiling deletes every valid licence in the register while keeping the junk. The complaint table is the only one missing the business id on some rows (2,497 of them), so the join has to tolerate gaps rather than drop them.

Output

One schema across all five tables - every record carries the full key set, empty where the table has nothing to say. Dates arrive as YYYY-MM-DD.

Notes

  • Public open data from NYC Open Data. No login, no scraping.
  • DCWP publishes this because it is the city's consumer-protection record - who is licensed, and what they did with the licence.
  • Charges are metered per record delivered, so pulling one business's record costs a fraction of a cent.

Example output

One licence - businessId=BA-1786461-2026 on the default licenses mode. Every record carries the full key set; the columns the table has nothing to say about come back "", and the aggregate columns (groupKey, groupCount, groupBy) are "" outside aggregate mode:

{
"platform": "nyc-dcwp",
"source": "nyc-dcwp-licenses",
"corpus": "licenses",
"recordKind": "license",
"mode": "licenses",
"groupKey": "", "groupCount": "", "groupBy": "",
"businessId": "BA-1786461-2026",
"businessName": "Paceline Consults Inc",
"dbaTradeName": "",
"businessCategory": "Debt Collection Agency",
"licenseNumber": "2136952-DCWP",
"licenseType": "Premises",
"licenseStatus": "Active",
"licenseCreationDate": "2026-08-19",
"licenseExpirationDate": "2027-01-31",
"detail": "",
"contactPhone": "(212) 812-2995",
"addressType": "Complete Address",
"addressBuilding": "225",
"addressStreet": "W 34TH ST",
"addressStreet2": "",
"addressCity": "NEW YORK",
"addressState": "NY",
"addressZip": "10122",
"addressBorough": "Manhattan",
"communityBoard": "105",
"councilDistrict": "03",
"bin": "1014402",
"bbl": "1007840019",
"nta": "MN17",
"censusTract": "109",
"latitude": "40.751483",
"longitude": "-73.991764",
"applicationId": "", "applicationType": "", "intakeChannel": "", "submissionDate": "", "applicationStatus": "", "dateClosed": "",
"tempOpLetterIssued": "", "tempOpLetterExpiration": "", "certificateOfInspection": "",
"inspectionNumber": "", "dateOfOccurrence": "", "dcwpLicenseNumber": "", "inspectionType": "", "inspectionStatus": "",
"nohNumber": "", "recordId": "", "relatedRecordType": "", "violationDate": "", "charge": "", "chargeCount": "",
"cureEligible": "", "cured": "", "outcome": "", "guilty": "", "notGuilty": "", "dismissed": "",
"intakeDate": "", "serviceRequestNumber": "", "complaintCode": "", "resultDate": "", "result": "", "referredTo": "",
"contractCancelledAmount": "", "refundAmount": "",
"sourceUpdatedAt": "2026-08-20"
}