The Blue Book APIthebluebook.com ↗
Search commercial construction contractors by keyword, CSI trade code, and region. Returns company profiles with phone, address, website, and trade specialties.
What is the The Blue Book API?
The Blue Book Building & Construction Network API provides 4 endpoints for searching and retrieving contractor profiles from one of the largest commercial construction directories in the US. The search_companies endpoint accepts free-text keywords, optional CSI trade codes, and geographic region IDs to return paginated company summaries. Each summary includes a company_id you can pass to get_company_detail to retrieve the full profile — name, address, phone, website, description, and trade specialties.
curl -X GET 'https://api.parse.bot/scraper/ece15523-b39d-42ad-96c3-9240ef62b597/search_companies?query=General+Contractors®ion_id=43' \ -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 thebluebook-com-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: Blue Book SDK — find construction companies by trade and region."""
from parse_apis.The_Blue_Book_API import BlueBook, CompanyNotFound
client = BlueBook()
# Browse trade categories to discover a CSI code
category = client.categories.list(limit=5).first()
if category is not None:
print(category.name, category.code)
# Pick a geographic region
region = client.regions.list(limit=5).first()
if region is not None:
print(region.city, region.region)
# Search companies using the derived category code and region
if category is not None and region is not None:
for summary in client.company_summaries.search(
query="General Contractors",
csi_code=category.code,
region_id=str(region.region),
limit=3,
):
print(summary.name, summary.location)
# Navigate from summary to full company detail
company = summary.details()
print(company.address, company.phone, company.website)
for specialty in company.specialties:
print(" ", specialty)
# Point lookup by known company_id with error handling
try:
detail = client.companies.get(company_id="1703349")
print(detail.name, detail.description[:80])
except CompanyNotFound as e:
print("Company not found:", e.company_id)
print("exercised: categories.list / regions.list / company_summaries.search / details / companies.get")
Search commercial construction companies on The Blue Book by trade, optionally filtered by geographic region. The site only searches by trade class: when csi_code is omitted, the query keyword is resolved through the site's own trade suggestions (exact trade-name match preferred, otherwise the first suggested trade) and that trade is searched; when csi_code is supplied it is used directly and the keyword is ignored (it must still be non-empty). A keyword that suggests no trade (e.g. a company name or an unknown term) returns an empty results array with csi_code and category_name null. Results are paginated on the caller's side as a true offset over the site's result stream: page (default 1) and page_size (default 20, maximum 50) select which slice is returned; each call costs one round trip for the keyword resolution (when needed), one for the first site page, plus up to three more for the requested slice. The payload carries results (one summary per company, each with a company_id usable in get_company_detail), total_count (the site's reported match count, a source total that may differ by one or two from the reachable stream), page, page_size, has_more (true when a later page still holds companies), csi_code (the trade code actually searched) and category_name (that trade's name as shown by the site). A page past the end, or a trade/region combination with no listed companies, returns an empty results array with has_more false. The location field of each summary is currently always an empty string because the site's result cards do not show a location. Omitting region_id lets the site apply its own default region.
| Param | Type | Description |
|---|---|---|
| page | integer | 1-based result page to return. Values below 1 are rejected. |
| queryrequired | string | Trade keyword resolved through the site's trade suggestions (e.g. 'plumbing', 'General Contractors', 'electrical contractor'). Ignored when csi_code is supplied. |
| csi_code | string | CSI trade code for filtering results (e.g. '1680' for Electrical Contractors). Obtain codes from list_categories endpoint. |
| page_size | integer | Number of companies per page, 1 to 50 inclusive; values outside that range are rejected. |
| region_id | string | Region ID to filter by geographic area (e.g. '1' for New York - NYC region). Obtain IDs from list_regions endpoint. |
{
"type": "object",
"fields": {
"page": "integer page that was returned",
"results": "array of company summary objects with company_id (string, usable in get_company_detail), name, and location (currently always empty string)",
"csi_code": "string trade code that was searched (resolved from query or passed through); null when the keyword matched no trade",
"has_more": "boolean, true when a later page still holds companies",
"page_size": "integer requested page size",
"total_count": "integer total number of matching companies as reported by the site",
"category_name": "string name of the searched trade as shown by the site; null when the keyword matched no trade"
},
"sample": {
"data": {
"page": 1,
"results": [
{
"name": "Comanche Construction LLC",
"location": "",
"company_id": "1703349"
},
{
"name": "Place Services Commercial Construction",
"location": "",
"company_id": "1700082"
},
{
"name": "A & R Construction",
"location": "",
"company_id": "1498132"
},
{
"name": "A.G. Gaston Construction Co. Inc.",
"location": "",
"company_id": "728185"
},
{
"name": "AMCO, Inc.",
"location": "",
"company_id": "2322"
}
],
"csi_code": "2200",
"has_more": true,
"page_size": 5,
"total_count": 492,
"category_name": "General Contractors"
},
"status": "success"
}
}About the The Blue Book API
Searching for Contractors
The search_companies endpoint accepts a required query string (e.g. 'plumbing', 'HVAC', 'general contractor') and returns an array of company summary objects, each containing company_id, name, and location, plus a total_count for pagination. You can narrow results with csi_code (a CSI trade division code such as '1680' for Electrical Contractors) and region_id (a numeric ID corresponding to a specific metro area). Both filter parameters are optional and composable — you can supply one, both, or neither.
Company Profiles
Passing a company_id from search results into get_company_detail returns the full company record: name, phone, address (city/state/zip), website URL, a free-text description narrative, and a specialties array listing the trade categories the company covers. This is the primary data payload for building contractor databases, vendor qualification workflows, or subcontractor shortlists.
Reference Endpoints
Two utility endpoints support the search filters. list_regions returns all Blue Book geographic regions as objects with id, city, state, zip, region, and recordcnt. You can pass a name substring to query to filter, or use '****' to return the full list. list_categories requires no inputs and returns all available CSI trade categories as objects with name and code — the code values feed directly into the csi_code filter on search_companies. Between the two, you can enumerate the full filter space before running any searches.
The The Blue Book API is a managed, monitored endpoint for thebluebook.com — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when thebluebook.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 thebluebook.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 searchable subcontractor database filtered by CSI trade code and metro region.
- Enrich CRM records with verified phone numbers and website URLs from
get_company_detail. - Generate shortlists of electrical or mechanical contractors in a specific city using
region_idandcsi_codetogether. - Audit contractor coverage in a given region by comparing
total_countresults across multiple trades. - Populate a vendor qualification form by pulling
specialtiesanddescriptionfields for each candidate company. - Map commercial construction activity by region using
list_regionsmetadata includingrecordcntper area. - Sync Blue Book contractor profiles into a procurement or estimating platform on a scheduled basis.
| Tier | Price | Credits/month | Rate limit |
|---|---|---|---|
| Free | $0/mo | 200 | 5 req/min |
| Hobby | $30/mo | 1,000 | 20 req/min |
| Developer | $100/mo | 5,000 | 100 req/min |
| Team | $300/mo | 20,000 | 300 req/min |
| Company | $1,000/mo | 100,000 | 500 req/min |
Each endpoint has a fixed posted price per successful call — most fall between 1 and 10 credits — shown on this API's page before you run it. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.
Does The Blue Book have an official developer API?+
What does `get_company_detail` return and what does it not include?+
name, phone, address, website, description, company_id, and a specialties array. It does not currently return email addresses, employee counts, license numbers, or project history. You can fork this API on Parse and revise it to add an endpoint targeting any additional profile data the source exposes.Can I retrieve reviews or ratings for a contractor?+
How do CSI trade codes work in the search filter?+
csi_code parameter on search_companies accepts a code string from the list_categories endpoint, which returns all available categories as objects with name and code fields. Run list_categories first to get valid codes, then pass a code such as '1680' to restrict results to a single trade division.Is search_companies paginated, and how do I navigate pages?+
total_count integer alongside the results array so you can determine how many matching companies exist. Check the endpoint's pagination parameters for the specific page or offset inputs — total_count tells you how many records are available across all pages.