nursys.com

nurse-license-verify

Installation

Adds this website's skill for your agents

 

Summary

Verify a U.S. nurse license on Nursys QuickConfirm (NCSBN's primary-source-equivalent database for 58 participating boards of nursing) — returns licensee name, license number, jurisdiction, type (RN/PN/APRN-CNP/APRN-CRNA/APRN-CNS/APRN-CNM), compact status, active status, original issue/expiration dates, and discipline flags. Bulk-verify loops one-call-per-license.

FIG. 01
FIG. 02
FIG. 03
FIG. 04
FIG. 05
FIG. 06
FIG. 07
FIG. 08
SKILL.md
229 lines

Nursys Nurse License Verification (QuickConfirm)

Purpose

Verify a single U.S. nurse license on Nursys QuickConfirm (https://www.nursys.com) — the National Council of State Boards of Nursing (NCSBN) primary-source-equivalent verification database for 58 participating U.S. boards of nursing — and return the licensee's normalized record: name, license number, jurisdiction, license type (RN / PN / APRN-CNP / APRN-CRNA / APRN-CNS / APRN-CNM), compact status (single-state vs. multistate), active status, original issue date, expiration date, and discipline flag. Read-only. To "bulk-verify" an input array, the caller invokes this skill once per license; there is no batched endpoint.

When to Use

  • HR / staffing teams confirming a candidate nurse's current license is in good standing in their jurisdiction.
  • Credentialing services validating provider rosters against board-of-nursing data of record.
  • Hospital / agency compliance teams running periodic re-checks of an active nurse roster's expiration dates and disciplinary status.
  • Any flow that needs one-off (or low-volume cold) license verification against Nursys-participating boards. Use the e-Notify path instead if you already have the nurse's SSN-last-4 + birth year (see Site-Specific Gotchas) — e-Notify is captcha-free for subsequent reviews.

Workflow

Recommended method is browser with a --verified --proxies Browserbase session — but with a hard caveat. Nursys QuickConfirm requires a Google reCAPTCHA v2 image puzzle (cars / crosswalks / motorcycles / traffic-lights) to be solved per search. In 2 iterations of 2026-05-21 testing (sessions held open up to 2+ minutes each), Browserbase's --verified auto-solver did NOT clear the image puzzles before they expired (~30s server-side expiry). The form refuses to submit while the captcha is unsolved, with the visible error "Verification challenge expired. Check the checkbox again." This is the wall — see the gotcha for mitigation options.

There is no public Nursys API, no JSON endpoint, no MCP, and no CLI. NCSBN explicitly forbids "data mining or automated data gathering or extraction tools" in the terms of use (which the agent must click "I agree" on before reaching the search form). The internal ASP.NET POST endpoints (LQCSearch.aspx, LQCSummaryReport.aspx) are session-bound to the cookie set by LQCTerms.aspx accept-click plus a reCAPTCHA g-recaptcha-response token in the form payload — they cannot be hit cookieless or token-less.

Optimal browser path (per-license)

  1. Spin a stealth + residential-proxy session — Imperva (the Nursys CDN) fingerprints bare sessions instantly and serves a static "additional security check is required" 403-equivalent block page with no challenge widget. --verified --proxies is mandatory:

    SID=$(browse cloud sessions create --keep-alive --verified --proxies \
      | node -e "let s='';process.stdin.on('data',c=>s+=c).on('end',()=>process.stdout.write(JSON.parse(s).id))")
    
  2. Open the terms page — and expect to reload it once. First load almost always returns the Imperva block (page title is empty, the iframe shows "We are sorry, but an additional security check is required" + a User-Agent dump). Reload + wait ~10s and the second load passes — Browserbase's stealth layer needs the first round-trip to register a valid Incapsula session cookie (visid_incap_2434260, nlbi_2434260, incap_ses_*).

    browse open "https://www.nursys.com/LQC/LQCTerms.aspx" --remote --session "$SID"
    browse wait load --remote --session "$SID"
    browse wait timeout 4000 --remote --session "$SID"
    TITLE=$(browse get title --remote --session "$SID" | grep -oE '"title": "[^"]*"' | cut -d'"' -f4)
    if [ -z "$TITLE" ]; then
      browse reload --remote --session "$SID"
      browse wait load --remote --session "$SID"
      browse wait timeout 10000 --remote --session "$SID"
    fi
    
  3. Dismiss the OneTrust cookie banner, then accept the FCRA terms. The banner appears as a dialog with "Accept All" + "Customize" buttons; click "Accept All" first so subsequent click-through doesn't collide with the banner overlay. Then click the "I agree" link in the terms body — this navigates to LQCSearch.aspx. (Snapshot to find the current refs — they're regenerated each load. The literal accessibility labels are button: Accept All and link: c I agree.)

  4. On the search page, pick a tab. Three tabs exist:

    • Search by License Number (recommended — most precise, fewest false-positives). Fields: License number (text), License type (select: PN / RN / APRN-CNP / APRN-CRNA / APRN-CNS / APRN-CNM), State (select; see jurisdiction list below).
    • Search by Name (broader, partial-name matching accepted). Fields: Last name (required, text), First name (text), License type (same select), State (same select), Search on maiden or other names (checkbox).
    • Search by NCSBN ID (exact match against the globally-unique NCSBN nurse ID, when the caller has one). Single text field.

    Default tab is Search by Name. Click tab: Search by License Number (or tab: Search by NCSBN ID) to switch. Note: the inner clickable that activates the tab is the tab: ref itself — do NOT click the StaticText children, which may navigate away to the e-Notify marketing page instead of switching the tab panel.

  5. Fill the form. Use browse fill (not browse type) for the text inputs — fill clears existing text. Use browse select for the dropdowns, passing the exact option label (e.g. RN, FLORIDA, CALIFORNIA-RN, LOUISIANA-PN).

  6. Solve the reCAPTCHA. Click checkbox: I'm not a robot. An image puzzle ("Select all squares with crosswalks", etc.) will appear in a popup iframe. Browserbase's --verified flag may attempt to solve it but observed reliability is poor (0/3 successful solves across 2 sessions in 2026-05-21 testing — see Site-Specific Gotchas). If the agent has access to an external captcha-solving integration (2captcha, anti-captcha) or a human-in-the-loop callback, route the iframe contents to that solver. Without a working solver, the skill cannot proceed past this gate.

  7. Click link: R Search (the styled "Search" button — labelled R Search in the a11y tree because of an icon). On a successful submit, the page navigates to a results listing. Expect the URL to remain at https://www.nursys.com/LQC/LQCSearch.aspx (it's a same-page postback with a new view); confirm by reading the breadcrumb / heading text.

  8. From the results page, click View Report on the target row. This loads the QuickConfirm License Verification Report detail view (LQCSummaryReport.aspx).

  9. Extract these fields from the detail report (per NCSBN's documented report schema):

    • Nurse's Name
    • License Jurisdiction
    • License Type (one of RN, PN, APRN-CNP, APRN-CRNA, APRN-CNS, APRN-CNM)
    • License Number
    • Compact Status (single state / multistate)
    • Is License Active (the page renders e.g. ACTIVE / EXPIRED / INACTIVE / REVOKED / SUSPENDED)
    • License Original Issue Date
    • License Expiration Date
    • Discipline Against License (yes/no — and if yes, the historical detail block)
    • Discipline Against Privilege to Practice (relevant only for compact-state multistate licenses)
    • NCSBN ID (if displayed — globally-unique cross-board identifier)
  10. Release the session. browse cloud sessions update "$SID" --status REQUEST_RELEASE. Each license costs one session because the cookie session-token from Terms cannot be reused across multiple searches (page-level postback regenerates a fresh ViewState that's tied to the per-session anti-XSRF token).

Bulk-verify caller pattern

For an input array, loop and invoke per-record. Don't try to batch through a single session — Nursys page-level postbacks bind ViewState to the current selection, so submitting a second search re-uses the previous record's metadata and produces wrong results. Expect ~1 captcha challenge per record, with the captcha being the bottleneck. The skill's Zod schema:

z.object({
  success: z.boolean(),
  license: z.object({
    licensee_name: z.string(),
    license_number: z.string(),
    state: z.string(),
    license_type: z.enum(["RN","PN","APRN-CNP","APRN-CRNA","APRN-CNS","APRN-CNM"]),
    license_type_category: z.enum(["RN","LPN","APRN"]),  // PN → LPN, APRN-* → APRN
    compact_status: z.enum(["single state","multistate"]).nullable(),
    status: z.string(),                                  // ACTIVE | EXPIRED | INACTIVE | REVOKED | SUSPENDED | ...
    original_issue_date: z.string().nullable(),         // ISO YYYY-MM-DD
    expiration_date: z.string().nullable(),             // ISO YYYY-MM-DD
    discipline_against_license: z.boolean(),
    discipline_against_privilege: z.boolean().nullable(),
    ncsbn_id: z.string().nullable(),
  }).nullable(),
  error_reasoning: z.string().nullable(),
})

For the array case, wrap in z.array(<the schema above>).

Site-Specific Gotchas

  • Anti-bot stack is Imperva (Incapsula) + Google reCAPTCHA v2 image challenges. Both must be cleared per session. The X-Cdn: Imperva header is visible on every Nursys response. Without --verified --proxies the session fails at the Imperva pre-challenge (the static "additional security check is required" page with no interactive widget) on the very first request. Even with --verified --proxies, the first page load typically returns the Imperva block — reload once after a ~10s wait and the second load passes (Imperva needs one round-trip to register the stealth session as valid).

  • THE CAPTCHA IS THE WALL. Nursys reCAPTCHA v2 image puzzles ("Select all squares with crosswalks", "Select all images with cars", "Select all squares with motorcycles" — verified across iters 2026-05-21) do not auto-solve under Browserbase --verified in observed wait windows of 30s, 60s, 90s, and 120s. The widget displays "Verification challenge expired. Check the checkbox again." after ~30s of inactivity, and the parent form refuses to POST while the captcha is unsolved. NCSBN's own FAQ (ncsbn.zendesk.com/hc/.../37034543426199-Is-there-a-way-to-bypass-the-captcha) explicitly states: "NCSBN does not make any exceptions to this for Nursys QuickConfirm look-ups." For production bulk-verify, integrate a dedicated captcha-solving service (2captcha, anti-captcha, or human-in-the-loop) — the agent should extract the reCAPTCHA data-sitekey from iframe[src*="recaptcha"] (visible inside the form's IframePresentational: reCAPTCHA element) and the page URL, POST those to the solver, then browse eval to inject the returned g-recaptcha-response token into the textarea #g-recaptcha-response before clicking Search. Without an external solver, this skill terminates at step 6 of the workflow.

  • e-Notify is the captcha-free path — but it requires PII the bulk-verify caller usually doesn't have. Per NCSBN's enrollment requirements, adding a license to an e-Notify nurse list requires (a) license number + license type + jurisdiction (or NCSBN ID), (b) last 4 digits of SSN, (c) birth year, and (d) work address. Items b–c are used at enrollment time to verify employment relationship and are never stored. Once a license is enrolled to the e-Notify nurse list, subsequent re-checks of that license — including downloading the Nursys Nurse Report — are captcha-free. Decision tree: if the caller's input rows include SSN-last-4 + birth-year per nurse, build a separate enroll-and-verify flow against https://www.nursys.com/EN/ (e-Notify); if they only have license + state + name (typical cold-verify case), QuickConfirm + captcha-solver is the only path.

  • LQCSearch.aspx 302-redirects back to LQCTerms.aspx if you skip the terms acceptance. The BIGipServerpool-nursys-com + ASP.NET_SessionId cookies are set by the GET of LQCTerms.aspx, but the postback-token that the search page validates is only granted after the I-agree click. Deep-linking to the search URL with a fresh cookie jar 302s you back to Terms every time. Always start at LQCTerms.aspx.

  • The "Search by Name" tab is the default — not "Search by License Number". The NCSBN how-to FAQ recommends the License Number tab because partial-name searches return up to dozens of homonyms (a SMITH search in FLORIDA RN returns hundreds), but the UI lands on Name first. If the caller has only a name, use the Name tab + Search on maiden or other names checkbox; if they have the number, switch tabs first.

  • Tab-switching tab refs vs. their children: in the accessibility tree the tab itself (tab: Search by License Number) is the correct click target. The nested StaticText: Search children render at higher refs but clicking them sometimes triggers a marketing-link redirect to EN/ENAbout.aspx instead of switching the panel. Verified during iter-1: clicking the [X-2520] ref (a child of the tab) navigated away; clicking the [X-5002] ref (the tab itself) switched panels in-place.

  • 58 participating jurisdictions, not 50 states. The State dropdown is not a US-states list — it includes US territories (American Samoa, Guam, Northern Mariana Islands, Virgin Islands) and splits some states into board-of-nursing-level entries: CALIFORNIA-RN vs. CALIFORNIA-VN, LOUISIANA-PN vs. LOUISIANA-RN, WEST VIRGINIA-PN vs. WEST VIRGINIA-RN. The label is the exact dropdown text — case-sensitive when passing to browse select. States NOT in the list are not Nursys-participating — for those, the caller must verify against the individual board's public lookup tool. As of 2026-05-21 the dropdown does NOT include Alaska's advanced practice tier (PN/RN only) and several other tiered exclusions; check https://www.nursys.com/LQC/LQCJurisdictions.aspx for the live participation grid.

  • License type enum is 6 values, not 3. The task spec says "RN / LPN / APRN" but Nursys distinguishes the four APRN sub-types: APRN-CNP (certified nurse practitioner), APRN-CRNA (certified registered nurse anesthetist), APRN-CNS (clinical nurse specialist), APRN-CNM (certified nurse-midwife). PN is Nursys's label for the LPN/LVN/VN tier. Normalize on output: PN → LPN, APRN-* → APRN, RN stays RN. Preserve the exact Nursys label in license_type and the normalized category in license_type_category.

  • Don't waste time scripting against GraphQL / JSON endpoints — there aren't any. Nursys is a classic ASP.NET WebForms application; every interaction is a server-side ViewState postback. The only "data" endpoints are the rendered .aspx pages. The CSP allows the page to call api.smooch.io (Zendesk chat), geolocation.onetrust.com (cookie consent), accept.authorize.net (subscription billing for e-Notify Plus), and Google Tag Manager — none of which expose license data.

  • Session-token cookies don't carry across multiple searches reliably. Each search resubmission regenerates __VIEWSTATE and __EVENTVALIDATION tied to the previously-rendered listing. For bulk loops, the safest pattern is one Browserbase session per license — open Terms → click I agree → fill form → solve captcha → search → view report → release. Sharing a session across N records risks state-leakage between records.

  • Read-only enforcement: the only "action" buttons on the detail report are Download Report (generates a PDF), Print, and Email. None of these are transactional but they all generate / send something — stop at the on-screen detail and extract; do NOT click Email (sends a real email to a user-supplied address), and do not click Download repeatedly (each download is logged against the session's audit trail per NCSBN's terms).

  • Sessions expire at 30 minutes wall-clock (expiresAt is +30min from create) and the keepAlive: true flag does NOT extend that — it only prevents idle-close. Budget each per-license attempt within 5 minutes wall to leave headroom for captcha retries; for bulk loops, create + release sessions rather than holding a single long-lived session.

Expected Output

Three outcome shapes the parent caller's Zod schema should branch on:

1. Successful single-record extraction

{
  "success": true,
  "license": {
    "licensee_name": "DOE, JANE M",
    "license_number": "9355105",
    "state": "FLORIDA",
    "license_type": "RN",
    "license_type_category": "RN",
    "compact_status": "multistate",
    "status": "ACTIVE",
    "original_issue_date": "2010-05-15",
    "expiration_date": "2026-04-30",
    "discipline_against_license": false,
    "discipline_against_privilege": false,
    "ncsbn_id": "0012345678"
  },
  "error_reasoning": null
}

2. License not found in selected jurisdiction

{
  "success": false,
  "license": null,
  "error_reasoning": "No record found for license number 9999999 (RN) in FLORIDA. The license may belong to a non-Nursys-participating board, may pre-date 1985 (Nursys's earliest record cutoff), or may not yet be synced — boards push to Nursys on a 1-7 day cadence."
}

3. Anti-bot wall (captcha not solved / Imperva block persisting)

{
  "success": false,
  "license": null,
  "error_reasoning": "Nursys QuickConfirm reCAPTCHA v2 image challenge expired before solver returned a token (waited 120s). The skill cannot complete without an external captcha-solving integration. See Site-Specific Gotchas → 'THE CAPTCHA IS THE WALL'."
}

For the bulk-verify (array) caller, return:

{
  "results": [<one of the three shapes above per input row>],
  "summary": {
    "total": 50,
    "succeeded": 12,
    "not_found": 3,
    "blocked_by_captcha": 35,
    "blocked_by_imperva": 0
  }
}
Nursys Nurse License Verification · browse.sh