# MacRAE's Blue Book Scraper: US Industrial Suppliers (`rel8ble/macraes-blue-book-scraper`) Actor

MacRAE's Blue Book scraper: find US and Canadian industrial suppliers by product, company or state. One result = one supplier: company, phone, fax, address, website, business type, certifications, product headings. For supplier sourcing and B2B leads. No login. $1.50 per 1,000.

- **URL**: https://apify.com/rel8ble/macraes-blue-book-scraper.md
- **Developed by:** [Giovanni Rich](https://apify.com/rel8ble) (community)
- **Categories:** Lead generation, Business, E-commerce
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$1.50 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## MacRAE's Blue Book Scraper: US Industrial Suppliers

**Industrial supplier directory scraper** for procurement teams, sourcing agents, B2B sales and market researchers: type a product such as **ball valves**, **cnc machining** or **injection molding**, and get **manufacturers and distributors from MacRAE's Blue Book** ("America's Original Industrial Directory Since 1893", as its home page says) as clean rows with **phone, fax, street address, website, business type, certifications and every product heading** they list. Filter by **US state or Canadian province**.

It works over plain HTTP, with **no browser and no login**. 20 suppliers with full details took 41 seconds in the Apify cloud (one run). List-only mode reads 25 suppliers per request.

### What you get

- **Contacts**: company name, **phone**, toll-free, **fax**, **website**, street, city, state, ZIP, country, LinkedIn / Facebook / X / YouTube links. Contact-person names are not collected.
- **What they do**: **business type** (Manufacturer, Distributor, Service, Exporter, Importer) with `isManufacturer` and `isDistributor` flags, **certifications** as listed (ISO 9001, AS9100, ITAR ...), **all product and service headings** with their codes, company description, featured products and logo for advertisers.
- **How you found them**: category, number of suppliers in that category, keyword or company name, state, company ID, profile URL.

**Not on this site:** MacRAE's Blue Book is a request-for-quote directory. It does not publish prices, minimum order quantities or e-mail addresses (e-mail goes through a site form). For e-mails, feed the `website` column into [Website Contact Extractor](https://apify.com/rel8ble/website-contact-extractor).

### Sample output

Real rows from the cloud run with the default input (`ball valves`, 20 results, 41 seconds):

| Company | Phone | City | Type | Website |
|---|---|---|---|---|
| Global Hose & Industrial Sales Co. (SDVOSB) | 615-262-2620 | Nashville, TN | Manufacturer / Distributor / Service | global-hose.com |
| Modern Industrial | 888-517-2310 | Fort Mill, SC | Distributor | modernindustrial.com |
| Metal Worx Express | 267-401-1670 | Huntingdon Valley, PA | Distributor / Service | metalworxexpress.com |
| Nycoil Co | 864-288-9906 | Spartanburg, SC | Manufacturer | nycoil.com |
| R & A Industries Inc. | 781-393-9114 | Medford, MA | Distributor / Service | raindusa.com |

Fill rates on those 20 rows: phone 90%, website 95%, street 100%. On 300 `hydraulic cylinders` suppliers (test run): **phone 99%**, fax 94%, **website 90%**, street address 100%, business type on most rows, certification 11%. 61% are manufacturers.

### Use cases

- **Supplier sourcing**: shortlist certified machine shops or valve makers in a region and call them for quotes.
- **B2B lead generation**: lists of US manufacturers by product line, with phone and website, for sales outreach.
- **Distributor search**: find who distributes a product line in a state or province.
- **Market mapping**: count suppliers per state or per product, see who holds which certification.
- **Data enrichment**: look companies up by name and add phone, address and product lines to your CRM.
- **AI agents**: an agent can call this actor with a product keyword and read back suppliers (see the MCP note below).

### Pricing

**$1.50 per 1,000 suppliers** ($0.0015 per result), pay per result, no start fee. Failed requests and filtered rows are never charged.

| Job | Rows | Cost |
|---|---|---|
| Quick test (default) | 20 | $0.03 |
| One product in one state | about 50 | $0.08 |
| One large heading, e.g. all "Prototypes" suppliers | 1,319 | about $2 |

Apify's free plan ($5 of monthly credit) covers about 3,300 results.

Other actors on the Store (free-plan prices, read 5 Nov 2026). Some ThomasNet actors charge less per row, for a different directory:

| Actor (30-day users) | Price per 1,000 suppliers |
|---|---|
| **This one** | **$1.50, details included, no start fee** |
| scrapers_lat MacRAE's Blue Book (1) | $20.00 |
| zen-studio ThomasNet (154) | $4.99 |
| azzouzana ThomasNet (23) | $1.00 + $0.005 per run |
| memo23 ThomasNet (16) | $1.00 + $0.005 per run |
| dami_studio ThomasNet (3) | $0.85 + $0.001 per run |
| fraktalapi ThomasNet (2) | $1.00 + $0.00005 per run |
| ahmed_jasarevic ThomasNet (1) | $0.90 + $0.00005 per run |
| exuberantal Global Sources, ThomasNet and Kompass (1) | $0.75 |

### FAQ

**Does it return prices or minimum order quantities?**
No, because the site does not publish them. Suppliers quote on request. Use the phone number or website to ask.

**Does it return e-mails?**
No. The site takes messages through a form and does not show addresses. Pair it with Website Contact Extractor on the `website` column.

**Why are a few rows from another state?**
Advertisers can appear in a state's list as "serving <state>". The `servingArea` column marks them, the address shows their real location, and `basedInStateOnly` drops them.

**How current is the data?**
It is what each supplier's listing shows today. Listings are kept up by the suppliers, so some details can be old (a certification year, for example). Check before you rely on one.

**Why fewer rows than the heading's total?**
Filters, `maxResultsPerSearch`, or `uniqueCompanies` skipping a company already saved from another heading. `RUN_SUMMARY` gives the counts.

**How long does a big pull take?**
With profiles, plan on roughly a row a second: the demo run averaged about 4 seconds a request in the cloud at 4 parallel requests, and the actor never goes over 300 requests a minute. A 1,319-supplier heading would take around 20-25 minutes (an estimate, not a measured run). List-only mode reads 25 rows per request. Raise `maxConcurrency` if you need more speed.

**Is there an official API?**
Not a public one that we could find. This actor reads the same public pages you see in a browser and returns them as JSON.

**For AI agents (MCP):** input is a list of product keywords (e.g. `ball valves`) plus optional states and filters; output is one JSON row per supplier with phone, address, website, business type, certification and product headings; typical cost is $0.03 for 20 rows; use it when you need US or Canadian industrial manufacturers or distributors of a given product. It does not return prices, MOQs or e-mails.

### Why this one

- **$1.50 per 1,000 suppliers, details included**, no start fee, against $20.00 for the only other MacRAE's Blue Book actor we found. ThomasNet actors read a different directory (prices under Pricing), so run this next to one of them if you want the widest supplier list.
- **Keyword to heading matching**: the site splits products into thousands of headings ("valves" matches 521). The actor ranks them (same words first, then the largest) and reads the best few, or all of them if you ask.
- **By state**: "Ohio", "TX" or "ON"; each keyword runs once per state, using the site's own local lists.
- **Filters before you pay**: manufacturer or distributor, certification text ("AS9100"), phone or website present. Filtered rows are never charged.
- **One row per company** across headings and keywords, by default.
- **Fast list-only mode** when you just need names and locations: 60 rows took 2.5 seconds in a test run outside the cloud.

### Example inputs for common jobs

First 20 ball valve suppliers with full details (default):

```json
{ "searchTerms": ["ball valves"], "maxResultsPerSearch": 20 }
```

AS9100 machine shops in Ohio and Texas:

```json
{ "searchTerms": ["cnc machining"], "states": ["OH", "TX"], "maxResultsPerSearch": 0, "certificationContains": ["AS9100"] }
```

Manufacturers with a phone and a website across every heading that matches:

```json
{ "searchTerms": ["hydraulic cylinders"], "maxCategoriesPerSearch": 0, "maxResultsPerSearch": 500, "businessTypes": ["manufacturer"], "requirePhone": true, "requireWebsite": true }
```

Look companies up by name:

```json
{ "companyNames": ["Parker Hannifin", "Mueller Co"], "maxResultsPerSearch": 10 }
```

A whole category you already picked, from its URL:

```json
{ "startUrls": [{ "url": "https://www.macraesbluebook.com/search/product_company_list.cfm?prod_code=6045900" }], "maxResultsPerSearch": 0 }
```

Names and locations only, fast:

```json
{ "searchTerms": ["injection molding"], "maxResultsPerSearch": 500, "scrapeDetails": false }
```

### How to use

1. Enter one or more product keywords, company names or macraesbluebook.com URLs.
2. Optionally add states or provinces and set **Max suppliers per search** (default 20; 0 = everything listed).
3. Optionally add filters: business type, certification, phone or website present.
4. Click **Start**. Download the dataset as JSON, CSV, Excel or HTML, or read it through the API.

### Input

| Field | Type | Meaning |
|---|---|---|
| `searchTerms` | list | Product or service keywords, 3-40 characters |
| `companyNames` | list | Companies to look up by name |
| `startUrls` | list | Category, profile or search result URLs |
| `states` | list | US states or Canadian provinces, name or code |
| `maxResultsPerSearch` | integer | Default 20; 0 = everything listed |
| `maxCategoriesPerSearch` | integer | Headings read per keyword. Default 3; 0 = all matches (up to 300) |
| `scrapeDetails` | boolean | Default true. false = list data only, much faster |
| `uniqueCompanies` | boolean | Default true: a company is saved and charged once per run |
| `requirePhone`, `requireWebsite`, `requireCertification` | boolean | Skip rows without it |
| `certificationContains` | list | Keep rows whose certification mentions any of these |
| `businessTypes` | list | `manufacturer`, `distributor`, `service`, `exporter`, `importer` |
| `basedInStateOnly` | boolean | Drop advertisers listed as "serving <state>" from elsewhere |

`states` applies to keywords and company names; a start URL keeps whatever state it already has.

### Output

One JSON row per supplier (trimmed example from a real run):

```json
{
  "companyName": "Hi-Tech Controls, Inc.",
  "companyId": "877222",
  "phone": "303-680-5159",
  "tollFreePhone": null,
  "fax": "303-680-5344",
  "website": "http://www.hitechcontrols.com/?ex=e3iejl-7s51d1-2hsph-du9m5x",
  "street": "7374 S. Eagle Street",
  "city": "Centennial",
  "state": "CO",
  "postalCode": "80112",
  "country": "USA",
  "servingArea": null,
  "businessActivities": [
    "Manufacturer",
    "Distributor",
    "Exporter"
  ],
  "isManufacturer": true,
  "isDistributor": true,
  "certification": "ISO 9001:2000",
  "products": [
    "BALLS: Valve",
    "BOXES",
    "BOXES: Custom",
    "BOXES: Electrical"
  ],
  "productCodes": [
    "424200",
    "859200",
    "865500",
    "867600"
  ],
  "productCount": 184,
  "featuredProducts": [],
  "description": "Hi-Tech Controls, Inc. and their supplier, HELUKABEL®, are a one stop source for wires and cables requiring RoHS, UL, CSA, Harmonized & CE approval. Cables for ...",
  "linkedin": null,
  "facebook": null,
  "twitter": null,
  "youtube": null,
  "instagram": null,
  "videoUrls": [],
  "logoUrl": null,
  "timeZone": "Mountain",
  "listingType": "basic",
  "detailsScraped": true,
  "matchedCategory": "Ball Valves",
  "matchedCategoryCode": "8322750",
  "categorySupplierCount": 411,
  "searchTerm": "ball valves",
  "searchType": "keyword",
  "stateFilter": null,
  "profileUrl": "https://www.macraesbluebook.com/search/company.cfm?company=877222",
  "sourceUrl": "https://www.macraesbluebook.com/search/product_company_list.cfm?prod_code=8322750",
  "position": 12,
  "scrapedAt": "2026-11-02T18:47:23.828Z"
}
```

The key-value store also holds `RUN_SUMMARY`: results per search, headings read, filtered rows, ignored inputs and why each search stopped.

### Integrations

Run it on an Apify schedule, through the Apify REST API, the JavaScript / Python clients, Make, Zapier, n8n, Google Sheets, or from AI agents via the Apify MCP server. Join runs on `companyId` to track new and removed suppliers.

This actor is not affiliated with MacRAE's Blue Book. It reads public pages that the site's robots.txt allows (read 5 Nov 2026: `keynoteselector.cfm`, `/Templates/` and `/search/special/` are disallowed, and the actor reads none of them).

Need a custom scraper or a ready dataset? Hire me on Fiverr: https://www.fiverr.com/rel8ble

# Actor input Schema

## `searchTerms` (type: `array`):

What the suppliers should make or sell, e.g. "ball valves", "cnc machining", "injection molding". 3-40 characters each. Each keyword is matched to the site's product headings and the best ones are read. Provide this, company names or start URLs; with nothing at all the actor runs a "ball valves" demo.

## `companyNames` (type: `array`):

Optional. Look suppliers up by name, e.g. "Parker Hannifin". The first rows of each search are the closest names.

## `startUrls` (type: `array`):

Optional. macraesbluebook.com category pages (search/product_company_list.cfm?prod_code=..., with or without \&region=...), company profiles (search/company.cfm?company=...) or search result pages.

## `states` (type: `array`):

Optional. Names or codes, e.g. "Ohio", "TX", "ON". Each keyword runs once per state. The site also lists advertisers "serving" a state from elsewhere; see the option below. Empty = all of the US and Canada.

## `maxResultsPerSearch` (type: `integer`):

Optional. Rows saved per keyword (per state), company name or URL, integer >= 0. Default 20; 0 = everything listed. You pay per row.

## `maxCategoriesPerSearch` (type: `integer`):

Optional. A keyword can match many headings ("valves" matches 521). They are ranked (same words first, then larger headings) and this many are read. Default 3; 0 = all matches (up to 300).

## `scrapeDetails` (type: `boolean`):

Default true: one extra request per supplier adds phone, fax, street address, website, business type, certification and every product heading (same price). false = list data only (name, city, state, short text, website for advertisers), about 25x fewer requests.

## `uniqueCompanies` (type: `boolean`):

Default true: a supplier found under several headings or keywords is saved and charged once. false = once per heading, so you can see every heading it appears in.

## `requirePhone` (type: `boolean`):

Optional. Skip suppliers without a phone number. Default false.

## `requireWebsite` (type: `boolean`):

Optional. Skip suppliers without a website. Default false.

## `requireCertification` (type: `boolean`):

Optional. Skip suppliers that list no certification. Default false.

## `certificationContains` (type: `array`):

Optional. Keep suppliers whose certification text contains any of these, e.g. "ISO 9001", "AS9100", "ITAR".

## `businessTypes` (type: `array`):

Optional. Keep suppliers with any of these types: "manufacturer", "distributor", "service", "exporter", "importer". Empty = all.

## `basedInStateOnly` (type: `boolean`):

Optional. With "states": drop advertisers listed as "serving <state>" that are based elsewhere. Default false.

## `maxConcurrency` (type: `integer`):

Optional, advanced. Parallel requests, 1-10. Default 4. The actor stays under 300 requests a minute either way.

## `maxRequestRetries` (type: `integer`):

Optional, advanced. Retries per failed request (each on a new proxy session), 0-20. Default 6.

## `proxyConfiguration` (type: `object`):

Optional, advanced. Default: Apify datacenter proxy.

## Actor input object example

```json
{
  "searchTerms": [
    "ball valves"
  ],
  "maxResultsPerSearch": 20,
  "maxCategoriesPerSearch": 3,
  "scrapeDetails": true,
  "uniqueCompanies": true,
  "requirePhone": false,
  "requireWebsite": false,
  "requireCertification": false,
  "basedInStateOnly": false,
  "maxConcurrency": 4,
  "maxRequestRetries": 6,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (type: `string`):

One row per supplier: company, phone, address, website, business type, certification and product headings.

## `summary` (type: `string`):

Per-search counts, categories read, filtered rows, ignored inputs and stop reasons.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "searchTerms": [
        "ball valves"
    ],
    "maxResultsPerSearch": 20,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("rel8ble/macraes-blue-book-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "searchTerms": ["ball valves"],
    "maxResultsPerSearch": 20,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("rel8ble/macraes-blue-book-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchTerms": [
    "ball valves"
  ],
  "maxResultsPerSearch": 20,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call rel8ble/macraes-blue-book-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,rel8ble/macraes-blue-book-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/jcKsKgbqsAzzfzilK/builds/I6meO42MF2MxFfuJX/openapi.json
