DC DDOT TOPS Permits - Construction & Occupancy avatar

DC DDOT TOPS Permits - Construction & Occupancy

Pricing

from $0.03 / 1,000 dc ddot tops permit records

Go to Apify Store
DC DDOT TOPS Permits - Construction & Occupancy

DC DDOT TOPS Permits - Construction & Occupancy

Washington DC DDOT right-of-way permits (public open data): 543k construction permits and 983k occupancy permits, 2005-present. Fees broken out by kind, three named parties, ward/ANC/SMD/ZIP, district overlays and pre-computed cycle times. Search by address, owner, permittee, ward or status.

Pricing

from $0.03 / 1,000 dc ddot tops permit records

Rating

0.0

(0)

Developer

Wenhao Yang

Wenhao Yang

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Categories

Share

Anything that touches a Washington DC street, sidewalk or alley has to be filed with DDOT's Transportation Online Permitting System first - construction staging areas, excavations, paving, street fixtures, banners, block parties, moving trucks. This actor turns that register into a charged-per-record search, filter and aggregate tool over two registers at once: 543,201 construction permits and 982,887 occupancy permits.

Built for: contractor and right-of-way diligence, street-closure and staging research, procurement and subcontractor intelligence, neighborhood impact studies, and anyone who needs the District's own permit record rather than an address-by-address lookup.

What it covers

Each register is queried on its own (corpus), and each record carries:

  • the permit - permit number, tracking number, status, permit type, issue / application / effective / expiration / approval dates
  • the parties - property owner, permittee, and applicant company
  • the money - the total fee with its parts broken out: permit fee, technology fee, inspection amount, meter fee and deposit
  • where - the work-site address plus ward, ANC, SMD, ZIP, quadrant, neighborhood, historic district, BID and zoning
  • how long it took - daysToAssign, daysToApprove, daysToIssue, pre-computed by the District rather than left for you to subtract
  • the location - latitude and longitude, on every row in both registers

The fine print that matters

The two registers carry different fields, and this actor tells you rather than guessing. permitType (New / Replace / Repair) exists only on the construction register; eventType - the ~34 values like Construction Staging Area, Block Party, Banner and Seasonal Display - exists only on the occupancy register. Asking for a dimension your corpus does not have is rejected with a clear error, not silently ignored.

permitType is stored as a code, and it is not empty. The District keeps this column as an integer whose domain says 0 = New, 1 = Replace, 2 = Repair. Read raw, a column that is 0 on most rows looks unpopulated; decoded, it is filled on 504,624 of 543,201 construction permits. This actor returns the decoded label.

A row is a work location, not necessarily a whole permit. A permit covering several street segments is filed as several rows that share one permit number, so counting rows and calling it "permits" overstates - the newest day's batch is 87 rows spread across 7 permit numbers, and the largest single number seen is 50 rows. The row is the billing unit and each one carries its own address and coordinates.

Some fields are thin, and they are not sold as features here. The construction register's contractor name is present on only 42,997 of 543,201 rows (7.9%), its meter amount on 4.1%, its BID overlay on 7.2% and its historic-district overlay on 20.8%. On the occupancy register the EWR number is present on 0.13% of rows. The ANC field is a placeholder - the literal AN - on 268,928 of 543,201 construction rows (49.5%), where the row's SMD still names a real commission; filtering anc therefore misses every permit carrying the placeholder. They are returned as fields, but nothing in this listing rests on them.

A permit that is "expired" usually just ran its course. On the construction register 448,875 of 543,201 permits sit at Permit Expired and on the occupancy register 799,563 of 982,887 sit at EXPIRED. That is the normal end state of a permit whose work is finished and whose term lapsed - not a cancelled one. Cancel/Withdrawn and Denied are the statuses that mean the permit did not proceed.

Default order is by issue date, deliberately. The District edits this layer continuously, but most edits are old permits being flipped to expired by a batch job - ordering by last-updated would surface five stale permits rather than the ones issued this week. Issued-date ordering returns genuinely current permits.

Typical questions

  • "Every right-of-way permit at an address or in a ZIP."
  • "What did pull permits for?"
  • "Street-closure and staging permits in a ward or ANC."
  • "Moving-truck and block-party occupancy permits."
  • "Permits issued in the last 90 days and still open."
  • "How long DDOT takes: days to issue, aggregated by ward."
  • "Aggregate by status, ward, ANC, ZIP, event type or fiscal year."

Inputs

