Ohio eLicense Scraper - Pharmacy & Professional avatar

Ohio eLicense Scraper - Pharmacy & Professional

Pricing

from $2.50 / 1,000 results

Go to Apify Store
Ohio eLicense Scraper - Pharmacy & Professional

Ohio eLicense Scraper - Pharmacy & Professional

Ohio eLicense scraper & API: search Ohio professional licenses across boards and export license number, profession, status, name, address and dates. Professional license verification, compliance and lead generation — fast, no login.

Pricing

from $2.50 / 1,000 results

Rating

0.0

(0)

Developer

Haketa

Haketa

Maintained by Community

Actor stats

0

Bookmarked

6

Total users

1

Monthly active users

8 days ago

Last modified

Security

Limited permissions

Share

Ohio eLicense Scraper — Pharmacy, Nursing, Medical & Multi-Board Professional License Lookup

The fastest way to scrape the Ohio eLicense portal. This Ohio eLicense scraper searches the official Ohio eLicense portal (elicense.ohio.gov) across 17 Ohio regulatory boards — pharmacists, nurses, physicians, dentists, engineers, accountants, cosmetologists, funeral directors and more — and pulls clean, structured license records with status, issue/expiration dates, county, address and a disciplinary-action flag. No login, no coding. Built for credentialing, compliance monitoring, B2B lead generation, recruiting, M&A diligence, and Ohio workforce analytics.

Export every result to JSON, CSV, Excel, or API.

Apify Actor

Built for: healthcare credentialing & compliance teams, locum / travel staffing and recruiting firms, pharma and medical-device sales, EHR / pharmacy-software vendors, contractor-services SaaS, insurance underwriters, attorneys and M&A advisors, journalists and health-policy researchers who need verified Ohio professional-license data.


🔎 Why scrape Ohio eLicense?

The Ohio eLicense portal is the single official lookup tool for professional and occupational licenses issued by the State of Ohio's regulatory boards — pharmacists in Columbus, nurses in Cleveland, physicians in Cincinnati, dentists in Toledo, engineers in Akron, accountants in Dayton. The data is public (published under Ohio's Public Records Act) and enormously valuable: it tells you who is licensed, whether the license is active, when it expires, where the licensee is located, and whether the board has taken disciplinary action.

But the portal was never designed for bulk access. It is built on Salesforce Visualforce + RichFaces + Ajax4JSF — a legacy JSF stack with no public API, no CSV export, and a search form that only exists after JavaScript renders it behind an F5/Shape bot-defense challenge. Collecting more than a handful of records by hand is slow, error-prone, and impossible to keep current. This Ohio eLicense scraper automates the whole thing: pick a board, add an optional filter, press Start, and walk away with structured, de-duplicated license data.

Common reasons people scrape Ohio eLicense:

  • ✅ Primary-source license verification for healthcare credentialing (Joint Commission, NCQA, URAC, DNV-GL)
  • ✅ Compliance monitoring — detect Active → Suspended / Revoked status flips day over day
  • ✅ B2B lead generation — build targeted Ohio lists by board, license type, or county
  • ✅ Recruiting & sourcing — find active RNs, LPNs, pharmacists, or skilled-trade professionals by region
  • ✅ M&A and legal due diligence on Ohio pharmacies, dental groups, and professional practices
  • ✅ Insurance underwriting — validate self-reported license numbers against the source
  • ✅ Market & public-health research — map Ohio's workforce supply by county and metro

