# New Orleans Code Enforcement - Cases, Violations, Hearings (`j0401/nola-code-enforcement`) Actor

New Orleans code enforcement (public open data, six linked corpora): cases, violations cited, inspections, hearings and judgments, abatements and the active pipeline, joined on the case id. Look up a property's case history, or filter by stage, status, code section, judgment or date.

- **URL**: https://apify.com/j0401/nola-code-enforcement.md
- **Developed by:** [Wenhao Yang](https://apify.com/j0401) (community)
- **Categories:** Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.03 / 1,000 code enforcement records

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## New Orleans Code Enforcement - Cases, Violations, Hearings

The City of New Orleans' code-enforcement system, straight from the City's open
data. **Six linked corpora** - the cases, the violations cited, the inspections,
the hearings and judgments, the abatements and the active pipeline - all joined
on the case id. **855,000+ records** across the system.

### Low cost

**From $0.00005 per record, down to $0.00003 at Gold.** Pay only for the
records you actually receive - the whole system stays queryable, you are
never billed for the scan behind it.

### What you get

Pick a **corpus** and get its records, most recent first. Every record carries the
case id, the case number, the property address and dates:

- **cases** (183k) - stage, open/closed, the compliance status text, the property
  location and coordinates
- **violations** (272k) - the code section cited and the violation text
- **inspections** (246k) - the inspection type, the result and the inspector
- **hearings** (103k) - the hearing date, the judgment and the property
- **abatements** (7.2k) - the City's abatement action, its status and exit reason
- **pipeline** (44k) - the active-pipeline table (it includes recently closed
  cases; set `oC="Open"` for live cases), with unpaid fees

Because every corpus carries `caseId`, the same case id can be looked up corpus
by corpus to assemble its violations, inspections and hearings.

### Filter it

- **One case** - `caseId="292742"` returns that case's record (and, corpus by
  corpus, its full history).
- **Property** - `address="GENTILLY"`, `caseNumber="23-09269"`.
- **Stage** - `stage="4 - Judgment"` for cases at the judgment stage.
- **Status** - `oC="Open"`; `stage` and `oC` apply to cases and pipeline.
- **Code** - `codeSection="26-157"` on the violations corpus.
- **Judgment** - `judgment="Guilty"` on the hearings corpus.
- **Inspection** - `inspectionType="Reinspection"`,
  `inspectionResult="No Violation"`.
- **Period** - `dateFrom="2024-01-01"`, or `recentDays=90` for the last quarter.

### Example inputs

**The open, active cases** - cases the City is still pursuing.

```json
{ "corpus": "cases", "oC": "Open", "maxResults": 50 }
```

**One property's case history** - the key that joins every corpus.

```json
{ "corpus": "violations", "caseId": "292742", "maxResults": 100 }
```

**Hearings won by the City** - a judgment on the hearings corpus.

```json
{ "corpus": "hearings", "judgment": "Guilty", "maxResults": 50 }
```

**How cases break down** - `mode=aggregate` counts per stage.

```json
{ "mode": "aggregate", "groupBy": "stage" }
```

### Or roll it up

Set `mode=aggregate` and get a count by the dimension the corpus supports:
**stage** or **oC** (cases, pipeline), **codeSection** (violations),
**inspectionType** / **inspectionResult** (inspections), **judgment** or
**councilDistrict** (hearings), **status** / **exitReason** (abatements). Every group comes back.

### Then use it

- **Due diligence on a property** - pull its case id and follow it across the
  violations, inspections and hearings.
- **Blight tracking** - the open pipeline, the abatements and the judgments.
- **Watch the pipeline** - cases moving from inspection to hearing to judgment.

### Example output

**One open case** - filed 2026-10-06, awaiting inspection:

```json
{
 "platform": "nola-code-enforcement",
 "source": "new-orleans-code-enforcement",
 "corpus": "cases",
 "mode": "rows",
 "groupKey": "",
 "groupCount": "",
 "groupBy": "",
 "caseId": "337764",
 "caseNumber": "26-11535-MPM",
 "address": "2400 Gentilly Blvd",
 "stage": "1 - Inspection",
 "oC": "Open",
 "statusText": "The case was filed on 10/06/2026 and the property is awaiting inspection to proceed further.",
 "primaryDate": "2026-10-06T15:20:26.000",
 "secondaryDate": "2026-10-06T15:20:26.000",
 "code": "",
 "description": "",
 "judgment": "",
 "inspectionType": "",
 "inspectionResult": "",
 "inspector": "",
 "zip": "70122",
 "councilDistrict": "",
 "geopin": "41076537",
 "xpos": "3681432.23",
 "ypos": "544877.16",
 "unpaidFees": "",
 "sourceUpdatedAt": "2026-10-17"
}
```

**`mode=aggregate`, `groupBy=stage`, `corpus=cases`** - the largest groups, e.g.:

```
6 - Case Closed                               148,762
4 - Judgment                                   23,254
3 - Hearing                                     4,551
2 - Title Research                              2,662
5 - In Compliance                               1,603
1 - Inspection                                  1,386
X - Processing                                    789
```

