# Colorado Professional License Scraper (`haketa/colorado-professional-license-scraper`) Actor

Colorado DORA professional license scraper & API: search licenses across boards and export license number, type, status, name, profession, address and issue/expiry dates. Professional license verification, compliance and lead generation — fast, no login.

- **URL**: https://apify.com/haketa/colorado-professional-license-scraper.md
- **Developed by:** [Haketa](https://apify.com/haketa) (community)
- **Categories:** Developer tools, Automation, Real estate
- **Stats:** 3 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.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.
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

## Colorado Professional License Scraper — DORA Data Extractor for Nurses, Doctors, Contractors, Engineers & 50+ Regulated Occupations

> **The most complete Colorado Department of Regulatory Agencies (DORA) license extraction tool on Apify.** Pull nightly-refreshed professional and occupational license records for every electrician, plumber, engineer, nurse, physician, real estate broker, cosmetologist, dentist, accountant, architect, and dozens more regulated trades in Colorado — structured, filtered, and ready for compliance, sales, recruiting, credentialing, and analytics workflows. Backed by the official **data.colorado.gov** Socrata SODA API.

[![Apify Actor](https://img.shields.io/badge/Apify-Actor-blue)](https://apify.com/haketa/colorado-professional-license-scraper)
[![Nightly Updated](https://img.shields.io/badge/Data-Nightly%20Refresh-orange)]()
[![Engine](https://img.shields.io/badge/Engine-Socrata%20SODA%20API-green)]()
[![No Auth](https://img.shields.io/badge/Authentication-None%20Required-success)]()
[![Coverage](https://img.shields.io/badge/Coverage-50%2B%20Professions-purple)]()
[![Pay Per Event](https://img.shields.io/badge/Pricing-Pay%20Per%20Event-yellow)]()
[![State](https://img.shields.io/badge/State-Colorado-red)]()
[![No Proxy](https://img.shields.io/badge/Proxy-Not%20Required-lightgrey)]()

***

### What This Actor Does

The **Colorado Professional License Scraper** is a production-ready Apify Actor that extracts the **complete public licensing dataset** from the **Colorado Department of Regulatory Agencies (DORA)** via the official **Colorado Information Marketplace (CIM)** open data portal at `data.colorado.gov`. DORA is the umbrella state agency that licenses, registers, and regulates more than fifty professional, occupational, and trade categories across Colorado — from individual electricians and registered nurses to engineering firms and real estate brokerages.

In a single run the actor returns clean, structured JSON for every license matching your filters — license number, professional name or entity name, type prefix, sub-category, specialty, status (Active/Expired/Suspended/Revoked/Surrendered/Inactive), first-issue date, last-renewal date, expiration date, city, state, ZIP, and a direct verification URL back to DORA. Records originate from the **`7s5z-vewr`** Socrata dataset — the same source that powers the public DORA license-lookup widget.

Out of the box the actor covers the major contractor and design-professional license families:

- **Electrical Contractors (EC)** — licensed electrical contracting firms
- **Plumbing Contractors (PC)** — licensed plumbing contracting firms
- **Mechanical / HVAC (ME)** — mechanical and HVAC contractors
- **Journeyman Wireman (JW)** — licensed electrical journeymen
- **Master Plumber (MP)** — master-level plumbing tradespeople
- **Journeyman Plumber (JP)** — journeyman plumbing tradespeople
- **Professional Engineer (PE)** — registered professional engineers
- **Architect (ARC)** — licensed architects
- **Real Estate Brokers (REB)** — licensed real estate brokers and associates
- **Cosmetology (COS)** — cosmetologists, estheticians, nail techs, barbers
- **Nursing (NA)** — registered nurses, LPNs, advanced practice nurses
- **Physicians (PHY)** — Colorado-licensed MDs and DOs
- And every other DORA license type prefix exposed by the CIM dataset

Each record includes a `verifyUrl` field pointing back to the live DORA detail page — perfect for compliance audit trails, credentialing packets, and dispute documentation.

#### Why scrape DORA yourself when this exists?

DORA publishes the data through the Socrata SODA API. In theory you can hit the endpoint directly. In practice every team that tries this hits the same wall of frustrations:

- Socrata field names are **all lowercase, abbreviated, and inconsistent** with the DORA labels (`licensefirstissuedate`, `licensestatusdescription`, `mailzipcode`, `linktoverifylicense`) — nothing matches your spreadsheet headers
- The dataset mixes **person records** (firstname/lastname/middlename/suffix) and **entity records** (entityname) in the same rows — one or the other is always null and your downstream joins break
- License **type prefixes** (`EC`, `PC`, `ME`, `JW`, `PE`, `ARC`, `REB`, `COS`, `NA`, `PHY` …) are undocumented two-to-four-letter codes — you'd have to reverse-engineer the taxonomy from the DORA portal
- The `linktoverifylicense` field is sometimes a **bare string**, sometimes a **`{url: "..."}` object**, sometimes `null` — naive parsers crash
- Date fields arrive as **ISO timestamps with `T00:00:00.000`** padding — you have to strip the time component before they land cleanly in BI tools
- Socrata's `$where` clause uses **SoQL**, not SQL — quoting rules, `upper()`, `IN(...)`, and date literals all have their own gotchas
- The CIM portal has **no native deduplication** — re-issued license numbers and capitalization variations require client-side dedup logic
- Pagination is **offset-based with no streaming cursor** — you have to track totals, batch politely, and respect Socrata's quota
- No incremental sync API — to build a delta pipeline you need to fetch and diff every run
- DIY rebuild: 6–12 hours of Node/Python plumbing nobody on your team wants to maintain

This actor solves all of that. It calls the Socrata API directly (no browser, no proxy, no login), normalizes every field name, splits person vs entity rows cleanly, parses dates, deduplicates by license number, and emits a flat JSON shape that drops straight into Postgres, BigQuery, Snowflake, Google Sheets, Airtable, HubSpot, Salesforce, or any CRM.

***

### Quick Start

#### One-Click Run

1. Open the **[Colorado Professional License Scraper](https://apify.com/haketa/colorado-professional-license-scraper)** on Apify Store
2. Click **Try for free** — the default input pulls active and expired licenses across the eight major contractor and design-professional categories (EC, PC, ME, JW, MP, JP, PE, ARC)
3. Hit **Start** — typical runs finish in 30 seconds to a few minutes depending on how many records you request
4. Download the dataset as JSON, CSV, Excel, HTML, XML, or JSONL directly from the Apify dataset view

#### API Run (Python)

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")

run = client.actor("haketa/colorado-professional-license-scraper").call(run_input={
    "licenseTypes": ["EC", "PC", "ME"],
    "statuses": ["Active"],
    "cities": ["Denver", "Colorado Springs", "Aurora"],
    "maxRecords": 5000,
})

for record in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(record["licenseNumber"], record["entityName"] or f"{record['firstName']} {record['lastName']}",
          record["licenseType"], record["status"], record["city"])
```

#### API Run (Node.js / TypeScript)

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

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });

const run = await client.actor('haketa/colorado-professional-license-scraper').call({
    licenseTypes: ['PE', 'ARC'],
    statuses: ['Active'],
    cities: ['Boulder', 'Fort Collins'],
    issuedAfter: '2020-01-01',
    maxRecords: 2000,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(`Got ${items.length} active Front Range engineers & architects`);
```

#### API Run (cURL)

```bash
curl -X POST "https://api.apify.com/v2/acts/haketa~colorado-professional-license-scraper/runs?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "licenseTypes": ["NA", "PHY"],
    "statuses": ["Active"],
    "cities": ["Denver"],
    "maxRecords": 10000
  }'
```

#### API Run (Apify CLI)

```bash
apify call haketa/colorado-professional-license-scraper \
  --input '{"licenseTypes":["REB"],"statuses":["Active"],"cities":["Denver","Aurora","Lakewood"]}'
```

***

### How It Works

The actor calls the official Colorado Information Marketplace (CIM) Socrata SODA API directly. There is no headless browser, no Puppeteer, no Playwright, no login flow, no CAPTCHA, no proxy. Everything is a plain HTTPS GET against `data.colorado.gov`.

#### Source endpoint

| Component | Value |
|---|---|
| Portal | Colorado Information Marketplace (CIM) |
| Dataset name | Professional and Occupational Licenses in Colorado |
| Dataset ID | `7s5z-vewr` |
| Base URL | `https://data.colorado.gov/resource/7s5z-vewr.json` |
| Refresh cadence | Nightly (DORA pushes a fresh extract every business night) |
| Authentication | None — public open-data API |
| Rate limits | Generous Socrata limits; default actor delay 200 ms between requests |

#### Query construction

The actor assembles a Socrata SoQL `$where` clause from your inputs and paginates with `$limit` + `$offset`. A typical request looks like:

```
GET https://data.colorado.gov/resource/7s5z-vewr.json
    ?$limit=1000
    &$offset=0
    &$order=licensefirstissuedate DESC
    &$where=licensetype in('EC','PC','ME') AND licensestatusdescription in('Active','Expired')
            AND (upper(city) = upper('Denver') OR upper(city) = upper('Aurora'))
            AND licensefirstissuedate >= '2024-01-01T00:00:00.000'
```

#### Engineering details

- **Direct HTTPS GET** — pure `got-scraping` calls, no browser stack
- **Real Socrata field discovery** — verified against live API; the actor knows the actual lowercase field names (`licensenumber`, `licensetype`, `subcategory`, `licensestatusdescription`, `firstname`, `lastname`, `middlename`, `suffix`, `entityname`, `city`, `state`, `mailzipcode`, `specialty`, `licensefirstissuedate`, `licenselastreneweddate`, `licenseexpirationdate`, `linktoverifylicense`)
- **Field-name fallback chain** — tries lowercase, camelCase, and PascalCase variants so the parser survives Socrata schema tweaks
- **Date normalization** — `2024-01-15T00:00:00.000` is sliced to `2024-01-15` for BI-friendly output
- **Verify-URL coercion** — handles `linktoverifylicense` whether it arrives as `null`, a string, or a `{ url: "..." }` object
- **Deduplication** — keyed on `licenseNumber` (falls back to last/first/type composite for malformed rows)
- **Up-front count query** — fetches `count(*) as total` so the actor knows how many records exist and can plan pagination
- **Polite delay** — configurable `requestDelay` (default 200 ms) keeps the actor well inside Socrata's quota
- **Filter validation** — on the first page the actor logs the actual returned `licensetype` values and warns if they don't match your filter, surfacing API schema drift immediately
- **Deterministic order** — `$order=licensefirstissuedate DESC` ensures stable pagination
- **No proxy required** — Socrata serves Apify datacenter IPs without complaint

***

### Input Parameters

```json
{
  "licenseTypes": ["EC", "PC", "ME", "JW", "MP", "JP", "PE", "ARC"],
  "statuses": ["Active", "Expired"],
  "cities": [],
  "issuedAfter": "",
  "issuedBefore": "",
  "maxRecords": 5000,
  "pageSize": 1000,
  "requestDelay": 200
}
```

#### Parameter reference

| Parameter | Type | Default | Description |
|---|---|---|---|
| `licenseTypes` | `array<string>` | EC, PC, ME, JW, MP, JP, PE, ARC | DORA license-type prefixes. Leave empty `[]` to pull every license type DORA exposes. Common values: `EC`, `PC`, `ME`, `JW`, `MP`, `JP`, `PE`, `ARC`, `REB` (Real Estate Broker), `COS` (Cosmetology), `NA` (Nursing), `PHY` (Physician). |
| `statuses` | `array<string>` | `["Active","Expired"]` | License statuses to include. Valid values: `Active`, `Expired`, `Suspended`, `Revoked`, `Surrendered`, `Inactive`. Empty array = all statuses. |
| `cities` | `array<string>` | `[]` | Case-insensitive city filter. Example: `["Denver","Colorado Springs","Aurora"]`. Empty = no city filter. |
| `issuedAfter` | `string` (YYYY-MM-DD) | `""` | Lower bound on `firstIssueDate`. Useful for delta sync ("only licenses first issued since my last run"). |
| `issuedBefore` | `string` (YYYY-MM-DD) | `""` | Upper bound on `firstIssueDate`. Useful for historical cohort analysis. |
| `maxRecords` | `integer` | `5000` | Cap on total records returned. `0` = unlimited. |
| `pageSize` | `integer` | `1000` | Records per Socrata page. Min 100, max 50 000. Sweet spot 1 000–5 000. |
| `requestDelay` | `integer` (ms) | `200` | Pause between Socrata requests. `0` is allowed but be polite to the public API. |

***

### Output Schema

Every record is a flat JSON object using the same field shape — whether the licensee is an individual (nurse, electrician journeyman, physician) or an entity (engineering firm, real estate brokerage, plumbing contractor). The individual-vs-entity distinction is carried by which name fields are populated.

#### Field reference

| Field | Type | Description |
|---|---|---|
| `licenseNumber` | string | null | DORA-assigned license or registration number |
| `licenseType` | string | null | Two-to-four-letter DORA type prefix (`EC`, `PC`, `ME`, `JW`, `MP`, `JP`, `PE`, `ARC`, `REB`, `COS`, `NA`, `PHY`, …) |
| `subCategory` | string | null | Sub-category within the type (e.g., Residential vs Commercial; RN vs LPN) where DORA provides one |
| `status` | string | null | Normalized status — see status reference below |
| `firstName` | string | null | Licensee given name (individuals only) |
| `lastName` | string | null | Licensee family name (individuals only) |
| `middleName` | string | null | Middle name or initial (individuals only) |
| `suffix` | string | null | Name suffix — Jr, Sr, II, III, IV, MD, DO, PhD, etc. |
| `entityName` | string | null | Company or brokerage / DBA (entity licenses only) |
| `city` | string | null | City on file with DORA |
| `state` | string | null | Two-letter US state abbreviation |
| `zipCode` | string | null | Mailing ZIP (5 or 9 digits) |
| `specialty` | string | null | Specialty area (e.g., a physician's board specialty) |
| `firstIssueDate` | string | null | First-issue date in `YYYY-MM-DD` |
| `lastRenewedDate` | string | null | Most recent renewal in `YYYY-MM-DD` |
| `expirationDate` | string | null | Current expiration in `YYYY-MM-DD` |
| `verifyUrl` | string | null | Direct URL to the live DORA license-lookup detail page |
| `scrapedAt` | string | ISO-8601 timestamp of extraction (UTC) |

#### Example: individual licensee (Professional Engineer)

```json
{
  "licenseNumber": "PE.0099999",
  "licenseType": "PE",
  "subCategory": null,
  "status": "Active",
  "firstName": "JESSICA",
  "lastName": "MARTINEZ",
  "middleName": "L",
  "suffix": null,
  "entityName": null,
  "city": "Denver",
  "state": "CO",
  "zipCode": "80202",
  "specialty": "Civil",
  "firstIssueDate": "2014-06-10",
  "lastRenewedDate": "2024-10-31",
  "expirationDate": "2025-10-31",
  "verifyUrl": "https://apps.colorado.gov/dora/licensing/Lookup/LicenseLookup.aspx?Num=PE.0099999",
  "scrapedAt": "2026-05-16T14:30:00.000Z"
}
```

#### Example: entity licensee (Plumbing Contractor)

```json
{
  "licenseNumber": "PC.9999999",
  "licenseType": "PC",
  "subCategory": "Residential",
  "status": "Active",
  "firstName": null,
  "lastName": null,
  "middleName": null,
  "suffix": null,
  "entityName": "ROCKY MOUNTAIN PLUMBING SERVICES LLC",
  "city": "Colorado Springs",
  "state": "CO",
  "zipCode": "80903",
  "specialty": null,
  "firstIssueDate": "2018-03-22",
  "lastRenewedDate": "2025-02-15",
  "expirationDate": "2027-02-15",
  "verifyUrl": "https://apps.colorado.gov/dora/licensing/Lookup/LicenseLookup.aspx?Num=PC.9999999",
  "scrapedAt": "2026-05-16T14:30:00.000Z"
}
```

#### Example: nurse (Registered Nurse)

```json
{
  "licenseNumber": "NA.99999",
  "licenseType": "NA",
  "subCategory": "RN",
  "status": "Active",
  "firstName": "CARLOS",
  "lastName": "RODRIGUEZ",
  "middleName": "A",
  "suffix": "RN",
  "entityName": null,
  "city": "Aurora",
  "state": "CO",
  "zipCode": "80012",
  "specialty": null,
  "firstIssueDate": "2017-07-01",
  "lastRenewedDate": "2024-08-31",
  "expirationDate": "2026-08-31",
  "verifyUrl": "https://apps.colorado.gov/dora/licensing/Lookup/LicenseLookup.aspx?Num=NA.99999",
  "scrapedAt": "2026-05-16T14:30:00.000Z"
}
```

***

### License Type Reference

The CIM dataset exposes dozens of DORA license-type prefixes. The most commonly requested ones — already covered by the actor's defaults and verified during testing — are listed below. Set `licenseTypes: []` if you want every prefix DORA publishes.

#### Construction & Trades

| Prefix | Profession |
|---|---|
| `EC` | Electrical Contractor |
| `PC` | Plumbing Contractor |
| `ME` | Mechanical / HVAC Contractor |
| `JW` | Journeyman Wireman (Electrical) |
| `MP` | Master Plumber |
| `JP` | Journeyman Plumber |
| `RW` | Residential Wireman |
| `ME-A` | Apprentice Electrician (where present) |

#### Design Professionals

| Prefix | Profession |
|---|---|
| `PE` | Professional Engineer |
| `ARC` | Architect |
| `PLS` | Professional Land Surveyor |

#### Healthcare

| Prefix | Profession |
|---|---|
| `NA` | Nursing (RN, LPN, APN) |
| `PHY` | Physician (MD / DO) |
| `DEN` | Dentist |
| `PHA` | Pharmacist |
| `VET` | Veterinarian |
| `PT` | Physical Therapist |
| `OPT` | Optometrist |
| `PSY` | Psychologist |

#### Real Estate, Insurance & Financial

| Prefix | Profession |
|---|---|
| `REB` | Real Estate Broker |
| `AP` | Appraiser |
| `MLO` | Mortgage Loan Originator |
| `ACC` | Certified Public Accountant |

#### Personal Services

| Prefix | Profession |
|---|---|
| `COS` | Cosmetology / Esthetics / Nail Tech |
| `BAR` | Barber |
| `MAS` | Massage Therapist |

> **Tip:** if a prefix you need isn't listed above, run the actor once with `licenseTypes: []` and `maxRecords: 200`, then group the results by `licenseType` to see the full catalog DORA is currently publishing.

***

### License Status Reference

#### Active statuses — currently authorized

| Status | Meaning |
|---|---|
| `Active` | License current and in good standing |
| `Inactive` | Voluntary inactive status — not currently practicing but reinstatable |

#### Inactive statuses — not authorized to practice

| Status | Meaning |
|---|---|
| `Expired` | Failed to renew by deadline; reinstatable per DORA rules |
| `Suspended` | Temporarily barred from practice (often pending hearing) |
| `Revoked` | Permanently terminated by Board action |
| `Surrendered` | Voluntarily surrendered, often pre-disciplinary |

Use `statuses: ["Active"]` for credentialing and compliance; `statuses: ["Suspended","Revoked","Surrendered"]` to monitor enforcement actions; or omit the field for the complete history.

***

### Use Cases

#### Healthcare Staffing, Travel Nursing & Locum Tenens

Travel-nursing platforms, locum-tenens agencies, and hospital floats teams use Colorado DORA data to:

- **Verify Colorado RN, LPN, MD, and DO licenses** before placing clinicians on assignment in Denver, Aurora, Colorado Springs, or Fort Collins hospital systems
- **Source candidates by metro** — pull every Active `NA` (nurse) record in a 60-mile radius of a hiring facility
- **Monitor expiration dates nightly** so credentials never lapse mid-assignment
- **Cross-check disciplinary status** by filtering on `Suspended` / `Revoked` before extending an offer
- **Replace per-lookup verification subscriptions** that charge $5–$20 per query
- **Document credentialing** with the DORA `verifyUrl` archived in the candidate's HR file

#### Compliance, Credentialing & Vendor Management

Hospital systems, ACOs, dental DSOs, pharmacy chains, multi-state contractors, and PBMs use the dataset to:

- **Automate monthly license verification** for every Colorado-licensed provider, contractor, or broker on payroll
- **Detect status changes within 24 hours** — `Active` → `Suspended` triggers immediate workflow
- **Maintain audit-ready logs** with timestamped `scrapedAt` proving when verification ran
- **Replace expensive third-party verification platforms** with a $0.01–$0.10 nightly run
- **Document Joint Commission, URAC, NCQA, and state inspector** due diligence
- **Run vendor-risk programs** for any Colorado-licensed counterparty (engineering firm, real estate broker, plumbing sub-contractor, etc.)

#### B2B Sales & Lead Generation

Pharma reps, medical device vendors, healthcare SaaS sellers, construction-materials suppliers, fintech vendors, insurance carriers, and trade-publication ad-sales teams use the dataset to:

- **Build targeted Colorado contractor lead lists** — every active Denver-metro electrical contractor (`EC`), every Front Range mechanical contractor (`ME`), every plumbing firm in Pueblo or Grand Junction
- **Identify net-new license issuances** by diffing this week's run against last week's — fresh `firstIssueDate` values are brand-new businesses
- **Route territory by ZIP density** of nurses, physicians, real estate brokers, or contractors
- **Enrich CRM records** (Salesforce, HubSpot, Pipedrive, Close) with current license status and verification URL
- **Power direct-mail and email campaigns** with verified mailing cities and ZIPs
- **Drive ABM playbooks** with verified entity counts per metro

#### Real Estate & PropTech

Real estate brokerages, MLS providers, lender platforms, and PropTech vendors use DORA data to:

- **Pull the complete active broker license list** (`REB`) by city — Denver, Boulder, Colorado Springs, Lakewood, Aurora, Fort Collins
- **Verify broker licenses** before onboarding agents to a brokerage platform
- **Monitor real estate license churn** — track brokers who go `Inactive` or fail to renew
- **Identify newly licensed brokers** for recruiting and broker-sponsor outreach
- **Audit broker counts** for market-share and competitive-intelligence reports

#### Construction & Trade Verification

GCs, sub-contractor management platforms, ISNetworld competitors, Avetta-style compliance tools, and bonding agencies use the data to:

- **Verify electrical (`EC`), plumbing (`PC`), and mechanical (`ME`) contractors** before issuing purchase orders or onboarding to a project
- **Confirm journeyman (`JW`, `JP`) and master (`MP`) trade licenses** for project staffing
- **Build pre-qualified bidder lists** by trade and metro
- **Flag contractors with disciplinary history** automatically
- **Cross-reference DORA verification URLs** in compliance packets
- **Reduce mechanic's-lien and bond-claim risk** by working only with currently licensed firms

#### Insurance Underwriting & Surety

Carriers and brokers writing professional liability, E\&O, contractor general liability, surety bonds, or healthcare-malpractice products use this data to:

- **Verify license validity** at bind, renewal, and at every premium audit
- **Adjust pricing for disciplinary history** programmatically
- **Monitor portfolio risk** — flag insureds whose status changes mid-policy
- **Process claims faster** with pre-verified licensee records
- **Underwrite contractor accounts** by validating trade license, sub-category, and renewal cadence

#### Legal, Litigation & Due Diligence

Plaintiff and defense attorneys, M\&A advisors, private investigators, and forensic accountants use DORA records to:

- **Verify provider, broker, or contractor credentials** in malpractice, construction-defect, or licensing disputes
- **Build license-history chronologies** when combined with archived runs (status changes over time)
- **Conduct pre-acquisition due diligence** on Colorado healthcare practices, brokerages, and contracting firms
- **Validate expert witness credentials** before engagement
- **Identify license-holder names** behind LLC entity names for service-of-process and discovery
- **Trace disciplinary actions** for regulatory-defense matters

#### Government, Public Health & Workforce Research

State agencies, academic public-health programs, think tanks, and journalists use DORA data to:

- **Quantify Colorado's healthcare workforce supply** by metro and specialty
- **Study contractor and trade-workforce shortages** across the Front Range, Western Slope, and rural Eastern Plains
- **Map license density** for healthcare-access and infrastructure equity studies
- **Investigate disciplinary patterns** for accountability journalism
- **Inform policy proposals** with empirical, current data — not stale 5-year-old census extracts

#### Academic, Continuing Education & Career Services

Pharmacy schools, nursing programs, real estate schools, trade schools, and CE providers use DORA data to:

- **Identify pipelines of newly licensed graduates** by year and metro
- **Target CE marketing** to active licensees approaching renewal
- **Build alumni outreach lists** for fundraising and engagement
- **Track program-graduate outcomes** longitudinally
- **Benchmark licensure exam pass-through** with downstream practice geography

#### Marketing, Data Journalism & Open Data Reporting

Data reporters, analytics consultancies, and open-data hobbyists use the dataset for:

- **Long-form data stories** on Colorado's regulated workforce
- **Dashboards** tracking professional licensing trends through pandemics, recessions, and migration waves
- **Civic-tech projects** improving public access to DORA data

***

### Sample Queries & Recipes

#### Recipe 1 — Every active Denver-metro electrical contractor

```json
{
  "licenseTypes": ["EC"],
  "statuses": ["Active"],
  "cities": ["Denver", "Aurora", "Lakewood", "Centennial", "Westminster", "Thornton"]
}
```

Goal: build a complete Denver-metro EC bidder list for a procurement system.

#### Recipe 2 — Active registered nurses across the Front Range

```json
{
  "licenseTypes": ["NA"],
  "statuses": ["Active"],
  "cities": ["Denver", "Colorado Springs", "Aurora", "Fort Collins", "Boulder", "Lakewood", "Pueblo"]
}
```

Goal: source-pool generation for travel-nursing and hospital recruiting.

#### Recipe 3 — Newly licensed plumbing & mechanical contractors (last 90 days)

```json
{
  "licenseTypes": ["PC", "ME"],
  "statuses": ["Active"],
  "issuedAfter": "2026-02-15"
}
```

Goal: net-new lead capture for a contractor-SaaS GTM team.

#### Recipe 4 — All Colorado Springs real estate brokers

```json
{
  "licenseTypes": ["REB"],
  "statuses": ["Active"],
  "cities": ["Colorado Springs"]
}
```

Goal: brokerage-recruiting outreach.

#### Recipe 5 — Suspended or revoked Colorado physicians (enforcement monitoring)

```json
{
  "licenseTypes": ["PHY"],
  "statuses": ["Suspended", "Revoked", "Surrendered"]
}
```

Goal: feed a healthcare-compliance enforcement dashboard.

#### Recipe 6 — Boulder & Fort Collins engineers and architects for a B2B campaign

```json
{
  "licenseTypes": ["PE", "ARC"],
  "statuses": ["Active"],
  "cities": ["Boulder", "Fort Collins"],
  "maxRecords": 3000
}
```

Goal: Front Range design-professional ABM list.

#### Recipe 7 — Statewide active cosmetology licensees, sampled for testing

```json
{
  "licenseTypes": ["COS"],
  "statuses": ["Active"],
  "maxRecords": 100,
  "pageSize": 100
}
```

Goal: schema-test before a large pull.

#### Recipe 8 — Full statewide pull (every type, every status)

```json
{
  "licenseTypes": [],
  "statuses": [],
  "cities": [],
  "maxRecords": 0,
  "pageSize": 5000
}
```

Goal: snapshot the entire DORA licensing universe for warehousing.

***

### Integration Examples

#### Google Sheets

1. Create an Apify Schedule running the actor nightly at 6:00 AM Mountain Time
2. Add the **Export to Google Sheets** integration to the schedule
3. Wake up to a freshly refreshed Colorado DORA license sheet every morning

#### Make.com / Zapier / n8n

Use the **Apify** connector on any major automation platform. Trigger downstream workflows on:

- New license records (today's run minus yesterday's run)
- Status transitions (`Active` → `Suspended`)
- City or ZIP changes (license-holder relocations)
- New disciplinary actions
- Approaching expiration dates (renewal-reminder emails)

#### Airtable

Pipe each Apify run into an Airtable base via webhook or the official Apify-Airtable integration. Use Airtable views to slice by `licenseType`, `city`, `status`, or `expirationDate`.

#### Power BI / Tableau / Looker / Metabase

Point your BI tool at the Apify dataset REST endpoint or sync the run output to your warehouse. Useful dashboards:

- Active license counts by profession and metro
- Year-over-year license issuance trends
- Disciplinary-action rates by license type
- Renewal-rate heatmaps by ZIP

#### Postgres / Snowflake / BigQuery / Redshift

Use the [Apify webhook integration](https://docs.apify.com/platform/integrations/webhooks) to POST run-finished events to your warehouse ingestion endpoint. Upsert on `licenseNumber` for an always-current `dora_licenses` table.

#### Salesforce / HubSpot / Pipedrive

Schedule the actor nightly, then upsert results against Account / Contact records keyed on `licenseNumber`. Status-change events automatically create Tasks, Opportunities, or Cases.

#### Slack / Microsoft Teams

Wire the Apify webhook to a Slack incoming webhook. Push alerts like "12 Colorado physicians newly listed as `Suspended` overnight" or "78 newly issued EC contractor licenses in the last 7 days."

***

### Major Colorado Markets at a Glance

| Metro / City | Population (metro) | Why it matters |
|---|---|---|
| Denver | 2.96M | State capital; densest concentration of nurses, physicians, brokers, and design professionals |
| Colorado Springs | 0.76M | Healthcare hub (UCHealth, Centura), Air Force / Space Force, growing contractor market |
| Aurora | 0.40M | Anschutz Medical Campus, Children's Hospital Colorado — healthcare licensing epicenter |
| Fort Collins | 0.37M | CSU, MedTech corridor, fast-growing contractor and design-pro market |
| Lakewood | 0.16M | West-metro residential growth; high EC/PC/ME density |
| Boulder | 0.11M | Engineering and tech-services concentration; PE / ARC heavy |
| Pueblo | 0.11M | Southern Colorado healthcare and trades hub |
| Centennial / Highlands Ranch | 0.30M | South-metro suburban growth corridor |
| Greeley | 0.11M | Weld County energy & ag — heavy mechanical and electrical contractor activity |
| Grand Junction | 0.07M | Western Slope healthcare and trades hub |
| Loveland | 0.08M | Northern Colorado growth ring (Fort Collins–Loveland corridor) |
| Westminster / Thornton / Broomfield | 0.40M | North-metro contractor and broker corridor |
| Castle Rock | 0.08M | Douglas County affluent residential — design-pro and broker activity |
| Durango | 0.02M | Four Corners regional anchor |

***

### Cost & Performance

| Metric | Value |
|---|---|
| Engine | Direct Socrata SODA API — no browser, no proxy |
| Runtime (default 5 000 records) | 30–90 seconds typical |
| Runtime (full statewide pull, unfiltered) | Several minutes; depends on dataset size at run time |
| Cost per run | Pay-per-event — fractions of a cent for typical runs |
| Pricing model | Pay-per-event (charged per actor start + per dataset item) |
| Data freshness | Nightly — DORA refreshes the CIM extract every business night |
| Auth required | None |
| Proxy required | None |
| Concurrency | Safe to run multiple parallel filtered configurations |
| Memory footprint | 512 MB is plenty; 1 GB recommended for unfiltered statewide pulls |
| Apify Free Plan | Fully supported |

***

### Compliance, Privacy & Legal Notes

- **Public open data** — every field in this dataset is published by DORA on [data.colorado.gov](https://data.colorado.gov/) under Colorado's Open Records Act (CORA) and the Colorado Information Marketplace's open-data license
- **No PHI** — DORA's licensing dataset contains no patient or clinical information; it is professional licensing data, not patient data
- **No SSNs, DOBs, or financial data** — only license-related public information
- **Address data** is the **mailing address on file with DORA** — typically a business or practice address, not a residence (though licensees may register a home address; treat city/ZIP as the practice locale)
- **HIPAA does not apply** — this is licensing data, not patient data
- **No emails** are included — DORA does not publish licensee email addresses through CIM
- **Robots.txt & ToS** — the actor uses Socrata's documented public SODA API; no scraping of HTML pages or circumvention of access controls
- **CAN-SPAM, TCPA, GDPR, CCPA, CPA (Colorado Privacy Act)** compliance is the responsibility of the data consumer downstream

> **Important:** DORA license data may not be used for unlawful purposes including identity fraud, stalking, harassment, or any use that would constitute an unfair or deceptive trade practice. Review DORA's [Open Records and Acceptable Use](https://dpo.colorado.gov/) policies before deploying at scale.

***

### Frequently Asked Questions

#### How fresh is the data?

DORA refreshes the underlying CIM dataset nightly (typically overnight Mountain Time). Each actor run pulls the current contents of the Socrata API, so data is at most one business day old.

#### How many records are there?

The full DORA professional and occupational license dataset contains hundreds of thousands of records spanning fifty-plus license types. Numbers vary at any given moment — set `maxRecords: 0` and `licenseTypes: []` to count the current total in the run logs.

#### Do I need a DORA account, API key, or app token?

No. The Socrata SODA API is fully public and unauthenticated. You only need an Apify account to run the actor.

#### Does this work for other states (Texas, California, Florida, New York)?

This actor is Colorado-specific. We maintain separate Apify actors for other state licensing boards — see the **Related Actors** section below.

#### Can I use this for license verification at scale?

Yes. Many compliance teams schedule the actor nightly, diff against the previous run, and trigger alerts on status changes (`Active` → `Suspended`, expiration approaching, etc.). The `verifyUrl` field gives you a defensible audit trail back to the live DORA detail page.

#### Are licensee email addresses or phone numbers included?

No. DORA does not publish licensee email addresses or phone numbers in the CIM extract. You receive name, city, state, ZIP, license metadata, and the DORA verification URL.

#### Can I filter by expiration date?

The actor returns `expirationDate` as a `YYYY-MM-DD` string. Apply expiration-date filters in your downstream pipeline (SQL `WHERE`, Python list comprehension, Sheets filter, Power Query, etc.). The direct `issuedAfter` / `issuedBefore` inputs filter by `firstIssueDate`.

#### Does the actor deduplicate?

Yes. Records are deduplicated client-side by `licenseNumber` (with a composite fallback for any rows missing a license number). Re-issued licenses with the same number appear once per run.

#### What's the difference between license types I haven't heard of?

DORA covers 50+ regulated professions under one umbrella. If a `licenseType` prefix in the dataset isn't familiar, the easiest way to decode it is to follow the `verifyUrl` on any record — DORA's live lookup page labels the profession in full.

#### Are proxies or residential IPs required?

No. Socrata serves Apify datacenter IPs without throttling under normal load. The actor uses a 200 ms request delay by default to stay polite.

#### Is there a historical snapshot version of the data?

DORA does not expose history directly. To build your own history, schedule the actor daily and archive each dataset run — Apify retains run datasets indefinitely on most paid plans.

#### Can I get NPI numbers for healthcare licensees?

NPIs are issued federally by CMS, not by DORA — they are not in this dataset. Cross-reference licensee names with the [NPPES NPI Registry](https://npiregistry.cms.hhs.gov/) for NPI enrichment.

#### Does this actor work on the Apify Free Plan?

Yes — full functionality on the free tier. Typical runs cost a small fraction of free-tier credits.

#### How do I report a bug or request a new license-type prefix?

Open an issue on the Apify Store actor page or reach out through the Apify developer profile.

#### Can I run this on a schedule?

Yes — Apify's built-in Scheduler supports hourly, daily, weekly, or any cron expression. Pair it with the webhook integration for a fully automated pipeline.

#### What export formats are supported?

JSON, CSV, Excel (XLSX), HTML, XML, RSS, and JSON Lines — directly from the Apify dataset view or REST API.

#### Does the dataset include closed or surrendered licenses?

Yes, when you include `Surrendered`, `Revoked`, `Suspended`, `Expired`, or `Inactive` in `statuses` (or omit the field entirely). Use this for historical analysis or enforcement monitoring.

#### How does pay-per-event pricing work?

You're charged a small amount for the actor start plus a per-item charge for each dataset record delivered. There are no monthly minimums — you only pay when you run, and small filtered runs cost pennies.

***

### Related Apify Actors by Haketa

If you need licensing data from other US states, federal contractor registries, or related business-verification sources, check these companion actors from the same publisher:

- [Texas Pharmacy License Scraper — TSBP](https://apify.com/haketa/tsbp-license-scraper) — every pharmacist, pharmacy, intern, and technician in Texas
- [California DCA Professional License Scraper](https://apify.com/haketa/california-dca-license-scraper) — California Department of Consumer Affairs
- [Ohio eLicense Scraper](https://apify.com/haketa/ohio-elicense-scraper) — Ohio professional licenses
- [Illinois IDFPR License Scraper](https://apify.com/haketa/illinois-idfpr-license-scraper) — Illinois licensed professionals
- [Virginia DPOR Professional License Scraper](https://apify.com/haketa/virginia-dpor-license-scraper) — Virginia regulated occupations
- [Minnesota DLI Professional License Scraper](https://apify.com/haketa/minnesota-dli-license-scraper) — Minnesota licensing
- [Washington L\&I Contractor License Scraper](https://apify.com/haketa/washington-li-contractor-license-scraper) — Washington contractor licenses
- [Arizona ROC Contractor License Scraper](https://apify.com/haketa/az-roc-contractor-license-scraper) — Arizona Registrar of Contractors
- [NC Licensing Board for General Contractors Scraper](https://apify.com/haketa/nc-licensing-board-for-general-contractors-scraper) — North Carolina GCs
- [SAM.gov Federal Contractor Entity Scraper](https://apify.com/haketa/sam-gov-federal-contractor-scraper) — federal contractor master file
- [TTB Alcohol Permittee Scraper](https://apify.com/haketa/ttb-alcohol-permittee-scraper) — federal TTB permits
- [BBB Business Scraper](https://apify.com/haketa/bbb-scraper) — Better Business Bureau profiles for enrichment

***

### Comparison vs. Alternatives

| Approach | Setup time | Data freshness | Cost (10 k records) | Schema normalization | Compliance audit log |
|---|---|---|---|---|---|
| **This actor** | < 1 minute | Nightly | Fractions of a cent | Built-in | Automatic (`scrapedAt`, `verifyUrl`) |
| Manual CIM portal CSV download | 10–20 min per pull | Nightly | Free | None | None |
| Custom Node/Python script | 6–12 hours of dev | Nightly | Free + infra | DIY | DIY |
| Paid license-verification API | Hours + contract | Real-time | $200–$2 000+/mo | Vendor schema | Vendor logs |
| CORA records request to DORA | Days | Stale | Variable | None | None |

***

### Why Pay-Per-Event Pricing?

Most data scrapers either charge a flat monthly subscription (you pay even when you don't run) or per-Compute-Unit (unpredictable bills). This actor uses **pay-per-event** pricing:

- You only pay when the actor runs
- Charges scale linearly with how much data you actually request
- Transparent line-item billing inside Apify
- No monthly minimums and no annual contract
- Free to evaluate — sample with `maxRecords: 100` for pennies before committing to a full warehouse load
- Predictable cost scaling — 100 records and 100 000 records both bill per item, no surprise overages

***

### Changelog

| Version | Date | Notes |
|---|---|---|
| 1.0.0 | 2026-05 | Initial public release — Socrata SODA API integration, full filter set (license types, statuses, cities, date range), deduplication, verify-URL extraction, pay-per-event pricing |

***

### Keywords

Colorado professional license lookup · Colorado DORA scraper · CO license verification · Denver license data · Colorado nurse doctor contractor lookup · DORA license search · data.colorado.gov scraper · Colorado Information Marketplace API · Colorado Socrata SODA scraper · Colorado contractor license database · Colorado electrician license lookup · Colorado plumbing contractor data · Colorado mechanical HVAC license · Colorado professional engineer registry · Colorado architect license API · Colorado real estate broker lookup · Colorado nursing license verification · Colorado physician license API · Colorado cosmetology license · Colorado dental license · Colorado pharmacist license · Colorado CPA license · Denver contractor leads · Colorado Springs contractor leads · Aurora professional license · Fort Collins engineer directory · Boulder architect database · Lakewood real estate broker list · Pueblo nursing license · CO DORA Apify actor · DORA license CSV download · Colorado credentialing automation · Colorado healthcare compliance · Colorado contractor verification · Colorado license expiration monitoring · Colorado disciplinary action lookup · Colorado occupational license API · 7s5z-vewr dataset · Front Range professional license data · Colorado workforce data extraction · Colorado professional license lead generation · Colorado license number lookup · Colorado broker recruiting data

***

### Support

- **Bug reports:** Use the **Issues** tab on the Apify Store page
- **Feature requests:** Same place — please describe the license type, filter, or integration you need
- **Direct contact:** Through the Apify developer profile

If this actor saves you time, a **5-star rating** on the Apify Store helps other Colorado healthcare, construction, real estate, and compliance teams discover it. Thank you!

### 📅 Changelog & Maintenance

**Last updated:** 2026-07-02 — Actor verified and maintained. Data pipeline tested for quality, structure and freshness; selectors/endpoints confirmed against the live site.

# Actor input Schema

## `licenseTypes` (type: `array`):

Choose which professions to pull. Leave empty to include a broad mix across all license types. You can select as many as you like.

## `statuses` (type: `array`):

Choose which license statuses to include. Leave empty to include every status. Select 'Active' only for a clean, currently-licensed lead list.

## `cities` (type: `array`):

Pick one or more Colorado cities to focus on. Leave empty to include every city statewide. Need a city that isn't listed? Add it under 'Other cities' below.

## `citiesCustom` (type: `array`):

Advanced: type any additional Colorado city names not offered in the dropdown above. Matching is case-insensitive.

## `issuedAfter` (type: `string`):

Only include licenses first issued on or after this date. Handy for finding newly licensed professionals. Format: YYYY-MM-DD. Leave empty for no lower bound.

## `issuedBefore` (type: `string`):

Only include licenses first issued on or before this date. Format: YYYY-MM-DD. Leave empty for no upper bound.

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

Maximum number of license records to return. Set 0 for unlimited (large professions can return hundreds of thousands of rows).

## `pageSize` (type: `integer`):

How many records to fetch per data request. The default works well for almost everyone.

## `requestDelay` (type: `integer`):

Pause between data requests, in milliseconds. The default is polite and reliable.

## Actor input object example

```json
{
  "licenseTypes": [],
  "statuses": [
    "Active"
  ],
  "cities": [],
  "citiesCustom": [],
  "maxRecords": 100,
  "pageSize": 1000,
  "requestDelay": 200
}
```

# Actor output Schema

## `licenseNumber` (type: `string`):

DORA-assigned license number

## `licenseType` (type: `string`):

License type prefix (EC, PC, ME, etc.)

## `subCategory` (type: `string`):

License sub-category if applicable

## `status` (type: `string`):

License status (Active, Expired, etc.)

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

Licensee first name

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

Licensee last name

## `middleName` (type: `string`):

Licensee middle name

## `suffix` (type: `string`):

Name suffix (Jr, Sr, III, etc.)

## `entityName` (type: `string`):

Company or entity name

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

City

## `state` (type: `string`):

State abbreviation

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

Mailing zip code

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

License specialty area

## `firstIssueDate` (type: `string`):

Date license was first issued

## `lastRenewedDate` (type: `string`):

Date of last renewal

## `expirationDate` (type: `string`):

License expiration date

## `verifyUrl` (type: `string`):

Direct link to DORA license detail

## `scrapedAt` (type: `string`):

ISO timestamp when scraped

# 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 = {
    "statuses": [
        "Active"
    ],
    "citiesCustom": [],
    "issuedAfter": "",
    "issuedBefore": "",
    "maxRecords": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("haketa/colorado-professional-license-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 = {
    "statuses": ["Active"],
    "citiesCustom": [],
    "issuedAfter": "",
    "issuedBefore": "",
    "maxRecords": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("haketa/colorado-professional-license-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 '{
  "statuses": [
    "Active"
  ],
  "citiesCustom": [],
  "issuedAfter": "",
  "issuedBefore": "",
  "maxRecords": 100
}' |
apify call haketa/colorado-professional-license-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,haketa/colorado-professional-license-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/lBz9sMER9DRgU1JeG/builds/lvM0z6rkXCFpi3TkW/openapi.json