✨ What this Ohio eLicense scraper does

  • ✅ Searches any of 17 Ohio regulatory boards — one board per run. Choose Board of Pharmacy, Nursing Board, Medical Board, Dental Board, Chiropractic Board, Cosmetology & Barber Board, Counselor/Social Worker/MFT Board, Chemical Dependency Professionals Board, Behavioral Health (DBH), Engineers & Surveyors Board, Architects Board, Accountancy Board, Embalmers & Funeral Directors Board, Motor Vehicle Repair Board, Casino Control Commission, Commerce – Manufactured Homes Program, or Industrial Compliance: Elevator.
  • ✅ Drives the live JSF / RichFaces form end-to-end — selects the board, waits for the license-type dropdown to repopulate, narrows by license type / name / license number, submits, and reads the results table.
  • ✅ Automatic pagination — walks the Ajax4JSF DataTables results grid page by page and returns hundreds of de-duplicated records per search, keyed on licenseNumber + board, then stops cleanly when the result set is exhausted.
  • ✅ Rich, normalized fields — licenseNumber, board, licenseType, licenseeType, lastName, firstName, businessName, licenseStatus, issueDate, expirationDate, address, city, county, state, zip, disciplinaryAction, detailUrl, scrapedAt.
  • ✅ Server + client filtering — narrow by license type at the portal, then post-filter by status (active_only / inactive_only / all) and by Ohio county.
  • ✅ Optional detail-page enrichment — set scrapeDetails: true to open each license page for the fullest record (address, issue/expiration dates).
  • ✅ Disciplinary flag — the portal's Board Action? column is normalized into a disciplinaryAction boolean on every row.
  • ✅ Export formats — JSON, CSV, Excel (XLSX), HTML, XML, JSON Lines, or RSS, from the dataset view or the Apify API.
  • ✅ Reliable browser engine — Playwright (Chromium) run through a residential US exit so the portal's bot-defense challenge solves and the Visualforce form renders.

⚠️ Coverage note: the actor searches one board per run (the first board you select). To cover multiple boards, run it once per board — e.g. on a schedule, or with the Apify API in a loop. There is no "all boards at once" mode; leaving the board list empty runs a quick Nursing Board sample so an empty run still returns useful data.

🎯 Use cases

  • Healthcare staffing & travel pharmacy/nursing — verify Ohio licenses before assignment, source candidates by county, monitor expirations so credentials never lapse mid-contract.
  • Credentialing, compliance & provider enrollment — automate primary-source verification, catch status changes within a day, and keep audit-ready logs with timestamped scrapedAt fields.
  • B2B sales & lead generation — build targeted Ohio lead lists by board, county, or license type; identify net-new issuances by diffing runs; enrich CRM records with current status.
  • Recruiting & workforce intelligence — map clinician and skilled-trade supply across rural Appalachian Ohio vs. urban metros; build longitudinal pipelines of newly issued licenses.
  • Compliance & disciplinary monitoring — continuously watch disciplinary events for a provider panel and trigger alerts when a status flips.
  • Legal, litigation & M&A diligence — verify licensure in disputes, build license-history chronologies, and vet responsible parties at a facility.
  • Insurance underwriting — validate license numbers at policy bind/renewal and adjust pricing for disciplinary history.
  • Market, academic & public-health research — study Ohio's healthcare-workforce shortages, pharmacy/primary-care deserts, and regulatory-enforcement trends by county.

📥 Input

Pick a board, optionally add a narrowing filter, and press Start. No filters are required — every parameter below is optional.

