Ohio eLicense Scraper - Pharmacy & Professional
Pricing
from $2.50 / 1,000 results
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
Maintained by CommunityActor stats
0
Bookmarked
6
Total users
1
Monthly active users
8 days ago
Last modified
Categories
Security
Limited permissionsShare
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.
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 / Revokedstatus 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: trueto open each license page for the fullest record (address, issue/expiration dates). - ✅ Disciplinary flag — the portal's Board Action? column is normalized into a
disciplinaryActionboolean 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
scrapedAtfields. - 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.
| Parameter | Type | Description |
|---|---|---|
boards | array<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"]. |
licenseTypes | array<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. |
searchName | string | Optional licensee last-name search, e.g. Smith. Partial matches supported. Empty = everyone on the board. |
searchLicenseNumber | string | Optional exact license/registration-number lookup. Empty = all records. |
statusFilter | string | all (default), active_only (current Active licenses), or inactive_only (Suspended, Revoked, Expired, Inactive, Surrendered, Not Renewed, Denied, Pending, Closed). |
counties | array<string> | Post-filter by Ohio county, e.g. Franklin (Columbus), Cuyahoga (Cleveland), Hamilton (Cincinnati). Empty = all 88 counties. |
scrapeDetails | boolean | true opens each license detail page for the fullest record — address plus issue/expiration dates (slower). Default false. |
maxRecords | integer | Hard cap on total records emitted. 0 = unlimited. Default 0 (prefill 100 for a cheap sample). |
maxPages | integer | Hard cap on result pages walked per search. 0 = paginate to the end. Default 0. |
requestDelay | integer (ms) | Pause between page loads. Keep ≥ 1000 for smooth runs. Range 500–10000. Default 2000. |
proxyConfiguration | object | Proxy 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
| Field | Description |
|---|---|
licenseNumber | Ohio license / application / endorsement number issued by the board (e.g. RN.503619, LPN.182864.MEDS-IV) |
board | Issuing board — e.g. Board of Pharmacy, Nursing Board, Medical Board |
licenseType | Specific license category — e.g. Registered Nurse (RN), Licensed Practical Nurse (LPN), Pharmacist, Doctor of Medicine |
licenseeType | The board's sub-category / entity classification for the row (e.g. MEDS-IV, MEDS) (present when the portal exposes it; null otherwise) |
lastName | Family name (individuals; null for business records) |
firstName | Given name / middle (individuals; null for business records) |
businessName | Facility / firm / pharmacy name (business records only) |
licenseStatus | Normalized status — Active, Inactive, Closed, Suspended, Revoked, Expired, etc. (see the status reference below) |
issueDate | License issue date, YYYY-MM-DD (detail page — populate with scrapeDetails: true) |
expirationDate | Current expiration date, YYYY-MM-DD (detail page — populate with scrapeDetails: true) |
address | Street address on file with the board (detail page — populate with scrapeDetails: true) |
city | City |
county | Ohio county |
state | Two-letter state abbreviation (usually OH) |
zip | ZIP code (5 or 9 digits) |
disciplinaryAction | true if the portal's Board Action? column says Yes, false if No, null if unknown |
detailUrl | Direct link back to the source license detail page (oh_verifylicensedetails?pid=…) |
scrapedAt | ISO-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%, withcityat 100% andcounty/zipat ~99%.address,issueDateandexpirationDateare not in the list view the portal returns — enablescrapeDetails: trueto fetch them from each license's detail page.businessNamepopulates 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 andstatusFilter: "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
Smithsweep 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
- Open the actor on the Apify Console and click Try for free.
- Pick a board (e.g.
Board of Pharmacy), and optionally add a license type, name, county, or status filter. - Set
maxRecords(e.g.100) for a fast, low-cost sample, or leave0for a full search. - Press Start. Your dataset appears in the run view in minutes.
- Export as JSON, CSV, Excel, HTML, XML, or RSS — or pull it via the Apify API.
- 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 ApifyClientclient = 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.govis 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
searchNamefor a diverse sample. A common surname likeSmithsurfaces a broad cross-section of licensees across the whole board. - Enable
scrapeDetails: truewhen you need full address and issue/expiration dates — the list view alone does not include them. - Diff daily runs on
licenseNumber+boardto detect new issuances, expirations, andActive → Suspendedstatus flips. - One board per run: to cover several boards, schedule the actor once per board or loop over boards via the API.
❓ FAQ
Is scraping Ohio eLicense legal?
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.
🔗 Related scrapers
Need licensing data from other states or related regulators? These sibling actors share the same clean, normalized JSON output:
- Illinois License Scraper (IDFPR) — Illinois multi-board state portal (closest sibling to Ohio)
- California DCA Professional License Scraper — every California professional board
- Virginia DPOR Professional License Scraper — Virginia regulated occupations
- Minnesota DLI Professional License Scraper — Minnesota Department of Labor & Industry
- Colorado Professional License Scraper — Colorado DORA licensing
- Texas Pharmacy License Scraper (TSBP) — Texas State Board of Pharmacy daily data
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.