williamshomes.com APIwilliamshomes.com ↗
Access Williams Homes community listings, floor plans, available homes, pricing, and specs across CA, ID, and MT via two structured API endpoints.
curl -X GET 'https://api.parse.bot/scraper/12ca6019-2528-4693-96c4-c70b23f44cb9/get_community_homes' \ -H 'X-API-Key: $PARSE_API_KEY'
Typed Python client. Install the CLI, sign in, then pull this API’s generated client:
pip install parse-sdk parse login parse add --marketplace williamshomes-com-api
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.
"""
Williams Homes API Client
Get your API key from: https://parse.bot/settings
"""
import os
import requests
from typing import Any, Dict, List, Optional
class ParseClient:
"""Client for interacting with the Williams Homes Parse API."""
def __init__(self, api_key: Optional[str] = None):
"""
Initialize the Parse API client.
Args:
api_key: API key for authentication. If not provided, reads from PARSE_API_KEY env var.
"""
self.base_url = "https://api.parse.bot"
self.scraper_id = "12ca6019-2528-4693-96c4-c70b23f44cb9"
self.api_key = api_key or os.getenv("PARSE_API_KEY")
if not self.api_key:
raise ValueError("API key not provided and PARSE_API_KEY environment variable not set")
def _call(self, endpoint: str, method: str = "POST", **params) -> Dict[str, Any]:
"""
Make a request to the Parse API.
Args:
endpoint: API endpoint name
method: HTTP method (GET or POST)
**params: Query/body parameters
Returns:
Response JSON as dictionary
"""
url = f"{self.base_url}/scraper/{self.scraper_id}/{endpoint}"
headers = {
"X-API-Key": self.api_key,
"Content-Type": "application/json"
}
if method == "GET":
response = requests.get(url, headers=headers, params=params)
elif method == "POST":
response = requests.post(url, headers=headers, json=params)
else:
raise ValueError(f"Unsupported HTTP method: {method}")
response.raise_for_status()
return response.json()
def list_communities(self) -> Dict[str, Any]:
"""
List all active Williams Homes communities.
Returns:
Dictionary containing list of communities and total count
"""
return self._call("list_communities", method="GET")
def get_community_homes(
self,
community_slug: str,
state_code: str,
city_slug: str
) -> Dict[str, Any]:
"""
Retrieve all floor plans and available homes for a specific community.
Args:
community_slug: URL slug of the community (e.g., 'palmera')
state_code: Two-letter lowercase US state code (e.g., 'ca')
city_slug: URL slug of the city (e.g., 'camarillo')
Returns:
Dictionary containing community info, floor plans, and available homes
"""
return self._call(
"get_community_homes",
method="GET",
community_slug=community_slug,
state_code=state_code,
city_slug=city_slug
)
def main():
"""Example workflow: explore communities and find homes in a specific community."""
# Initialize client
client = ParseClient()
print("=" * 70)
print("Williams Homes Community & Inventory Search")
print("=" * 70)
# Step 1: List all communities
print("\n[Step 1] Fetching all Williams Homes communities...")
communities_response = client.list_communities()
if communities_response.get("status") != "success":
print("Failed to fetch communities")
return
communities = communities_response["data"]["communities"]
total_communities = communities_response["data"]["total"]
print(f"Found {total_communities} communities:")
print("-" * 70)
for i, community in enumerate(communities[:5], 1):
print(f"{i}. {community['community_name']} - {community['city']}, {community['state']}")
# Step 2: Pick a community and get detailed inventory
print("\n[Step 2] Selecting first community and fetching inventory...")
selected_community = communities[0]
print(f"\nSelected: {selected_community['community_name']}")
print(f"Location: {selected_community['city']}, {selected_community['state']}")
# Step 3: Get homes and plans for selected community
homes_response = client.get_community_homes(
community_slug=selected_community["community_slug"],
state_code=selected_community["state_code"],
city_slug=selected_community["city_slug"]
)
if homes_response.get("status") != "success":
print("Failed to fetch community homes")
return
community_data = homes_response["data"]
# Step 4: Display floor plans
print("\n" + "=" * 70)
print("FLOOR PLANS")
print("=" * 70)
plans = community_data.get("plans", [])
print(f"Total Plans: {community_data.get('total_plans', 0)}\n")
for plan in plans:
print(f"Plan: {plan['plan_name']}")
print(f" Starting Price: ${plan['from_price']:,}")
print(f" Bedrooms: {plan['bedrooms']} | Bathrooms: {plan['bathrooms']}")
print(f" Square Footage: {plan['square_footage']}")
print()
# Step 5: Display available homes
print("=" * 70)
print("AVAILABLE HOMES")
print("=" * 70)
available_homes = community_data.get("available_homes", [])
print(f"Total Available: {community_data.get('total_available_homes', 0)}\n")
# Group homes by plan and show summary
homes_by_plan = {}
for home in available_homes:
plan_name = home["plan_name"]
if plan_name not in homes_by_plan:
homes_by_plan[plan_name] = []
homes_by_plan[plan_name].append(home)
for plan_name, homes_in_plan in homes_by_plan.items():
print(f"\n{plan_name} ({len(homes_in_plan)} available)")
print("-" * 70)
for home in homes_in_plan[:3]: # Show first 3 homes per plan
qmi_label = " [QMI Available]" if home.get("is_qmi") else ""
print(f" • {home['address']}")
print(f" Lot: {home['lot_number']} | Price: ${home['price']:,}{qmi_label}")
print(f" {home['bedrooms']} bed, {home['bathrooms']} bath | {home['square_footage']} sqft")
if len(homes_in_plan) > 3:
print(f" ... and {len(homes_in_plan) - 3} more homes")
# Step 6: Summary statistics
print("\n" + "=" * 70)
print("SUMMARY")
print("=" * 70)
qmi_count = sum(1 for h in available_homes if h.get("is_qmi"))
avg_price = sum(h["price"] for h in available_homes) / len(available_homes) if available_homes else 0
print(f"Total Available Homes: {len(available_homes)}")
print(f"QMI Available: {qmi_count}")
print(f"Average Price: ${avg_price:,.0f}")
print(f"Price Range: ${min(h['price'] for h in available_homes):,} - ${max(h['price'] for h in available_homes):,}")
# Find the most expensive and least expensive
if available_homes:
most_expensive = max(available_homes, key=lambda x: x["price"])
least_expensive = min(available_homes, key=lambda x: x["price"])
print(f"\nMost Expensive: {most_expensive['address']} (${most_expensive['price']:,})")
print(f"Least Expensive: {least_expensive['address']} (${least_expensive['price']:,})")
if __name__ == "__main__":
main()Retrieve all floor plans and available homes for a specific Williams Homes community. Returns plan specifications (name, starting price, beds, baths, square footage) and individual available home listings with plan associations, lot numbers, QMI status, and pricing.
| Param | Type | Description |
|---|---|---|
| city_slugrequired | string | URL slug of the city (e.g. 'camarillo', 'star', 'bozeman'). Obtainable from the list_communities endpoint. |
| state_coderequired | string | Two-letter lowercase US state code (e.g. 'ca', 'id', 'mt'). |
| community_slugrequired | string | URL slug of the community (e.g. 'palmera', 'cranefield', 'base-camp'). Obtainable from the list_communities endpoint. |
{
"type": "object",
"fields": {
"plans": "array of plan objects with plan_name, builder_name, community_name, from_price, bedrooms, bathrooms, square_footage, listing_url",
"total_plans": "integer",
"builder_name": "string",
"community_name": "string",
"available_homes": "array of home objects with address, builder_name, community_name, plan_name, lot_number, price, is_qmi, qmi_price, bedrooms, bathrooms, square_footage, listing_url",
"total_available_homes": "integer"
},
"sample": {
"data": {
"plans": [
{
"bedrooms": 2,
"bathrooms": 2.5,
"plan_name": "Plan A",
"from_price": 728600,
"listing_url": "https://williamshomes.com/communities/ca/camarillo/palmera/plan/plan-a---palmera",
"builder_name": "Williams Homes",
"community_name": "Palmera",
"square_footage": "1707+"
}
],
"total_plans": 4,
"builder_name": "Williams Homes",
"community_name": "Palmera",
"available_homes": [
{
"price": 824815,
"is_qmi": true,
"address": "2852 Via Descanso",
"bedrooms": 3,
"bathrooms": 2.5,
"plan_name": "Plan C",
"qmi_price": 824815,
"lot_number": "111",
"listing_url": "https://williamshomes.com/available-homes/ca/camarillo/palmera/1288",
"builder_name": "Williams Homes",
"community_name": "Palmera",
"square_footage": 1918
}
],
"total_available_homes": 20
},
"status": "success"
}
}About the williamshomes.com API
The Williams Homes API covers 2 endpoints that expose community listings, floor plan specifications, and available home inventory across California, Idaho, and Montana. The get_community_homes endpoint returns both plan-level data (beds, baths, square footage, starting price) and individual available home records with lot numbers, QMI status, and addresses. The list_communities endpoint surfaces all active communities with the slugs needed to query them.
Endpoints
The API exposes two endpoints. list_communities requires no inputs and returns every active Williams Homes community as an array, each object containing community_name, community_slug, city_slug, state_code, city, state, and url. The total field gives the full count. Use the community_slug, city_slug, and state_code values from this response as inputs to the second endpoint.
Community Homes Data
get_community_homes accepts three required parameters — state_code (e.g. ca), city_slug (e.g. camarillo), and community_slug (e.g. palmera) — and returns two parallel data sets. The plans array contains floor plan objects with plan_name, from_price, bedrooms, bathrooms, square_footage, builder_name, community_name, and listing_url. The available_homes array lists specific homes for sale, each with address, lot_number, plan_name, price, is_qmi, qmi_price, bedrooms, and bathrooms. total_plans and total_available_homes integers accompany each array.
QMI and Inventory
The is_qmi boolean on each available home flags Quick Move-In properties. Where applicable, a separate qmi_price is returned alongside the standard price field, letting you distinguish move-in-ready units from to-be-built inventory. Geographic coverage is currently limited to Williams Homes' active markets: California, Idaho, and Montana.
The williamshomes.com API is a managed, monitored endpoint for williamshomes.com — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when williamshomes.com 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 williamshomes.com 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?+
- Build a new-construction home search tool filtered by state, beds, baths, and price range using
plansandavailable_homesfields. - Track Quick Move-In (QMI) inventory by monitoring the
is_qmiflag andqmi_priceacross all communities. - Compare starting prices across floor plans within a single community using
from_pricefrom theplansarray. - Generate community summary pages by pulling
community_name,city,state, andurlfromlist_communities. - Alert buyers when a specific floor plan becomes available by polling
total_available_homesand matchingplan_nameinavailable_homes. - Aggregate lot-level inventory data using
lot_number,address, andpricefor new-construction market analysis. - Map available homes to their parent floor plan specs by joining
plan_nameacross theplansandavailable_homesarrays.
| 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 | 250 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 Williams Homes offer an official developer API?+
What does `get_community_homes` return for floor plans versus available homes?+
plans array contains plan-level data: plan_name, from_price, bedrooms, bathrooms, square_footage, and listing_url. The available_homes array contains individual home records with address, lot_number, price, is_qmi, qmi_price, and the associated plan_name. The two arrays can be joined on plan_name to map specific available units to their floor plan specs.Which states and markets are covered?+
state_code parameter (e.g. ca, id, mt). Communities outside these three states are not covered. You can fork this API on Parse and revise it to add coverage for additional builders or markets.Does the API return photos, virtual tours, or floor plan images?+
Can I filter available homes by price range or bedroom count directly in the API?+
get_community_homes returns the full set of plans and available homes for a given community, and filtering by price, bedrooms, or bathrooms must be applied client-side after receiving the response arrays.