### Notes on the data, from the source

- **Six corpora, one key.** The numeric `caseId` ties them together; the human
  `caseNumber` (e.g. `23-09269-MPM`) is the string you see on a notice. Looking up
  a case id one corpus at a time returns that corpus's rows; run it per corpus to
  build the full history.
- **`judgment` is a substring filter.** `judgment="Guilty"` also matches
  `Not Guilty` (a small share of rows); use the exact hearing value when that
  distinction matters.
- **The sub-tables lag the cases table.** A case filed today is in `cases` and
  `pipeline` but not yet in violations/hearings/inspections - a case id that
  misses one corpus is normal.
- **Filters and groupBy are per corpus.** `stage` exists on cases and pipeline
  but not on violations; `codeSection` exists only on violations. A filter that
  does not apply to the chosen corpus is rejected rather than ignored.
- **Statuses are free text.** The `statusText` field is the City's own sentence
  describing where the case stands (and often embeds a date). It is carried as
  text and is not offered as a filter or a group-by dimension.

# Actor input Schema

## `corpus` (type: `string`):

Which table to query. cases = every case (the default); violations = the code sections cited; inspections = inspections performed; hearings = hearings and their judgments; abatements = City abatement actions; pipeline = the active pipeline (it includes recently closed cases; set oC="Open" for live cases). Filters and groupBy differ by corpus.

## `caseId` (type: `string`):

Look up one case across the corpus by its numeric case id, e.g. '292742'. This is the key that joins every corpus. Exact match, not a substring. Blank = any.

## `caseNumber` (type: `string`):

Substring match on the human case number, e.g. '23-09269', 'MPM'. Available on cases, violations, inspections, hearings, abatements and pipeline. Blank = any.

## `address` (type: `string`):

Substring match on the property address or location, e.g. 'GENTILLY', 'ST CLAUDE'. Blank = any.

## `stage` (type: `string`):

Case stage. Available on cases and pipeline. Not every stage value applies to both. Blank = any.

## `oC` (type: `string`):

Whether the case is still open. Available on cases and pipeline. Blank = any.

## `codeSection` (type: `string`):

The municipal code section cited (corpus=violations), e.g. '26-160(a)', '26-157'. 70 distinct sections. Blank = any.

## `judgment` (type: `string`):

Hearing judgment (corpus=hearings), e.g. 'Guilty', 'Dismissed', 'Reset'. Blank = any.

## `inspectionType` (type: `string`):

Substring match on the inspection type (corpus=inspections), e.g. 'Reinspection', 'Initial', 'Demolition', 'Posting'. The source has 40+ types, so this is a contains-match rather than a fixed list. Blank = any.

## `inspectionResult` (type: `string`):

The inspection outcome (corpus=inspections), e.g. 'Violation', 'Complete', 'No Violation'. Blank = any.

## `status` (type: `string`):

The abatement's status (corpus=abatements). Blank = any.

## `dateFrom` (type: `string`):

Earliest date for the corpus's own date column: cases/pipeline = filed, violations = violation date, inspections = inspection date, hearings = hearing date, abatements = filed. YYYY-MM-DD. Blank = any.

## `dateTo` (type: `string`):

Latest date for the corpus's own date column, YYYY-MM-DD. Blank = any.

## `recentDays` (type: `integer`):

Only records whose date is within the last N days. Cannot be combined with 'On or after' (the run fails if both are set). 0 = off.

## `mode` (type: `string`):

rows = records matching your filters (default). aggregate = one count row per group (see groupBy).

## `groupBy` (type: `string`):

Which dimension to aggregate over (mode=aggregate). Blank = the corpus's default (cases/pipeline -> stage, violations -> codeSection, inspections -> inspectionType, hearings -> judgment, abatements -> status). A dimension that does not exist on the chosen corpus is rejected. Every group is returned.

## `maxResults` (type: `integer`):

Cap the number of records pushed in rows mode (0 = default 50; up to 2,000 per run). Each record is metered individually, so there is no per-run charge cap. Aggregate mode returns every group.

## Actor input object example

```json
{
  "corpus": "cases",
  "caseId": "",
  "caseNumber": "",
  "address": "",
  "stage": "",
  "oC": "",
  "codeSection": "",
  "judgment": "",
  "inspectionType": "",
  "inspectionResult": "",
  "status": "",
  "dateFrom": "",
  "dateTo": "",
  "recentDays": 0,
  "mode": "rows",
  "groupBy": "",
  "maxResults": 50
}
```

# Actor output Schema

## `recordsUrl` (type: `string`):

New Orleans code enforcement records - as JSON

## `datasetUrl` (type: `string`):

No description

## `runUrl` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("j0401/nola-code-enforcement").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("j0401/nola-code-enforcement").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call j0401/nola-code-enforcement --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,j0401/nola-code-enforcement"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/dMhAi6pQxpuAlzFGE/builds/2Q7wXeD93WQxPIO79/openapi.json