ParameterTypeDescription
boardsarray<string>Ohio board to search (one board per run — the first entry is used). Choose from the 17-board dropdown, e.g. Board of Pharmacy, Nursing Board, Medical Board, Dental Board, Engineers and Surveyors Board, Accountancy Board. Leave empty to run a quick Nursing Board sample. Default ["Nursing Board"].
licenseTypesarray<string>Narrow to a specific license type inside the chosen board, e.g. Pharmacist, Registered Nurse, Doctor of Medicine. Partial names work. Empty = every license type on that board.
searchNamestringOptional licensee last-name search, e.g. Smith. Partial matches supported. Empty = everyone on the board.
searchLicenseNumberstringOptional exact license/registration-number lookup. Empty = all records.
statusFilterstringall (default), active_only (current Active licenses), or inactive_only (Suspended, Revoked, Expired, Inactive, Surrendered, Not Renewed, Denied, Pending, Closed).
countiesarray<string>Post-filter by Ohio county, e.g. Franklin (Columbus), Cuyahoga (Cleveland), Hamilton (Cincinnati). Empty = all 88 counties.
scrapeDetailsbooleantrue opens each license detail page for the fullest record — address plus issue/expiration dates (slower). Default false.
maxRecordsintegerHard cap on total records emitted. 0 = unlimited. Default 0 (prefill 100 for a cheap sample).
maxPagesintegerHard cap on result pages walked per search. 0 = paginate to the end. Default 0.
requestDelayinteger (ms)Pause between page loads. Keep ≥ 1000 for smooth runs. Range 500–10000. Default 2000.
proxyConfigurationobjectProxy block. Defaults to Apify Residential, US — required for the portal's bot-defense challenge to solve. Keep the default unless you have a specific reason to change it.
{
"boards": ["Board of Pharmacy"],
"licenseTypes": ["Pharmacist"],
"searchName": "Smith",
"searchLicenseNumber": "",
"statusFilter": "active_only",
"counties": ["Franklin", "Cuyahoga"],
"scrapeDetails": false,
"maxRecords": 100,
"maxPages": 0,
"requestDelay": 2000,
"proxyConfiguration": {
"useApifyProxy": true,
"apifyProxyGroups": ["RESIDENTIAL"],
"apifyProxyCountry": "US"
}
}

📤 Output

Every record uses the same flat JSON shape — whether the licensee is a Columbus pharmacist, a Cleveland RN, a Cincinnati dentist, or a Dayton accountant — so downstream consumers ingest the whole dataset without per-board branching.

The example below is a real list-level record from a verification run (Nursing Board, surname Smith). At the list level the portal returns identity, status, location and the disciplinary flag; address and the date fields come from the per-license detail page (scrapeDetails: true).

{
"licenseNumber": "LPN.182864.MEDS-IV",
"board": "Nursing Board",
"licenseType": "Licensed Practical Nurse (LPN)",
"licenseeType": "MEDS-IV",
"lastName": "Smith",
"firstName": "Charity Danielle",
"businessName": null,
"licenseStatus": "Active",
"issueDate": null,
"expirationDate": null,
"address": null,
"city": "Mansfield",
"county": "Richland",
"state": "OH",
"zip": "44903",
"disciplinaryAction": false,
"detailUrl": "https://elicense.ohio.gov/oh_verifylicensedetails?pid=a0R8y000000HNsOEAW",
"scrapedAt": "2026-11-02T00:22:55.301Z"
}

A business record (e.g. a Terminal Distributor of Dangerous Drugs pharmacy facility on the Board of Pharmacy) follows the same shape with a populated businessName, and lastName / firstName set to null.

Field reference

FieldDescription
licenseNumberOhio license / application / endorsement number issued by the board (e.g. RN.503619, LPN.182864.MEDS-IV)
boardIssuing board — e.g. Board of Pharmacy, Nursing Board, Medical Board
licenseTypeSpecific license category — e.g. Registered Nurse (RN), Licensed Practical Nurse (LPN), Pharmacist, Doctor of Medicine
licenseeTypeThe board's sub-category / entity classification for the row (e.g. MEDS-IV, MEDS) (present when the portal exposes it; null otherwise)
lastNameFamily name (individuals; null for business records)
firstNameGiven name / middle (individuals; null for business records)
businessNameFacility / firm / pharmacy name (business records only)
licenseStatusNormalized status — Active, Inactive, Closed, Suspended, Revoked, Expired, etc. (see the status reference below)
issueDateLicense issue date, YYYY-MM-DD (detail page — populate with scrapeDetails: true)
expirationDateCurrent expiration date, YYYY-MM-DD (detail page — populate with scrapeDetails: true)
addressStreet address on file with the board (detail page — populate with scrapeDetails: true)
cityCity
countyOhio county
stateTwo-letter state abbreviation (usually OH)
zipZIP code (5 or 9 digits)
disciplinaryActiontrue if the portal's Board Action? column says Yes, false if No, null if unknown
detailUrlDirect link back to the source license detail page (oh_verifylicensedetails?pid=…)
scrapedAtISO-8601 timestamp of extraction

