# UK Dentist & Dental Professional Register Scraper (`crawlerbros/uk-dentist-register-scraper`) Actor

Verify UK dental professionals against the General Dental Council's official register (olr.gdc-uk.org). Search by name/town/register type or look up exact GDC registration numbers to get registration status, registrant type, qualifications, specialties and DCP titles.

- **URL**: https://apify.com/crawlerbros/uk-dentist-register-scraper.md
- **Developed by:** [Crawler Bros](https://apify.com/crawlerbros) (community)
- **Categories:** Automation, Lead generation, Other
- **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

## UK Dentist & Dental Professional Register Scraper

Verify UK dental professionals against the **General Dental Council (GDC)** official public register at `olr.gdc-uk.org`. Search by name, town, or register type — or look up an exact GDC registration number — to confirm whether a dentist, dental hygienist, dental nurse, dental therapist, dental technician, clinical dental technician, or orthodontic therapist is currently registered and legally able to practise in the UK. No login, no cookies, no proxy required.

### What this actor does

- **Two lookup modes:** free-form register search, or exact registration-number lookup
- **Search by any combination of:** forename, surname, town, register type
- **Phonetic ("sounds like") matching** on forename and surname — catches spelling variants (e.g. "Steven" / "Stephen", "Smith" / "Smyth")
- **Filter by DCP title** (Dental Nurse, Dental Hygienist, Dental Therapist, Dental Technician, Clinical Dental Technician, Orthodontic Therapist)
- **Filter by specialist-list specialty** (Orthodontics, Endodontics, Oral Surgery, Paediatric Dentistry, and 9 more)
- **Include/exclude erased registrants** — see historical/removed entries when needed
- **Handles dual-registered professionals** — some individuals hold more than one registration type (e.g. qualified as a Dental Nurse, later became a Dentist); every registration they hold is captured, not just the primary one
- **Full result-set pagination** — follows the register's own paging so large matches (up to its 250-record cap) are returned in full, not just the first page
- **Empty fields are never included** — only real, extracted data is emitted

### Output per registrant

- `registrationNumber` — unique GDC registration number
- `fullName`, `firstName`, `surname`
- `status` — e.g. `Registered`, `Suspended`, `Erased`
- `registrantType` — e.g. `Dentist`, `Dental Care Professional`, `Temporary Registrant Dentist`
- `dcpTitles[]` — for Dental Care Professionals: `title`, `firstRegisteredOn`, `currentPeriodFrom`, `currentPeriodUntil` per title held
- `specialties[]` — for specialist dentists: `specialty`, `firstRegisteredOn`, `currentPeriodFrom`, `currentPeriodUntil` per specialty held
- `firstRegisteredOn` — date first joined the register (ISO `YYYY-MM-DD`)
- `currentPeriodFrom` / `currentPeriodUntil` — current registration period validity dates
- `qualifications[]` — qualifications as entered on the register
- `registrations[]` — present only for professionals holding more than one registration type; each entry is a full sub-record (`registrantType`, `status`, dates, `qualifications`, `dcpTitles`/`specialties`) for that additional registration
- `sourceUrl` — direct link to the official GDC register entry
- `recordType`, `scrapedAt`

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | select | `search` | `search` (by name/town/register type) or `byRegistrationNumbers` (exact lookup) |
| `registerType` | select | `all` | `all` / `dentists` / `specialistLists` / `dcp` / `temporaryRegistrantDentist` / `visitingPractitionerDentist` / `visitingPractitionerDcp` |
| `firstName` | string | – | Forename to search for (mode=search) |
| `surname` | string | – | Surname to search for (mode=search) |
| `town` | string | – | Practice/registered town (mode=search) |
| `firstNameSoundsLike` | boolean | `false` | Phonetic match on forename |
| `surnameSoundsLike` | boolean | `false` | Phonetic match on surname |
| `includeErasedRegistrants` | boolean | `false` | Include erased/removed registrants |
| `dcpTitle` | select | – (any) | Restrict to a specific DCP title |
| `specialty` | select | – (any) | Restrict to a specific specialist-list specialty |
| `sortBy` | select | `surname` | `surname` / `firstName` / `registrationNumber` / `status` / `registrantType` |
| `sortAscending` | boolean | `true` | Sort direction |
| `registrationNumbers` | array | `["60065"]` | Exact GDC registration numbers (mode=byRegistrationNumbers) |
| `maxItems` | integer | `50` | Hard cap on emitted records (1–250 — the register itself caps any single search at 250 matches) |

#### Example: verify a named dentist

```json
{
  "mode": "search",
  "firstName": "John",
  "surname": "Smith",
  "maxItems": 25
}
```

#### Example: find all registered orthodontists in a surname

```json
{
  "mode": "search",
  "registerType": "dentists",
  "surname": "Khan",
  "specialty": "Orthodontics"
}
```

#### Example: find dental nurses by town

```json
{
  "mode": "search",
  "registerType": "dcp",
  "dcpTitle": "Dental Nurse",
  "town": "Manchester",
  "maxItems": 100
}
```

#### Example: exact registration-number lookup

```json
{
  "mode": "byRegistrationNumbers",
  "registrationNumbers": ["60065", "77692", "303212"]
}
```

### Use cases

- **Employers & recruiters** — verify a candidate dentist/DCP holds a current, valid GDC registration before hiring
- **Patients** — confirm a dental professional treating them is legitimately registered
- **Dental practices** — bulk-verify staff registration status and renewal dates ahead of CQC inspections
- **Insurance & compliance** — cross-check registration status and specialty claims
- **Recruitment agencies** — build verified candidate shortlists filtered by specialty or DCP title
- **Researchers** — analyse the composition of the UK dental workforce by region, title, or specialty

### FAQ

**What's the GDC register?** The General Dental Council is the UK statutory regulator for dentistry. Anyone practising as a dentist or dental care professional (dental nurse, hygienist, therapist, technician, clinical dental technician, orthodontic therapist) in the UK must be registered with the GDC. The register is public and updated daily.

**Why did my search return no records?** Either no registrant matches your filters, or your search matched more than 250 records and the register asks you to narrow it (add a forename, town, or specialty). The actor reports which case applies via the run's status message.

**What does "sounds like" mean?** It's a phonetic match, so spelling variants of a name (e.g. "Catherine"/"Katherine", "Smith"/"Smyth") are matched even if you don't know the exact spelling used on the register.

**What is a dual-registered professional?** Some people hold more than one registration under the same GDC number — for example, someone who first qualified and registered as a Dental Nurse and later trained and registered as a Dentist. For these records, the primary registration is shown at the top level and every registration they hold appears in the `registrations` field.

**Does this include specialist dentists?** Yes — `registerType: specialistLists` combined with the `specialty` filter surfaces dentists holding one of the 13 GDC specialist-list specialties (Orthodontics, Endodontics, Oral Surgery, etc.), each with their own registration dates for that specialty.

**Is erased/removed data included?** Only when `includeErasedRegistrants` is set to `true`. By default, only current registrants are returned.

**How fresh is the data?** The GDC register itself states it is updated daily, and every run of this actor reads the register live.

**Do I need a proxy or login?** No — the register is a public government-regulator service with no rate-limiting or anti-bot measures encountered in normal use, so no proxy or cookies are required.

# Actor input Schema

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

What to fetch.

## `registerType` (type: `string`):

Which register to search. 'Specialist Lists' searches the same Dentists register but is intended to be combined with the Specialty filter below.

## `firstName` (type: `string`):

Forename to search for. Matches anywhere in the registrant's forenames.

## `surname` (type: `string`):

Surname to search for.

## `town` (type: `string`):

Practice/registered town to search for. Can be combined with forename/surname or used alone.

## `firstNameSoundsLike` (type: `boolean`):

Phonetic match on forename (catches spelling variants, e.g. 'Steven'/'Stephen').

## `surnameSoundsLike` (type: `boolean`):

Phonetic match on surname (catches spelling variants, e.g. 'Smith'/'Smyth').

## `includeErasedRegistrants` (type: `boolean`):

Also include registrants who have been erased/removed from the register.

## `dcpTitle` (type: `string`):

Restrict to a specific Dental Care Professional title. Works with any Register selection (results are narrowed to registrants holding this title).

## `specialty` (type: `string`):

Restrict to dentists holding a specific GDC specialist-list specialty.

## `sortBy` (type: `string`):

Field to sort results by.

## `sortAscending` (type: `boolean`):

Sort A-Z / low-high. Turn off for Z-A / high-low.

## `registrationNumbers` (type: `array`):

Exact GDC registration numbers to look up, e.g. `60065`.

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

Hard cap on emitted records. The GDC register itself refuses any single search that matches more than 250 registrants ('Too Many Results') — narrow your Forename/Surname/Town/filters if you hit that.

## Actor input object example

```json
{
  "mode": "search",
  "registerType": "all",
  "firstName": "John",
  "surname": "Smith",
  "firstNameSoundsLike": false,
  "surnameSoundsLike": false,
  "includeErasedRegistrants": false,
  "dcpTitle": "",
  "specialty": "",
  "sortBy": "surname",
  "sortAscending": true,
  "registrationNumbers": [
    "60065"
  ],
  "maxItems": 50
}
```

# Actor output Schema

## `registrants` (type: `string`):

Dataset containing all scraped GDC registrant 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",
    "registerType": "all",
    "firstName": "John",
    "surname": "Smith",
    "firstNameSoundsLike": false,
    "surnameSoundsLike": false,
    "includeErasedRegistrants": false,
    "dcpTitle": "",
    "specialty": "",
    "sortBy": "surname",
    "sortAscending": true,
    "registrationNumbers": [
        "60065"
    ],
    "maxItems": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawlerbros/uk-dentist-register-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",
    "registerType": "all",
    "firstName": "John",
    "surname": "Smith",
    "firstNameSoundsLike": False,
    "surnameSoundsLike": False,
    "includeErasedRegistrants": False,
    "dcpTitle": "",
    "specialty": "",
    "sortBy": "surname",
    "sortAscending": True,
    "registrationNumbers": ["60065"],
    "maxItems": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("crawlerbros/uk-dentist-register-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",
  "registerType": "all",
  "firstName": "John",
  "surname": "Smith",
  "firstNameSoundsLike": false,
  "surnameSoundsLike": false,
  "includeErasedRegistrants": false,
  "dcpTitle": "",
  "specialty": "",
  "sortBy": "surname",
  "sortAscending": true,
  "registrationNumbers": [
    "60065"
  ],
  "maxItems": 50
}' |
apify call crawlerbros/uk-dentist-register-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,crawlerbros/uk-dentist-register-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/o9ZazF0aDsE9C0dEp/builds/sbuDPejVLRg0whazG/openapi.json
