NMLS Consumer Access Scraper — Licenses & Contacts avatar

NMLS Consumer Access Scraper — Licenses & Contacts

Pricing

from $1.00 / 1,000 record scrapeds

Go to Apify Store
NMLS Consumer Access Scraper — Licenses & Contacts

NMLS Consumer Access Scraper — Licenses & Contacts

Scrape NMLS Consumer Access for mortgage companies, MLOs, and branches — state licenses with statuses and dates, regulatory disclosures with PDF links, trade names, and sponsor/branch relationships. Search by name, NMLS ID, or state; CAPTCHA solved automatically. Clean JSON/CSV output.

Pricing

from $1.00 / 1,000 record scrapeds

Rating

0.0

(0)

Developer

Muhamed Didovic

Muhamed Didovic

Maintained by Community

Actor stats

0

Bookmarked

24

Total users

7

Monthly active users

7 hours ago

Last modified

Share

NMLS Consumer Access Scraper logo

Turn NMLS Consumer Access into structured mortgage-licensing data. Scrape any company, individual (MLO), or branch from nmlsconsumeraccess.org — legal name, NMLS ID, addresses, every state license with status and dates, regulatory-action disclosures with PDF links, trade names, and sponsor/branch relationships. Search by name, look up NMLS IDs directly, filter to branches, or sweep a whole state. Optional public-email enrichment. JSON or CSV out, priced per result.

InputRow(s) emitted
Name / search queryOne row per matching company, MLO, or branch
NMLS IDThe matching entity (company, individual, or branch), or a lookup_status: not_found row if the ID misses
Sponsoring company NMLS IDThe company plus each sponsored MLO
State codeMatching entities in that state (pair with entity type)
Detail or search URLThe entity on that page, or every hit from that search

Pure HTTP (impit + cheerio). CAPTCHA is solved automatically. No browser.

Why use this scraper?

NMLS Consumer Access is the public mortgage-licensing registry, but it is gated behind a CAPTCHA and has no export.

  • Five seeding modes. Search by company or person name, fetch exact NMLS IDs, pull a company's sponsored MLO roster, sweep a state, or paste detail-page URLs.
  • CAPTCHA handled for you. BotDetect is solved once per session and reused for every request in the run.
  • Full state-license tables. Regulator, license name/number, status, issue date, status date, renewal year, and trade names on that license. Large lenders return 90–180 license rows each.
  • Regulatory disclosures with PDF links. Consent orders, final orders, settlements — each with a document URL.
  • Relationship expansion. Follow an individual's sponsoring companies and a company's branches and sponsored MLOs (maxSeedDepth). by_company_employees expands MLOs even when depth is 0.
  • Optional contact emails. enrichEmails: true attaches a public contact_email when one is found ($0.05 only on a hit).
  • Clean exports. One row per entity, JSON + CSV, no duplicates within a run.

Overview

Built for compliance teams, lender-vetting pipelines, recruiters, and anyone who needs a machine-readable copy of what nmlsconsumeraccess.org already shows a browser. Each dataset row is one entity. Companies carry corporate fields and a branch list URL; individuals carry employers and sponsor refs; branches carry the parent company and their own licenses.

Supported inputs

Pick a mode and fill in the matching field.

ModeInput fieldBehaviour
by_namenamesRuns an NMLS search per query. Add a city/state/ZIP to narrow (e.g. Rocket Mortgage Detroit MI) — NMLS rejects overly broad searches.
by_idnmlsIdsFetches each ID's detail page directly. Each ID is tried as company → individual → branch (or restricted via entityType, including BRANCH). A miss still writes a row with lookup_status: "not_found".
by_company_employeessponsoringCompanyIdsFetches each company, runs NMLS search on its name across its licensed states (or states), and keeps every individual whose detail page names that company as sponsor. Each MLO row carries sponsoringCompanyId. Cap with maxItems.
by_statestatesTwo-letter codes (TX, CA). Searches the whole state; pair with entityType to keep it focused.
by_urlstartUrlsExact NMLS URLs — detail pages like https://www.nmlsconsumeraccess.org/EntityDetails.aspx/COMPANY/3030 or search URLs like https://www.nmlsconsumeraccess.org/Home.aspx/SubSearch?searchText=....

Not supported: hosts outside nmlsconsumeraccess.org; licensee-only NMLS portal pages.

Use cases

TeamWhat they build
Lead generation / salesContact lists of licensed mortgage companies and MLOs by state, with phone, email, and website
Compliance & riskLicense-status monitoring and disclosure (regulatory-action) alerts on counterparties
Fintech / lending platformsPartner-vetting pipelines keyed on NMLS ID with license coverage per state
Market researchState-by-state maps of active mortgage lenders, brokers, and servicers
RecruitersMLO sourcing with sponsoring-company relationships
Journalists / researchersDatasets on enforcement actions and license surrenders