Field coverage (verified): on a list-level run, the core identity fields — licenseNumber, board, licenseType, licenseStatus, lastName, firstName, detailUrl — populate at 100%, with city at 100% and county / zip at ~99%. address, issueDate and expirationDate are not in the list view the portal returns — enable scrapeDetails: true to fetch them from each license's detail page. businessName populates on business/facility records (e.g. pharmacies), not on individual licensees.

License status reference

Active statuses (active_only): Active.

Inactive / lapsed statuses (inactive_only): Inactive, Closed, Expired, Suspended, Revoked, Surrendered, Not Renewed, Denied, Pending.

Tip: compliance teams typically want statusFilter: "active_only" for credentialing and statusFilter: "all" for change-detection diffs against the previous day's run.

🔁 Pagination & scale

The Ohio eLicense results table is a jQuery DataTables grid re-rendered by Ajax4JSF — there is no clean ?page=N URL. The actor clicks the table's Next control, waits for the partial Ajax update to settle, parses the new rows, and repeats. Records are de-duplicated across pages using licenseNumber + board before they are pushed to the dataset (a verification run produced 0 duplicates).

One portal quirk this actor handles for you: the DataTables Next control does not reliably get a disabled class at the true end of the result set — on the final pages it re-renders a single stale row and keeps Next clickable. The actor detects this by watching for pages that introduce no new unique license records and stops as soon as the data is exhausted, so a run never spins in place wasting proxy time.

Scale is controlled entirely by you:

  • maxRecords — stop after N total records (0 = unlimited). Great for cheap sample runs.
  • maxPages — stop after N result pages per search (0 = walk to the end). Each page is ~10 records.
  • A targeted single-board / single-surname / single-license-type search typically returns hundreds of de-duplicated records (e.g. a surname Smith sweep on the Nursing Board returns ~150). Narrow further (county, license type) for a tighter set, or run once per board to cover multiple boards.

⚙️ How to use

  1. Open the actor on the Apify Console and click Try for free.
  2. Pick a board (e.g. Board of Pharmacy), and optionally add a license type, name, county, or status filter.
  3. Set maxRecords (e.g. 100) for a fast, low-cost sample, or leave 0 for a full search.
  4. Press Start. Your dataset appears in the run view in minutes.
  5. Export as JSON, CSV, Excel, HTML, XML, or RSS — or pull it via the Apify API.
  6. Automate: schedule the actor on a cron, or wire it into Make, Zapier, n8n, Google Sheets, a webhook, or your warehouse (Postgres / Snowflake / BigQuery) for continuous verification.

API run (Python)

from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("haketa/ohio-elicense-scraper").call(run_input={
"boards": ["Board of Pharmacy"],
"licenseTypes": ["Pharmacist"],
"statusFilter": "active_only",
"counties": ["Franklin", "Cuyahoga", "Hamilton"],
"scrapeDetails": True,
"maxRecords": 500,
})
for record in client.dataset(run["defaultDatasetId"]).iterate_items():
print(record["licenseNumber"], record["board"],
record["lastName"] or record["businessName"], record["city"])

You can also start a run with a plain HTTP POST to https://api.apify.com/v2/acts/haketa~ohio-elicense-scraper/runs?token=YOUR_TOKEN and the same JSON body, then read the dataset from the returned defaultDatasetId.

💡 Tips

  • Keep the default Residential/US proxy on. elicense.ohio.gov is fronted by an F5/Shape bot-defense layer that hard-blocks datacenter IPs; a residential US exit is required for the Visualforce form to render.
  • Narrow before you scale. A board plus a license type, surname, or county returns a tight, relevant set far faster than an unfiltered sweep.
  • Use searchName for a diverse sample. A common surname like Smith surfaces a broad cross-section of licensees across the whole board.
  • Enable scrapeDetails: true when you need full address and issue/expiration dates — the list view alone does not include them.
  • Diff daily runs on licenseNumber + board to detect new issuances, expirations, and Active → Suspended status flips.
  • One board per run: to cover several boards, schedule the actor once per board or loop over boards via the API.

