# Pennsylvania Professional License Search - PALS Leads (`scrapers_lat/pennsylvania-pals-licenses-scraper`) Actor

Search Pennsylvania's PALS licence register across 31 state boards: nurses, doctors, pharmacists, realtors, engineers, accountants and more. Every record carries the licensee's email and phone, address, licence dates, disciplinary history and their other PA licences.

- **URL**: https://apify.com/scrapers\_lat/pennsylvania-pals-licenses-scraper.md
- **Developed by:** [Scrapers Lat](https://apify.com/scrapers_lat) (community)
- **Categories:** Lead generation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $20.00 / 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.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#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

## Pennsylvania Professional License Search — PALS Leads

Every professional licence Pennsylvania issues, in one dataset — **with the licensee's email address and phone number attached**.

The Pennsylvania Licensing System (PALS) is the public register run by the Department of State's Bureau of Professional and Occupational Affairs. It covers **31 state licensing boards**: nurses, physicians, pharmacists, dentists, realtors and brokers, appraisers, engineers and surveyors, accountants, architects, psychologists, social workers, physical and occupational therapists, veterinarians, funeral directors, cosmetologists, barbers, auctioneers, crane operators, vehicle dealers and more — plus the licensed **establishments**: pharmacies, salons, funeral homes, dealerships, architecture and engineering firms.

Search it by name, by firm, by licence number, or sweep an entire board or county in bulk.

***

### What you get for every licence

**Identity & licence**

- Full name (first, middle, last, suffix) or registered establishment name, and any DBA / fictitious name
- Licence number, licence type and recorded speciality
- Issuing board (full name) and profession group
- Status — Active, Expired, Inactive, Suspension, Null and Void, Deceased, Out of Business — plus a clean `isActive` flag and the date the status took effect

**Contact details**

- **Email address of record**
- **Phone number**, normalised to `+1XXXXXXXXXX`
- Street address (for establishments), city, **Pennsylvania county**, state, ZIP and country
- A single-line `fullAddress`, plus flags for whether an email, a phone and a Pennsylvania address are on file

**Dates you can act on**

- Issue date, expiry date, last renewal date, next scheduled renewal
- `daysToExpiration` and `isExpiringWithin90Days` — ready-made renewal and win-back segments
- How the licence was obtained (application, examination, reciprocity)

**Compliance & relationships**

- Every board **disciplinary action** on the licence, with its complaint number, the action taken and the order document reference
- **Every other Pennsylvania licence the same person or firm holds**, across all 31 boards, with each one's number, type, status, expiry and last renewal — so a nurse who is also a dietitian, or a broker who is also an appraiser, shows up as one connected profile
- Sponsors, supervisors and prerequisite licence holders linked to the licence, with their own name and licence number
- Recorded status history

***

### Four ways to search

| Mode | Use it for |
| --- | --- |
| **By licensee name** | Verify or enrich a person. Last and first name match from the start of the name, so `SCHW` finds SCHWAB, SCHWARTZ, SCHWENK. |
| **By establishment / firm name** | Licensed businesses: `RITE AID`, `UPMC`, `KELLER WILLIAMS`. |
| **By licence number(s)** | Bulk verification of licences you already hold. Individuals and establishments both resolved. |
| **Bulk sweep** | Whole boards, whole counties, whole professions. |

### Filters that narrow the list to the leads you actually want

- **Licensing boards** — pick any of the 31, or take all of them
- **Counties** — any of Pennsylvania's 67, by name
- **City** and **ZIP code**
- **Licence status** — active only, or everything that is *not* active (expired, lapsed, suspended: the renewal and win-back audience)
- **Licence type contains** — `Registered Nurse`, `Broker`, `Practical`, `Firm`… each board issues dozens of types
- **Only licensees with an email** / **with a phone** — go straight to a contactable list
- **Only licensees with a disciplinary action** — compliance and due-diligence screening
- **Expiring within N days** — set 90 for a renewal-season campaign

***

### Past the register's own 500-result limit

The public site will never show you more than **500 results** for any one search, and it gives you no way to page beyond that. That ceiling is the reason bulk Pennsylvania licence data is hard to get.

This actor detects when a search has hit the ceiling and automatically splits it into narrower name ranges, repeating until every slice fits under the limit — so a bulk sweep keeps going where the website stops. A single run routinely returns many times what the site itself will display. Depth is yours to control: raise **Name split depth** for the very large boards (Nursing, Medicine), lower it for a quick shallow pass.

***

### Good for

- **Recruiting and staffing** — contactable lists of RNs, LPNs, therapists, pharmacists and technicians by county
- **Sales into licensed professionals** — software, insurance, CE courses, practice services, equipment
- **Renewal and CE marketing** — everyone whose licence expires in the next 90 days
- **Compliance, KYC and vendor screening** — licence status, expiry and disciplinary history on demand
- **Market and competitive analysis** — counts and density by board, licence type, county and city
- **CRM enrichment** — attach a verified licence number, status and expiry to records you already have

### Output

JSON, CSV, Excel, XML or HTML from the Apify dataset, plus three ready-made views: **Licences** (the overview), **Contact list** (name, email, phone, address) and **Disciplinary & renewals**. Available through the Apify API and integrations.

### Notes

- Free Apify plans are capped at 10 results per run.
- Contact details are published by the register only where the licensee has one on file; coverage is high on some boards and partial on others, and the `hasEmail` / `hasPhone` flags let you filter to what is actually there.
- Street-level addresses are published for establishments; individual licensees are published at city, county and ZIP level, which is the register's own policy.
- Data reflects the Pennsylvania public register at the moment of the run.

# Actor input Schema

## `searchMode` (type: `string`):

By name: look up individual licensees by last/first name. Establishments: licensed firms, pharmacies, salons, funeral homes, dealerships. By licence number: verify licences you already hold. Bulk sweep: walk whole boards and counties past the register's own 500-result ceiling.

## `lastName` (type: `string`):

Licensee surname. Matches from the start of the name, so "SCHW" returns SCHWAB, SCHWARTZ, SCHWENK. Leave blank in bulk sweep mode.

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

Optional given name, also matched from the start of the name.

## `facilityName` (type: `string`):

Licensed business name, matched from the start: "RITE AID", "UPMC", "KELLER WILLIAMS". Used when Search mode is "By establishment / firm name".

## `licenseNumbers` (type: `array`):

Exact PA licence numbers, e.g. RN123456L or MD012345. Used when Search mode is "By licence number(s)".

## `boards` (type: `array`):

Restrict to specific state boards. Leave empty for all 31. Nursing 43, Medicine 37, Osteopathic Medicine 36, Pharmacy 8, Dentistry 13, Real Estate 27, Real Estate Appraisers 5, Engineers/Surveyors/Geologists 28, Accountancy 3, Architects 1, Landscape Architects 7, Social Work & Counseling 29, Psychology 30, Physical Therapy 42, Occupational Therapy 9, Speech-Language 40, Optometry 26, Podiatry 33, Chiropractic 2, Veterinary 23, Nursing Home Administration 24, Radiology Personnel 39, Massage Therapy 12, Cosmetology 20, Barbers 15, Funeral Directors 17, Auctioneers 31, Crane Operators 41, Vehicle Dealers 38, Navigation Commission 6, Health Division Volunteers 10.

## `counties` (type: `array`):

Pennsylvania counties to restrict to, e.g. Philadelphia, Allegheny, Montgomery. Exact county names only. Leave empty for statewide (and out-of-state licensees).

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

City of the licensee's address of record, matched from the start of the name.

## `zipCode` (type: `string`):

Exact 5-digit ZIP of the address of record.

## `licenseStatus` (type: `string`):

Active keeps only licences currently in good standing. Inactive keeps expired, suspended, inactive, null-and-void and deceased records - useful for renewal and win-back campaigns.

## `licenseTypeContains` (type: `string`):

Keep only licence types containing this text, e.g. "Registered Nurse", "Broker", "Practical", "Firm". Boards issue dozens of licence types each.

## `onlyWithEmail` (type: `boolean`):

Drop records with no email address on file.

## `onlyWithPhone` (type: `boolean`):

Drop records with no phone number on file.

## `onlyWithDisciplinaryAction` (type: `boolean`):

Keep only licences that carry at least one board disciplinary action or complaint. Compliance and due-diligence screening.

## `expiringWithinDays` (type: `integer`):

Keep only licences that expire within this many days from today. Set 90 for a renewal-season list. Leave empty to ignore expiry.

## `sweepEntities` (type: `string`):

What the bulk sweep walks: individual licensees, licensed establishments, or both.

## `maxPrefixDepth` (type: `integer`):

The register never returns more than 500 rows for one query. When a query hits that ceiling the actor splits it by name prefix and retries. Depth 4 (default) resolves almost every board; raise it for very large boards such as Nursing, lower it for faster shallow runs.

## `includeDetails` (type: `boolean`):

Fetch each licence's detail record: issue, expiry and last-renewal dates, disciplinary actions with complaint numbers, every other Pennsylvania licence the person holds, sponsor relationships and the establishment's street address. Turn off for a faster, thinner run.

## `maxRecords` (type: `integer`):

Stop after this many licence records. Free Apify plans are capped at 10 per run.

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

Parallel requests to the register. 6 is a good balance; lower it if you see timeouts.

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

Optional. The register answers datacenter IPs directly, so a proxy is normally unnecessary.

## Actor input object example

```json
{
  "searchMode": "name",
  "lastName": "SMITH",
  "licenseNumbers": [],
  "boards": [],
  "counties": [],
  "licenseStatus": "any",
  "onlyWithEmail": false,
  "onlyWithPhone": false,
  "onlyWithDisciplinaryAction": false,
  "sweepEntities": "individuals",
  "maxPrefixDepth": 4,
  "includeDetails": true,
  "maxRecords": 50,
  "maxConcurrency": 6,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `results` (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 = {
    "lastName": "SMITH"
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapers_lat/pennsylvania-pals-licenses-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 = { "lastName": "SMITH" }

# Run the Actor and wait for it to finish
run = client.actor("scrapers_lat/pennsylvania-pals-licenses-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 '{
  "lastName": "SMITH"
}' |
apify call scrapers_lat/pennsylvania-pals-licenses-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapers_lat/pennsylvania-pals-licenses-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/4aCE7VEJpYDglJMgV/builds/qDyg1FVbY8AvN7thB/openapi.json