How it works

How the NMLS Consumer Access Scraper works

  1. Solve the gate once. NMLS redirects every request to a BotDetect CAPTCHA page. The actor solves it and keeps the unlocked session cookie for the whole run.
  2. Seed from your names / IDs / states / URLs — searches go through NMLS's own JSON search endpoint.
  3. Fetch each entity's detail page in parallel over the shared session, re-solving if the session expires.
  4. Parse company / individual / branch layouts into one structured row each.
  5. Optionally expand to related entities (sponsors, branches, sponsored MLOs) up to maxSeedDepth hops and maxSeedExpansions entities. by_company_employees always walks the MLO roster.
  6. Optionally enrich a public contact email when enrichEmails is on.
  7. Push one row per entity to the dataset.

Input configuration

FieldTypeRequiredNotes
modestringnoby_name (default) / by_id / by_state / by_url / by_company_employees
namesarrayfor by_nameSearch queries. Prefill: Rocket Mortgage Detroit MI
nmlsIdsarrayfor by_idExact NMLS IDs. Prefill: 3030
sponsoringCompanyIdsarrayfor by_company_employeesCompany NMLS IDs whose MLO roster you want. Prefill: 3030
statesarrayfor by_stateTwo-letter codes (TX, CA)
entityTypestringno"" (any), COMPANY, INDIVIDUAL, or BRANCH
startUrlsarrayfor by_urlDetail or SubSearch URLs
includeDisclosuresbooleannoDefault true
maxSeedDepthintegerno0–3, default 0
maxSeedExpansionsintegernoDefault 100
enrichEmailsbooleannoDefault false. Bills contact-email only when an email is found
maxItemsintegernoDefault 1000
maxConcurrencyintegernoDefault 5
proxyobjectnoDefault Apify RESIDENTIAL

Example input

Fetch two lenders and map their branches:

{
"mode": "by_id",
"nmlsIds": ["330511", "1850"],
"maxSeedDepth": 1,
"maxSeedExpansions": 50,
"maxItems": 100
}

Companies matching a name search:

{
"mode": "by_name",
"names": ["Better Mortgage New York NY"],
"entityType": "COMPANY",
"maxItems": 20
}

A single branch by NMLS ID:

{
"mode": "by_id",
"nmlsIds": ["2708833"],
"entityType": "BRANCH",
"maxItems": 1
}

MLOs sponsored by a company:

{
"mode": "by_company_employees",
"sponsoringCompanyIds": ["3030"],
"maxItems": 50
}

Output overview

Each entity is one dataset row with entityType set to COMPANY, INDIVIDUAL, or BRANCH. All three share identity, a split address (city, state, zip, addressLine2 plus the original streetAddress), stateLicenses[], license rollups, and disclosures[]. Companies add corporate fields (businessStructure, sponsoredMlos, trade-name history, branchListUrl). Individuals add employers[], officeLocations[], and sponsor refs in relatedRefs[]; since MLO pages carry no street-address field, an individual's streetAddress / city / state / zip come from their Main office (or the first listed one). Successful lookups set lookup_status: "found"; an ID that matches no type writes a short not_found row. When enrichEmails is on, a found address lands in contact_email.

Output samples

One company row, trimmed (this lender returns 93 license entries; two shown):