❓ FAQ

The actor reads public records published by the State of Ohio at elicense.ohio.gov under the Ohio Public Records Act (R.C. 149.43). It interacts only with the public verification form, honors requestDelay, and bypasses no authentication, paywall, or CAPTCHA. Compliance with CAN-SPAM, TCPA, GDPR/CCPA, and Ohio data-broker rules is the data consumer's responsibility — do not use the data for unlawful purposes.

How many results can I get, and how fast?

A targeted single-board search returns hundreds of records (a surname sweep on a large board such as Nursing returns ~150); a single license-number lookup returns one. A list-level single-board sweep typically takes a few minutes; enabling scrapeDetails adds a navigation per record and takes longer. Use maxRecords / maxPages to bound runtime and cost.

Do I need proxies or a login?

No login, no API key, and no CAPTCHA at the verification page. You do need a proxy: the portal's bot-defense layer blocks datacenter IPs, so the actor defaults to Apify Residential (US) — keep that default for reliable runs.

Is there an Ohio eLicense API?

The State of Ohio does not offer a public API or CSV export — the only access point is the interactive oh_verifylicense web form. This actor is effectively that missing Ohio eLicense API: it returns the same data as clean JSON/CSV and can be called over the Apify REST API or on a schedule.

How fresh is the data?

Live at run time. The actor queries the portal directly during each run, so every record reflects the portal's current state at scrape time. Schedule it daily for an always-up-to-date local copy.

How many boards does it cover, and can it do all of them at once?

It covers 17 Ohio regulatory boards and searches one board per run (the first board you select). There is no "all boards at once" mode — to cover multiple boards, run the actor once per board (easy to automate with a schedule or an API loop). Leaving the board list empty runs a quick Nursing Board sample.

Can I filter by county, status, or license type?

Yes. Filter by license type at the portal (licenseTypes), then post-filter by status (statusFilter) and Ohio county (counties, all 88 supported). Dates (issueDate, expirationDate, with scrapeDetails: true) are returned as fields so you can apply date-range filters downstream.

Are emails or phone numbers included, and are records de-duplicated?

Emails: no — Ohio eLicense does not publish licensee email addresses. Phone numbers: occasionally appear on detail pages for business records (scrapeDetails: true). De-duplication: every record is keyed by licenseNumber + board, so overlapping pages are de-duped before push (verification runs show 0 duplicates).

Does the dataset include revoked, expired or closed records?

Yes — set statusFilter: "all" or statusFilter: "inactive_only" to include Closed, Inactive, Suspended, Revoked, Expired, Surrendered, and other inactive statuses for historical analysis or sanction monitoring.

What export formats are supported?

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

A common gotcha?

Remember the actor processes only the first board in the boards list per run, and the Ohio portal needs a board combined with at least one narrowing criterion (name, license type, or license number) to return results — a board-only query just re-renders an empty form, so the actor seeds a Smith surname search when no narrower is supplied.

Need licensing data from other states or related regulators? These sibling actors share the same clean, normalized JSON output:


Compliance & privacy notes

  • Public data only — license-related public information published by the State of Ohio. No PHI, SSNs, DOBs, or financial data; HIPAA does not apply.
  • Address data is the business / practice address on file with the board in most cases, not a personal residence.
  • No emails — Ohio eLicense does not publish licensee email addresses.
  • Ohio license data may not be used for unlawful purposes including identity fraud, stalking, or harassment. Consult Ohio's Public Records Act guidance and your own counsel before using this data in regulated workflows.

Ready to pull Ohio professional-license data? Pick a board, press Start, and export verified Ohio eLicense records as JSON, CSV, Excel, or API. ⭐ A 5-star rating on the Apify Store helps other credentialing, compliance, recruiting, and contractor-services teams find this Ohio eLicense scraper.