InputWhat it does
moderows (default) / aggregate
corpusconstruction (default) / occupancy
permitNumber / trackingNumberexact permit or tracking number
addresswork-site address substring
owner / permittee / applicantname substring on each party
ward / anc / zip / quadrantdistrict filters; zip matches as a prefix
statusexact status, as the register spells it
permitTypeNew / Replace / Repair - construction corpus only
eventTypeoccupancy-register event kind (e.g. Block Party) - occupancy corpus only
fiscalYearDistrict fiscal year
issuedFrom / issuedToissue-date range (inclusive)
groupByaggregate over status / permitType / eventType / ward / anc / zip / quadrant / fiscalYear

Aggregate groups are counted over the same filters as rows; quadrant and fiscalYear are available dimensions too. | maxResults | cap records (default 50) |

Default run = 50 construction rows, newest issue date first. Because one permit can span several rows, a 50-row page may cover only a handful of permit numbers - raise maxResults, or filter by permit number, when you need a full permit. Fast enough for the daily auto-test. For a targeted query add a filter; for a broad view use aggregate.

Example inputs

One permit by number

{ "permitNumber": "PA489240" }

A ward's recent permits

{ "corpus": "construction", "ward": "2", "maxResults": 5 }

Utility work by the owner

{ "owner": "Washington Gas", "maxResults": 5 }

Occupancy permits - street events and block parties

{ "corpus": "occupancy", "eventType": "Block Party", "maxResults": 5 }

How the register splits by status

{ "mode": "aggregate", "groupBy": "status" }

Low cost

From $0.00005 per record, down to $0.00003 at Gold Pay-per-event: you are charged per record delivered, and nothing for the query. Cost scales with what you pull, not with the size of the register, and each record is metered individually - one address's permit history costs a fraction of a cent.

Example output

One construction permit - permitNumber=PA489240 returns its status, fees, parties, location and cycle times:

{
"platform": "dc-tops-permits",
"source": "dc-ddot-tops",
"corpus": "construction",
"mode": "rows",
"groupKey": "",
"groupCount": "",
"groupBy": "",
"permitNumber": "PA489240",
"trackingNumber": "489240",
"status": "Issued",
"statusCode": "9",
"permitType": "New",
"eventType": "",
"issueDate": "2026-09-25",
"applicationDate": "2026-02-23",
"effectiveDate": "2026-08-03",
"expirationDate": "2027-08-02",
"lastApprovalDate": "2026-07-14",
"lastUpdateDate": "2026-09-25",
"address": "1200 - 1225 BLOCK OF NEW HAMPSHIRE AVENUE NW",
"ownerName": "Wash Gas & Light Co.",
"permitteeName": "Wash Gas & Light Co.",
"applicantCompany": "Wash Gas & Light Co.",
"contractorName": "",
"warehouseNumber": "",
"constructionPermitNumber": "",
"totalFee": "148.5",
"technologyFee": "13.5",
"permitFee": "135",
"inspectionAmount": "0",
"meterAmount": "",
"depositAmount": "0",
"workDetail": "INSTALL ABOVE GROUND POLE-MOUNTED ELECTRONIC PRESSURE RECORDER, WR#4071366, P#1031491",
"typeDetailNames": "Fixture; Street Fixture or Furniture (Exception)",
"roadClosed": "",
"daysToAssign": "113",
"daysToApprove": "141",
"daysToIssue": "215",
"ward": "2",
"anc": "AN",
"smd": "2A06",
"zip": "20036",
"quadrant": "NW",
"neighborhood": "West End, Foggy Bottom, GWU",
"historicDistrict": "",
"bid": "",
"zoning": "CR",
"fiscalYear": "2026",
"latitude": "38.90558552",
"longitude": "-77.04724693",
"sourceUpdatedAt": "2026-09-27"
}

An aggregate row - {"mode": "aggregate", "groupBy": "status"} returns one row per status, with the record fields blank:

{
"platform": "dc-tops-permits",
"source": "dc-ddot-tops",
"corpus": "construction",
"mode": "aggregate",
"groupKey": "Permit Expired",
"groupCount": "448875",
"groupBy": "status",
"permitNumber": "",
"issueDate": "",
"address": "",
"ownerName": "",
"sourceUpdatedAt": "2026-09-27"
}

Notes

  • Source: DC Department of Transportation, published on the District's open GIS server. No login, no key.
  • Freshness: every record carries sourceUpdatedAt, the newest edit date in the register (measured: the probe day).
  • Coverage: District of Columbia only. Permits issued from 2005 in the construction register and from 2009 in the occupancy register (applications in the construction register reach back to 2004).