{
"nmlsId": "330511",
"entityType": "COMPANY",
"name": "Better Mortgage Corporation",
"streetAddress": "1 World Trade Center 80th Floor New York, NY 10007",
"city": "New York",
"state": "NY",
"zip": "10007",
"addressLine2": "80th Floor",
"lookup_status": "found",
"mailingAddress": "1 World Trade Center 80th Floor New York, NY 10007",
"phone": "415-523-8837",
"email": "licensingteam@better.com",
"website": ["www.better.com", "www.neohomeloans.com"],
"otherTradeNames": ["Better Mortgage", "NEO Home Loans"],
"priorOtherTradeNames": ["Avex Funding Corporation", "Better", "Better.com"],
"priorLegalNames": ["Avex Funding Corporation"],
"sponsoredMlos": "353",
"fiscalYearEnd": "12/31",
"formedIn": "California, United States",
"dateFormed": "02/25/2003",
"businessStructure": "Corporation",
"regulatoryActions": "Yes",
"stateLicensesCount": 93,
"stateLicensesActiveCount": 80,
"hasRegulatoryActions": true,
"licenseTypes": ["Mortgage Banker License", "Mortgage Broker/Lender License - Other Trade Name #1"],
"stateLicenses": [
{
"regulator": "Arizona",
"licenseName": "Mortgage Banker License",
"authorizedToConductBusiness": "Yes",
"licenseNumber": "BK-0942146",
"originalIssueDate": "05/03/2017",
"status": "Approved",
"statusDate": "09/30/2025",
"renewedThrough": "2026",
"otherTradeNames": "Better Mortgage; NEO Home Loans"
},
{
"regulator": "Alaska",
"licenseName": "Mortgage Broker/Lender License - Other Trade Name #1",
"authorizedToConductBusiness": "No",
"licenseNumber": "AK330511",
"originalIssueDate": "08/04/2020",
"status": "Voluntary Surrender",
"statusDate": "07/14/2022",
"renewedThrough": "None"
}
],
"disclosures": [
{
"title": "Consent Order",
"url": "https://www.nmlsconsumeraccess.org/EntityDetails.aspx/Artifact/Other.pdf?q=277502-368825"
},
{
"title": "Settlement",
"url": "https://www.nmlsconsumeraccess.org/EntityDetails.aspx/Artifact/Settlement.pdf?q=308059-398860"
}
],
"branchListUrl": "https://www.nmlsconsumeraccess.org/EntityDetails.aspx/Branches/330511",
"sourceUrl": "https://www.nmlsconsumeraccess.org/EntityDetails.aspx/COMPANY/330511",
"scrapedAt": "2026-07-22T21:32:55.719Z"
}

Key output fields

GroupFields
IdentitynmlsId, entityType (COMPANY / INDIVIDUAL / BRANCH), name, lookup_status (found / not_found), sourceUrl, scrapedAt
ContactstreetAddress, city, state, zip, addressLine2, mailingAddress, phone, tollFreeNumber, fax, email, website[]
Enrichment (when enrichEmails: true)contact_email, contact_website, emailEnrichment.{website, emails, source, confidence}
Names historyotherTradeNames[], priorOtherTradeNames[], priorLegalNames[], otherNames[]
Corporate (companies)businessStructure, formedIn, dateFormed, fiscalYearEnd, stockSymbol, sponsoredMlos, branchListUrl
LicensesstateLicenses[], stateLicensesCount, stateLicensesActiveCount, licenseTypes[], hasRegulatoryActions
DisclosuresregulatoryActions, selfReportedDisciplinaryActions, disclosures[].{title, url}
Relationshipsemployers[] and officeLocations[].{company, companyNmlsId, type, streetAddress, city, state, zip, startDate} (individuals), relatedRefs[].{entityType, id, url}, sponsoringCompanyId (MLOs reached through a company roster)

Pricing

EventWhenRate
Actor startOnce per run, per GB of memory$0.10
Record scrapedEach dataset row (company, MLO, or branch)$0.001
Contact email foundOnly when enrichEmails is on and a public email is found$0.05 (billed as additional-data units until the named contact-email event can be registered on 7 Oct 2026)

Cap spend with maxItems. Enrichment is never billed on a miss.

What makes this richer than the competition

Compared with jungle_synthesizer/nmls-consumer-access-crawler:

CapabilityOther NMLS crawlerThis actor
CAPTCHA after a successful solve still dropping the recordReported by their users (closed issues, May 2026)Session is re-solved transparently; cloud smoke on 330511 returned 93 licenses
Company → sponsored MLO rosterby_company_employeesSame mode (sponsoringCompanyIds), sponsor confirmed on each detail page, sponsoringCompanyId on every MLO row, plus MLO expansion when maxSeedDepth >= 1
Split address + license rollupscity / state / zipSame, plus addressLine2, stateLicensesCount, stateLicensesActiveCount, hasRegulatoryActions
Missed ID is visiblelookup_statuslookup_status: "not_found" row instead of a silent skip
Branch-only lookupSearch/company/MLO focusedentityType: "BRANCH" plus branch expansion from a company
Contact email enrichmentNot on the Store cardOpt-in enrichEmails, billed only on a hit
Public issuesTwo closed "record not found" bugsNone filed

Same start + per-record price ($0.10 + $0.001).

Notes & limitations

  • NMLS rejects overly broad name searches. Add a city, state, or ZIP.
  • Datacenter proxies are blocked. Keep the default residential group.
  • Only public Consumer Access pages are scraped — no NMLS portal login, no non-public data.
  • Local OCR almost never solves BotDetect; the run uses CapSolver behind the scenes.

FAQ

