# RICS Firms Scraper (`crawlerbros/rics-firms-scraper`) Actor

Scrape RICS' official Find a Surveyor directory (ricsfirms.com) - 40,000+ chartered surveying firms worldwide. Search by location, firm name, keyword, service, topic, or country, or fetch specific firms by office ID/URL.

- **URL**: https://apify.com/crawlerbros/rics-firms-scraper.md
- **Developed by:** [Crawler Bros](https://apify.com/crawlerbros) (community)
- **Categories:** Real estate, Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## RICS Firms Scraper

Scrape RICS' official **Find a Surveyor** directory (ricsfirms.com) — the Royal Institution of Chartered Surveyors' worldwide listing of 40,000+ chartered surveying firms. Search by town/city/postcode, firm name, keyword, surveying service, consumer topic, or country — or fetch specific firms by office ID/URL for a full profile. HTTP-only, no auth, no proxy.

### What this actor does

- **Two modes:** `search` (directory search with filters) and `byOfficeIds` (direct lookup by office ID / profile URL)
- **Filters (combinable):** location, firm name, keyword, surveying service (131 options), consumer topic (52 options), country (102 options), RICS-regulated only, residential-only, commercial-only, free-advice-only
- **Full firm profiles:** optionally enrich each result with services offered, surveyor type, business type, partners/directors, and RICS personnel
- **Global coverage:** the UK directory by default, or any of the 100+ countries RICS firms operate in
- **Empty fields are omitted** — every record only contains data the firm actually published

### Output per firm

- `officeId`, `ricsFirmNumber` — RICS' internal office/firm identifiers
- `firmName`, `ricsRegulated`
- `aboutUs` — firm's own description
- `address`, `town`, `city` (search mode; broader locality than `town`, e.g. "London" vs. "London, NW4"), `region`, `postalCode`, `country`, `countryCode`
- `latitude`, `longitude` — geocoordinates (profile lookups)
- `phone`, `email`, `websiteUrl`
- `logoUrl` — firm logo (when published)
- `servesResidential`, `servesCommercial`, `offersFreeAdvice`, `basedInSearchArea` (search mode)
- `listingPackage` — RICS directory listing tier (search mode)
- `surveyorTypes[]` — e.g. "Chartered Building Surveyor"
- `servicesOffered[]` — e.g. "Party walls", "Valuation", "Building surveying"
- `businessType` — e.g. "Private Practice"
- `partnersAndDirectors[]`, `ricsPersonnel[]`
- `regulationStatusText`
- `sourceUrl` — the firm's live profile page on ricsfirms.com
- `recordType: "surveyorFirm"`, `scrapedAt`

Note: the "Services & Staff" panel (`servicesOffered`, `surveyorTypes`, `businessType`, `partnersAndDirectors`, `ricsPersonnel`) is only published by RICS for firms with an enhanced directory listing. Basic listings still return full contact details (name, address, phone, email, website) but omit these fields — this reflects what the firm actually published, not a scraping gap.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | string | `search` | `search` / `byOfficeIds` |
| `locationQuery` | string | `London` | Town, city, or postcode (mode=search) |
| `firmNameQuery` | string | – | Filter by firm name (mode=search) |
| `keyword` | string | – | Free-text keyword against "about us" and services (mode=search) |
| `serviceName` | select | – | One of 131 surveying services (mode=search) |
| `topicName` | select | – | One of 52 consumer topics, e.g. Buying, Party Walls (mode=search) |
| `countryCode` | select | – | One of 102 countries; blank = UK default (mode=search) |
| `includeFullProfile` | bool | `true` | Fetch each firm's profile page for the full "Services & Staff" panel (mode=search) |
| `ricsRegulatedOnly` | bool | `false` | Only keep RICS-regulated firms (mode=search) |
| `residentialOnly` | bool | `false` | Only keep firms serving residential clients (mode=search) |
| `commercialOnly` | bool | `false` | Only keep firms serving commercial clients (mode=search) |
| `freeAdviceOnly` | bool | `false` | Only keep firms offering free initial advice (mode=search) |
| `officeIds` | array | – | Office numbers or profile URLs (mode=byOfficeIds) |
| `maxItems` | int | `25` | Hard cap (1–1000) |

#### Example: firms near a UK town offering a specific service

```json
{
  "mode": "search",
  "locationQuery": "Manchester",
  "serviceName": "102",
  "maxItems": 50
}
```

#### Example: browse a whole country

```json
{
  "mode": "search",
  "countryCode": "AU",
  "maxItems": 100,
  "includeFullProfile": false
}
```

#### Example: lookup specific firms by office ID

```json
{
  "mode": "byOfficeIds",
  "officeIds": ["233706", "https://www.ricsfirms.com/office/266306/Crest-Surveyors-Ltd"]
}
```

### Use cases

- **Lead generation** — build a list of chartered surveyors in a target region for partnership or referral outreach
- **Market research** — analyze surveying-firm density and service mix by town, region, or country
- **Directory aggregation** — feed RICS-verified firms into a real-estate or conveyancing marketplace
- **Compliance checks** — confirm a firm's RICS-regulated status before engaging them
- **Competitive analysis** — compare service offerings and business types across firms in a market

### FAQ

**What is RICS Find a Surveyor?** The Royal Institution of Chartered Surveyors' official public directory of member firms, covering residential and commercial surveying, valuation, party walls, and more. See [ricsfirms.com](https://www.ricsfirms.com).

**Is authentication required?** No. The directory and every firm profile page are public.

**What's the difference between `search` and `byOfficeIds`?** `search` browses the directory by location/name/keyword/service/topic/country. `byOfficeIds` fetches one or more specific firms directly when you already know their office number or profile URL (e.g. from a previous search run).

**Why do some firms have fewer fields than others?** RICS' directory has tiered listings — enhanced (paid) listings publish a full "Services & Staff" panel; basic listings only publish contact details. The actor never fabricates missing data.

**Can I search outside the UK?** Yes — set `countryCode` to any of the 102 supported countries, optionally combined with `locationQuery` for a specific city within that country.

**What does `basedInSearchArea` mean?** `true` if the firm's office is physically located in/near the searched location; `false` if it was matched by name/service but is based elsewhere. Only present for location-based searches.

**How fresh is the data?** Real-time — every run queries RICS' live directory and profile pages directly.

# Actor input Schema

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

What to fetch.

## `locationQuery` (type: `string`):

UK town/city/postcode or an international city name to search near (mode=search). Leave blank to browse the whole directory, optionally combined with Country.

## `firmNameQuery` (type: `string`):

Filter to firms whose name matches this text (mode=search).

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

Free-text keyword matched against each firm's "about us" description and services (mode=search).

## `serviceName` (type: `string`):

Restrict results to firms offering this specific surveying service (mode=search).

## `topicName` (type: `string`):

Restrict results to firms relevant to this consumer topic, e.g. Buying, Party Walls, Extensions (mode=search).

## `countryCode` (type: `string`):

Restrict results to a specific country. Leave blank for the UK default directory, or combine with Location for a place inside that country (mode=search).

## `includeFullProfile` (type: `boolean`):

Fetch each firm's profile page for services offered, surveyor type, business type, partners/directors and RICS personnel (mode=search). Adds one extra request per firm; disable for faster/lighter runs.

## `ricsRegulatedOnly` (type: `boolean`):

Only keep firms flagged as RICS-regulated (mode=search).

## `residentialOnly` (type: `boolean`):

Only keep firms that target residential-property clients (mode=search).

## `commercialOnly` (type: `boolean`):

Only keep firms that target commercial-property clients (mode=search).

## `freeAdviceOnly` (type: `boolean`):

Only keep firms that offer free initial advice (mode=search).

## `officeIds` (type: `array`):

RICS office numbers (e.g. `233706`) or full profile URLs (e.g. `https://www.ricsfirms.com/office/233706/Peter-Barry-Surveyors`).

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

Hard cap on the number of firm records emitted.

## Actor input object example

```json
{
  "mode": "search",
  "locationQuery": "London",
  "serviceName": "",
  "topicName": "",
  "countryCode": "",
  "includeFullProfile": true,
  "ricsRegulatedOnly": false,
  "residentialOnly": false,
  "commercialOnly": false,
  "freeAdviceOnly": false,
  "officeIds": [
    "233706"
  ],
  "maxItems": 25
}
```

# Actor output Schema

## `firms` (type: `string`):

Dataset containing all scraped surveying firm records.

# 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": "search",
    "locationQuery": "London",
    "serviceName": "",
    "topicName": "",
    "countryCode": "",
    "includeFullProfile": true,
    "ricsRegulatedOnly": false,
    "residentialOnly": false,
    "commercialOnly": false,
    "freeAdviceOnly": false,
    "officeIds": [
        "233706"
    ],
    "maxItems": 25
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawlerbros/rics-firms-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 = {
    "mode": "search",
    "locationQuery": "London",
    "serviceName": "",
    "topicName": "",
    "countryCode": "",
    "includeFullProfile": True,
    "ricsRegulatedOnly": False,
    "residentialOnly": False,
    "commercialOnly": False,
    "freeAdviceOnly": False,
    "officeIds": ["233706"],
    "maxItems": 25,
}

# Run the Actor and wait for it to finish
run = client.actor("crawlerbros/rics-firms-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 '{
  "mode": "search",
  "locationQuery": "London",
  "serviceName": "",
  "topicName": "",
  "countryCode": "",
  "includeFullProfile": true,
  "ricsRegulatedOnly": false,
  "residentialOnly": false,
  "commercialOnly": false,
  "freeAdviceOnly": false,
  "officeIds": [
    "233706"
  ],
  "maxItems": 25
}' |
apify call crawlerbros/rics-firms-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,crawlerbros/rics-firms-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/tG9F4dowIsJSKD990/builds/AUh049JpGpXOelIPt/openapi.json
