# BluePages Saudi Directory Scraper: Phones, Emails & WhatsApp (`automatic/bluepages-saudi-directory`) Actor

Collect Saudi company profiles from BluePages: name, activity, city and region with ISO code, address, published phones, emails, websites, WhatsApp, map and social links. Schedule daily runs to get only new or changed profiles. Contacts are as published, unverified. $1.50 per 1,000 profiles.

- **URL**: https://apify.com/automatic/bluepages-saudi-directory.md
- **Developed by:** [Philip Kirkbride](https://apify.com/automatic) (community)
- **Features:** 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 business profiles

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

## BluePages Saudi Business Profiles & Contacts

Build a Saudi supplier shortlist from **BluePages** business profiles. Get company names, activities, cities, regions, addresses and any published business phones, emails, WhatsApp numbers and websites in a dataset you can export to Excel, CSV or JSON.

**$1.50 per 1,000 delivered profiles. No start fee.** Contacts are included when the directory publishes them, with no additional contact charge.

### Useful for

- **Supplier research:** collect available business profiles for a product or service shortlist.
- **Market mapping:** compare businesses by their published activities and locations.
- **CRM preparation:** bring selected profiles and their source links into one consistent export, with region and ISO codes for your own data model.
- **Directory monitoring:** follow new or changed profiles over time instead of re-exporting the same rows.

### What you get

Each result contains one business profile with:

- Business name and published activity.
- City and the administrative region, plus ISO codes for joining.
- Address and postal code where the directory publishes them.
- Published business phone numbers, email addresses, websites and WhatsApp numbers where available.
- A published map link and social-media profile links where available.
- The original BluePages profile link and an observation date.

Missing fields stay empty: a profile can be useful with a phone but no email, or with a name and location but no contacts. Company branches can have separate profiles in different cities.

Download results as **CSV, Excel or JSON**, or read the dataset through the Apify API.

### Join keys for your CRM or data model

| Field | What it is |
| --- | --- |
| `recordId` | Stable identity for this profile in this Actor: the directory's company UUID plus the city context. Use it as the deduplication key. |
| `sourceCompanyId` | The published BluePages company UUID, when the page exposes one. |
| `cityId` | The directory's own city identifier when the profile link carries it. |
| `city`, `cityContext` | Published city, and the city used to group the profile. |
| `region`, `regionCode` | Administrative region derived from the published city, with its ISO 3166-2:SA code (for example `SA-01` for Riyadh). This is derived, not a directory field. |
| `countryCode` | ISO 3166-1 alpha-2 code published by the source (`SA`). |

**Commercial registration (CR) and VAT numbers are not published on these public profiles**, so this Actor cannot supply them. If you need CR numbers, join this export to a commercial-registry source on the company name and city.

### Quick start

1. Leave the defaults to collect **10 profiles** in about twenty seconds.
2. Optionally add a city (Riyadh, Jeddah, Abha, Makkah or Madinah) and a name or activity filter.
3. To collect specific companies, choose **Profile URLs** and paste their BluePages company-profile links.
4. Click **Start** and export the dataset.

You can request up to **100 profiles per run**. Names and activity text are preserved as published; filters do not translate between Arabic and English.

### Follow only new or changed profiles

Turn on **Only new or changed profiles** to get a change feed:

- The first run for a filter set returns everything it examines and says `firstRun: true` in the run summary.
- Later runs return only profiles that are new, or whose published details changed, marked with `changeType` (`new` or `changed`) and `changedFields`.
- Unchanged profiles do not use the profile limit, so a scheduled daily run keeps moving through the directory instead of returning the same first rows.
- A saved list of already-delivered profiles keeps this state. Give it a name in **Saved state name** if you want to continue the same feed after changing the profile limits.

Set a city plus a daily schedule to build a directory coverage feed, or use **Profile URLs** for a watchlist of companies you care about.

### Example result

```json
{
  "recordId": "004299a4-588f-535c-a80a-8edf09740ace:ابها",
  "sourceCompanyId": "004299a4-588f-535c-a80a-8edf09740ace",
  "sourceUrl": "https://bluepages.com.sa/%D8%A3%D8%A8%D9%87%D8%A7/%D9%85%D8%BA%D8%A7%D8%B3%D9%84/%D9%85%D8%BA%D8%A7%D8%B3%D9%84-%D8%A7%D9%84%D8%B1%D9%8A%D8%A7%D8%AF%D8%A9-%D8%A7%D9%84%D9%85%D8%B1%D9%83%D8%B2%D9%8A%D8%A9-a1b1a7",
  "name": "مغاسل الريادة المركزية",
  "city": "أبها",
  "region": "منطقة عسير",
  "regionCode": "SA-14",
  "countryCode": "SA",
  "activity": "مغاسل",
  "address": "خميس مشيط",
  "postcode": null,
  "phones": ["0544490908"],
  "emails": ["cfo@equalhouses.com"],
  "websites": ["https://www.equalhouses.com/"],
  "whatsapp": null,
  "mapUrl": "https://maps.app.goo.gl/MxxadB7QvaPHxG9o7",
  "socialLinks": null,
  "language": "ar",
  "observedAt": "2026-11-10T05:30:00+00:00"
}
```

### Pricing

Pay **$0.0015 for each business profile delivered**, equivalent to **$1.50 per 1,000 profiles**. For example, the 10-profile quick start costs $0.015, 25 delivered profiles cost $0.0375 and 100 cost $0.15.

The price covers all available phone, email, website, WhatsApp and map values. A profile with missing optional contacts has the same price. Duplicate profile identities within a run are counted once, and a run that reaches its charge limit stops before delivering more rows.

### Coverage and data quality

Coverage is limited to the profiles BluePages makes available to this Actor. It does not include every BluePages listing or every Saudi company. Filters narrow this available set, so fewer results or no results do not establish that a business is absent from the wider directory.

Business details and contacts are **source-provided and unverified**. They can be incomplete or outdated; email deliverability, phone and WhatsApp reachability and company registration are not checked. The directory also publishes placeholder social links for some companies. Some published names or contacts may belong to sole traders. Review the original profile before relying on a record.

### FAQ

**Can I get commercial-registration or VAT numbers?** No. BluePages does not publish them on these profiles. The dataset gives you stable profile and city identifiers, name, activity, region and contacts; join to a registry source for CR data.

**Why do I get fewer rows than the limit?** Filters may match fewer profiles, the scan budget may be reached (reported as partial coverage), or the run's charge limit may stop delivery. The run summary states which.

**Why is a field empty?** The directory publishes contacts inconsistently. Empty means the profile does not publish that value at that moment, not that the Actor failed to read it.

**Does the Actor call phone numbers, message WhatsApp contacts or visit websites?** No. Every published contact and link is returned as data only.

**Is Arabic or English better?** Use the language the business publishes. Filters do not translate names or activities, so an Arabic filter will not match an English name.

**What happens when a profile page changes shape?** The run fails with a clear message rather than silently dropping the profile. You keep the rows delivered before the failure.

**Can I run it daily?** Yes. Use **Only new or changed profiles** with a saved state name, and expect only the rows that moved.

Independently maintained; not affiliated with or endorsed by BluePages.

# Actor input Schema

## `mode` (type: `string`):

Directory scan collects published BluePages profiles for a city and activity filter. Profile URLs collects only the company profiles you list.

## `profileUrls` (type: `array`):

Required when collecting listed profiles. Exact https bluepages.com.sa company profile URLs only; no category, search, account or API URLs. Known cities: Riyadh, Jeddah, Abha, Makkah and Madinah, in Arabic or the site's English address form.

## `keyword` (type: `string`):

Case- and diacritic-insensitive substring of the published business name. This narrows the profiles being collected; it is not the directory's full name search, and English text does not translate Arabic names.

## `city` (type: `string`):

City name used by the directory, for example الرياض, Riyadh, Jeddah or Abha. Recognises Riyadh, Jeddah, Abha, Makkah and Madinah. Leave empty for all of them.

## `activity` (type: `string`):

Substring of the published activity text, for example كابلات or مقاولون. Matching is on the source's own wording, so Arabic and English activity names are not translated.

## `maxItems` (type: `integer`):

Hard limit on output profiles; 10 in the quick start, 25 by default, 100 at most. The run's charge limit can reduce it.

## `maxProfiles` (type: `integer`):

Hard budget on profiles examined per run, including names that do not match the keyword. Reaching it is reported as partial coverage.

## `maxSeconds` (type: `integer`):

Includes pauses, redirects and page reads. If you raise it above 300, also raise the run timeout in the Apify Console.

## `onlyNewSinceLastRun` (type: `boolean`):

Return only profiles not delivered before, or whose published details changed. Unchanged profiles do not use the output limit, so a scheduled daily run continues through the directory instead of returning the same first profiles. The first run with a filter set returns everything it examines.

## `stateKey` (type: `string`):

Name of the saved list of already-delivered profiles for this filter set. Leave empty to derive it from the scan settings. Set the same name to continue a feed after changing maxItems or maxProfiles.

## Actor input object example

```json
{
  "mode": "sitemap",
  "profileUrls": [],
  "keyword": "",
  "city": "",
  "activity": "",
  "maxItems": 10,
  "maxProfiles": 100,
  "maxSeconds": 180,
  "onlyNewSinceLastRun": false,
  "stateKey": ""
}
```

# Actor output Schema

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

No description

## `coverage` (type: `string`):

No description

# 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 = {
    "mode": "sitemap",
    "maxItems": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("automatic/bluepages-saudi-directory").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 = {
    "mode": "sitemap",
    "maxItems": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("automatic/bluepages-saudi-directory").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 '{
  "mode": "sitemap",
  "maxItems": 10
}' |
apify call automatic/bluepages-saudi-directory --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automatic/bluepages-saudi-directory"
        }
    }
}
```

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/L42p9b2mQ1qN5BEkc/builds/AvPWYj6CONzZIWL8T/openapi.json