How does the actor get past the NMLS CAPTCHA? NMLS serves a BotDetect image CAPTCHA before any data page. The actor solves it at run start and reuses the unlocked session, re-solving if the session expires. You do not configure a solver.

Which entity types are returned? Companies, individuals (MLOs), and branches. In by_id mode each ID is tried as company → individual → branch until one matches. Set entityType to COMPANY, INDIVIDUAL, or BRANCH to skip the guessing.

Why do my name searches return nothing? NMLS caps result sets server-side. Narrow the query — e.g. Better Mortgage New York NY.

How do I get a company's branches or an MLO's employer? Set maxSeedDepth: 1. Companies expand to branches and sponsored MLOs; individuals expand to sponsoring companies. maxSeedExpansions caps the total.

How do I pull the MLOs a company sponsors? Set mode: "by_company_employees" and put the company NMLS ID in sponsoringCompanyIds. NMLS has no roster page, so the actor searches the company name as an individual query (per licensed state, then per state and first name when NMLS refuses a query as too broad) and keeps only people whose detail page lists that company under its sponsors. The company row is included; each MLO row has sponsoringCompanyId. For a sponsor with thousands of MLOs the result is a sample bounded by maxItems, not the full list. Pass states to focus the sweep.

What if an NMLS ID does not exist? The run still writes a row: lookup_status: "not_found", with the ID you asked for. Hits use lookup_status: "found".

What does enrichEmails cost? Nothing unless a public email is found. A hit charges the contact-email event ($0.05). The NMLS page email (email) is always included when the registry lists one, at no extra charge.

Do I need my own proxy? No. The default Apify residential proxy works. Switching away from RESIDENTIAL will typically break the run.

Can it access licensee-only or authenticated NMLS data? No. Only the public Consumer Access pages.

How do I limit cost? Set maxItems. The actor stops queuing new entities once the cap is reached.

Support

Additional services

Custom output shape, additional fields, one-off datasets, or a similar scraper for another licensing registry: muhamed.didovic@gmail.com. API access (usage fee only, no Apify fee) on request.

Explore more scrapers

Other scrapers and actors at memo23's Apify profile — job boards, real estate, directories, social, and more.

🤖 For AI Agents & LLM Apps

Compact reference for agents calling this actor via the Apify MCP server or the Apify API (actor: memo23/nmls-scraper).

Purpose: look up US mortgage companies, loan originators (MLOs), and branches in the NMLS Consumer Access registry, with state licenses and regulatory disclosures.

Minimal input:

{ "mode": "by_id", "nmlsIds": ["330511"], "maxItems": 1 }

Output: one dataset row per entity — nmlsId, lookup_status, entityType, name, streetAddress, city, state, zip, phone, email, website, otherTradeNames, businessStructure, sponsoredMlos, stateLicenses[], stateLicensesCount, hasRegulatoryActions, disclosures[] ({title, url}), sourceUrl. Optional: contact_email when enrichEmails is true.

Company MLO roster: { "mode": "by_company_employees", "sponsoringCompanyIds": ["3030"], "maxItems": 50 }

Behaviors an agent should know:

  • Always set maxItems. An uncapped state sweep can be thousands of rows.
  • The actor solves NMLS's CAPTCHA itself (adds about 10–60 s at run start).
  • Requires residential proxy (the default is correct).
  • Broad name searches are rejected by NMLS — include a city or state in names.
  • Billing: $0.10 per start (per GB) + $0.001 per row. enrichEmails adds $0.05 only when an email is found.
  • One row per entity; entityType tells you which parser produced it.

⚠️ Disclaimer

This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by the Nationwide Multistate Licensing System (NMLS), the State Regulatory Registry LLC (SRR), the Conference of State Bank Supervisors (CSBS), or any of their subsidiaries or affiliates. All trademarks mentioned are the property of their respective owners.

The scraper accesses only publicly available pages on nmlsconsumeraccess.org — the same consumer-facing registry data anyone can view in a browser. No authenticated NMLS portal content, licensee-only features, or non-public data is accessed. Users are responsible for ensuring their use complies with nmlsconsumeraccess.org's Terms of Use, applicable data-protection law (GDPR, CCPA, etc.), and any contractual obligations of their own organisation.


SEO Keywords

nmls scraper, nmls consumer access scraper, scrape nmls, nmls api, nmls data export, nmls license lookup api, mortgage license data, mortgage company license scraper, mlo license scraper, mortgage loan originator data, nmls id lookup, state mortgage license database, mortgage lender verification, mortgage broker license data, loan officer license lookup, mortgage compliance data, nmls regulatory actions data, mortgage industry dataset, mortgage lead generation data, nmls branch locations data, mortgage licensing api alternative