Los Angeles APIlosangeles.gov ↗
Access LA building permits, inspections, code enforcement, certificates of occupancy, parcel zoning, and retrofit compliance data via 8 structured endpoints.
What is the Los Angeles API?
The Los Angeles LADBS API provides 8 endpoints covering the full lifecycle of building activity at any LA address — from permit search to inspection history. Starting with search_permits_by_address, you can resolve a street address into an address_id that unlocks permit lists, parcel profiles, code enforcement cases, certificates of occupancy, and seismic retrofit compliance status. All data is drawn from the LA Department of Building and Safety database.
curl -X GET 'https://api.parse.bot/scraper/529a8bbd-aaca-475d-82da-568cb822cf27/search_permits_by_address?street_name=MAIN&street_number=100' \ -H 'X-API-Key: $PARSE_API_KEY'
Typed, relational, agent-ready
A generated client with real types, enums, and the links between objects — the structure a flat JSON response can't carry. Autocompletes in your editor and reads cleanly to coding agents.
- Fully typed · autocompletes
- Objects link to objects
- Typed errors & pagination
Typed Python client. Set up the SDK in your uv project, then pull this API’s typed client:
uv add parse-sdk uv run parse init uv run parse add --marketplace losangeles-gov-api
uv run parse add --marketplace pulls a pinned snapshot of this canonical API — it won’t change underneath you. To customize it, subscribe and swap to your own copy.
"""Walkthrough: LADBS SDK — property permit investigation in Los Angeles."""
from parse_apis.ladbs_online_services_api import LADBS, AddressNotFound
client = LADBS()
# Search for properties at an address
results = client.addresssearchresults.search(street_number="200", street_name="SPRING", limit=5)
for addr in results:
print(addr.id, addr.address)
# Drill into the first address — get summary of available data
address = client.addresssearchresults.search(street_number="100", street_name="MAIN", limit=1).first()
if address:
summary = address.summary()
print(summary.address, len(summary.sections), "sections")
for section in summary.sections:
print(section.name, section.count)
# Parcel profile — zoning, lot, tract info
profile = address.parcel_profile()
print(profile.zones, profile.lot, profile.council_district)
# List permits and get details on the first one
permit = address.permits(limit=1).first()
if permit:
detail = permit.details()
print(permit.permit_number, permit.type, detail.status_history)
# Code enforcement cases
for case in address.code_enforcement(limit=3):
print(case.date_received, case.problem_description, case.status)
# Retrofit compliance info
retrofit = address.retrofit_info()
print(retrofit.soft_story, retrofit.non_ductile_concrete)
# Typed error handling
try:
bad = client.address(id="9999999").summary()
print(bad.address)
except AddressNotFound as exc:
print(f"Address not found: {exc}")
print("exercised: search / summary / parcel_profile / permits / details / code_enforcement / retrofit_info")
Search for building permits by street address. Returns matching addresses with numeric IDs for further lookups. Multiple matches may be returned if the street name matches addresses in different directions (N, S, E, W). A single exact match redirects directly and returns as 'Direct Match'.
| Param | Type | Description |
|---|---|---|
| street_namerequired | string | Street name without prefixes or suffixes, uppercase preferred (e.g., 'MAIN', 'SPRING') |
| street_numberrequired | string | Street number (e.g., '200'). Do not use fractions. |
{
"type": "object",
"fields": {
"addresses": "array of objects with 'address' (string, full street address) and 'id' (string, numeric ID for use in other endpoints)"
},
"sample": {
"data": {
"addresses": [
{
"id": "630413",
"address": "200 N SPRING ST 90012"
},
{
"id": "630516",
"address": "200 S SPRING ST 90012"
}
]
},
"status": "success"
}
}About the Los Angeles API
Address Resolution and Permit Discovery
All lookups begin with search_permits_by_address, which accepts a street_number and street_name (uppercase preferred, no prefixes or suffixes) and returns an array of matched addresses, each with an id field. That id feeds into every other endpoint. A useful first step after resolving an address is get_property_permit_summary, which returns an array of sections — each with a name and count — so you can see how many permits, code enforcement cases, or certificates of occupancy exist before making individual detail requests.
Permit Details and Inspection History
get_permit_list_by_parcel returns all permits for a parcel, each containing a permit_number, a three-part ID (id1, id2, id3), job_number, and type. Pass those three ID parts to get_permit_details to retrieve summary, contact_info, clearance_info, inspector_info, status_history, inspection_history, and pending_inspections. Note that older permits may return empty string fields when detail records are not stored in the LADBS system, and parcels with very large permit counts may time out.
Parcel, Compliance, and Enforcement Data
get_parcel_profile returns zoning designations (Zone(s)), lot and tract identifiers, council district, and associated job addresses for a parcel — field availability varies by address. get_code_enforcement_info returns an array of enforcement cases with date_received, case_id, problem_description, and status. get_certificate_of_occupancy returns CoO records including cofo_number, date, and status. get_retrofit_program_info returns soft_story and non_ductile_concrete compliance status text, reflecting LA's mandatory seismic retrofit programs.
The Los Angeles API is a managed, monitored endpoint for losangeles.gov — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when losangeles.gov changes and a check fails, the API is automatically queued for repair and re-verified. It is built to keep working as the site underneath it changes.
This isn't an official losangeles.gov API — it's an independent, maintained REST wrapper over public data. Where the source has no official API (or only a limited one), Parse gives you a stable contract over a source that never promised one, and keeps it current. Need a new endpoint or field? You can revise it yourself in plain English and the agent rebuilds it against the live site in minutes — contributing the change back to the shared API is free.
Will this API break when the source site changes?+
Is this an official API from the source site?+
Can I fix or extend this API myself if I need a new endpoint or field?+
What happens if I call an endpoint that has an issue?+
- Audit a property's full permit history before a real estate transaction using
get_permit_list_by_parcel - Check open code enforcement cases on a target address with
get_code_enforcement_info - Verify a building's certificate of occupancy status for due diligence or lending purposes
- Look up seismic retrofit compliance for soft-story or non-ductile concrete buildings via
get_retrofit_program_info - Pull zoning designations and council district assignments for parcels using
get_parcel_profile - Track inspection history and pending inspections on active construction permits via
get_permit_details - Build a property research dashboard that aggregates permit counts, enforcement cases, and CoO records by address
| Tier | Price | Credits/month | Rate limit |
|---|---|---|---|
| Free | $0/mo | 100 | 5 req/min |
| Hobby | $30/mo | 1,000 | 20 req/min |
| Developer | $100/mo | 5,000 | 100 req/min |
One credit = one API call regardless of which marketplace API you call. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.
Does the City of Los Angeles have an official developer API for LADBS data?+
What does `get_permit_details` return, and what are its limitations?+
get_permit_details returns summary, contact_info, clearance_info, inspector_info, status_history, inspection_history, and pending_inspections for a specific permit identified by a three-part ID (id1, id2, id3) from get_permit_list_by_parcel. Older permits frequently return empty string fields because detail records are not retained in the LADBS system for historical entries.Does the API return permit valuation amounts or construction cost estimates?+
Can I search for permits across multiple addresses in a single request?+
search_permits_by_address accepts one street_number and street_name per call and returns matching addresses with their IDs. There is no batch input. Each address requires a separate call. You can fork the API on Parse and revise it to add a batch wrapper endpoint if needed.How complete is the parcel profile data returned by `get_parcel_profile`?+
get_parcel_profile returns whatever fields LADBS has on record for a given address_id, including Lot, Tract, Zone(s), Council District, and job_addresses. The field set is variable — some addresses return fewer fields than others depending on what is stored in the underlying LADBS database. There is no guaranteed minimum set of fields for every parcel.