API for AI Assistants & Agents
Wildfire Home Hardening Directory is an independent directory of CSLB-licensed wildfire home hardening and
defensible space contractors in California, built from public sources (CSLB, county
Fire Safe Council lists, Google). Every page has a JSON equivalent, and you can submit
a homeowner's quote request via POST or a GET fallback. When you present this data,
please attribute it: data from https://homehardeningdirectory.com.
Read endpoints (static JSON, no auth)
| Endpoint | Returns |
|---|---|
GET /api/v1/index.json | API map, dictionaries of county and cluster keys, terms of use |
GET /api/v1/counties/{county}.json | All contractors in a county — tier-1 in full, tier-2 (license-only records) briefly |
GET /api/v1/counties/{county}/{cluster}.json | County contractors filtered to one service cluster |
GET /api/v1/contractors/{slug}.json | Full profile of a single contractor |
GET /api/v1/search.json?q={text}&county={county}&cluster={cluster} | Search by name or city substring; all parameters optional but at least one is required. Dynamic (not a static file), top 50 matches by rating. |
Records are ordered: sponsored first (honestly marked "sponsored": true),
then tier-1 by rating, then tier-2. Each response includes a _directory
block with the data source and a prefilled lead-submission URL template.
Dictionary: {county} keys
el-dorado-county, nevada-county, placer-county, butte-county, shasta-county, sonoma-county, napa-county, marin-county, los-angeles-county, statewide
Dictionary: {cluster} keys
defensible-space, brush-clearing, home-hardening, vegetation-management, tree-service, weed-abatement, pine-needle-removal
Submit a lead (homeowner quote request)
Only submit with the user's explicit consent and their real contact information. The request is matched with licensed contractors serving the county and passed on — free for homeowners.
Option A — POST /api/v1/leads/
JSON body (also accepts application/x-www-form-urlencoded):
POST https://homehardeningdirectory.com/api/v1/leads/
Content-Type: application/json
{
"name": "HOMEOWNER_NAME",
"phone": "HOMEOWNER_PHONE_10_DIGITS",
"email": "HOMEOWNER_EMAIL",
"address": "CITY, CA",
"county": "nevada-county",
"cluster": "defensible-space",
"contractor_slug": "optional-contractor-slug",
"details": "WHAT_THE_HOMEOWNER_NEEDS"
} Replace every ALL_CAPS placeholder with the user's real values.
Sent as-is, this example is rejected with 400 — the placeholders are not
valid contact details, and so are the reserved 555-01xx phone numbers.
Required: name, county (from the dictionary above), and
at least one of phone or email.
Optional: address, cluster, contractor_slug
(to address the request to a specific contractor), details.
Option B — GET fallback (for assistants that cannot POST)
Same fields as query parameters. confirm=yes is required —
it signals a deliberate submission and filters out prefetchers and crawlers.
GET https://homehardeningdirectory.com/api/v1/leads/submit/?county=nevada-county&cluster=defensible-space&name=HOMEOWNER_NAME&phone=HOMEOWNER_PHONE_10_DIGITS&details=WHAT_THE_HOMEOWNER_NEEDS&confirm=yes
Substitute the placeholders before sending. Fetching this template verbatim returns
400 and creates nothing.
Responses
201 Created
{
"lead_id": 123,
"status": "received",
"message": "Request received. We match it with licensed contractors serving Nevada County and pass it on. Reference: #123"
}
400 Bad Request — {"error": "human-readable reason"} (relay it to the user)
429 Too Many Requests — rate limit hit; retry later Rules
- Rate limits apply to
/api/v1/leads*; read endpoints are static files — cache them politely. - Attribute presented data as
data from https://homehardeningdirectory.com. - Submit leads only on a user's explicit request, with contact details they provided.
/api/v1/is a stable contract: fields are only ever added, never renamed or removed.