← Guides

How-to

How to run New Mexico Contractor License Lookup & List Scraper (NM CID)

Step-by-step: the exact input, what each filter does, and the rows that come back from the NM CID contractor registry.

The honest version first: if you have one New Mexico contractor to check and you need their status today, use the state’s own portal. It’s free and it’s live. This actor reads something different — a copy of the whole NM CID contractor registry, every licence in every status, that we sweep from the portal once a month — so a licence that was suspended this week can still read as Active here until the next sweep. That gap is the trade-off, and the run log tells you its size: it states the date of the sweep the rows came from.

What you get in exchange is the registry as data. The portal answers one search at a time, behind a CAPTCHA, and stops counting at 300 results per search; there is no statewide download. The sweep of 2026-10-23 holds 61,240 licences — 15,616 Active, 44,422 Cancelled, 810 Revoked, 260 Suspended, 125 Inactive, 5 Inspector, 2 Expired — and a run filters that copy in memory. Every Active contractor in Albuquerque (3,754 of them), every licence expiring before the end of the quarter, or a batch of licence numbers to verify: one run each.

What you’ll need

Nothing but an Apify account.

No proxy, no API key, no CAPTCHA solver. The portal’s search form still sits behind a distorted-text image CAPTCHA (you can see it further down this page), but that is the monthly sweep’s problem, not your run’s: a run never touches the portal at all. It reads the snapshot, filters it, and charges per licence returned. There is no per-search fee.

Step 1 — Open the actor

Open New Mexico Contractor License Lookup & List Scraper (NM CID) on the Apify Store and press Try for free. The actor’s own page on this site lists its live health and pricing.

The New Mexico Contractor License Lookup listing on the Apify Store
The listing on the Apify Store. Pricing and the health record are both public.

Step 2 — Fill in the input

The input form for New Mexico Contractor License Lookup in the Apify Console
The input form, as it appears in the Apify Console.
FieldTypeRequiredWhat it does
statusesarraynoOnly return licences with one of these statuses, as NM CID writes them (Active, Cancelled, Inactive, Revoked, Suspended…). Empty means every status.
citystringnoOnly return licences whose business city is exactly this city (case-insensitive, e.g. Albuquerque).
zipCodestringnoOnly return licences whose business ZIP starts with this — 871 for a whole prefix, 87110 for one ZIP.
expiresAfterstringnoOnly licences expiring on or after this date (YYYY-MM-DD).
expiresBeforestringnoOnly licences expiring on or before this date (YYYY-MM-DD).
businessNamestringnoOnly licences whose business name contains this text (e.g. Smith).
businessNamesarraynoThe same, as a batch: one lookup per entry, in one run.
licenseNumberstringnoExact NM CID licence number. Returns that one licence.
licenseNumbersarraynoThe same, as a batch.
maxResultsintegernoCap on rows returned. Default 500, maximum 100,000. In a batch it applies per entry.

Every field is optional, and the filters combine: each one you set must hold.

The fork in the road is whether you give a name or a number. Leave both blank and the run is a statewide export of whatever the other filters allow — statuses: ["Active"] with nothing else is the 15,616 Active licences, capped by maxResults. Give a licenseNumber and you are asking a closed question: does this licence exist, and what is its status as of the sweep? Give a businessName and it’s a contains match against the state’s own spelling, so Smith finds ADAMS & SMITH, INC. too.

maxResults is the field to watch. The default is 500, which is a sample, not a statewide list: there are 3,754 Active licences in Albuquerque alone, so a city export needs maxResults raised to cover it. In a batch the cap is per entry, so one common name cannot eat the share of the others.

Two more things about the filters. city is an exact match on the city as filed, so a suburb is its own string (Rio Rancho is not Albuquerque). And once you set an expiry window, a licence without a readable expiry date is left out of it rather than guessed at.

A working input:

{
  "statuses": ["Active"],
  "city": "Albuquerque",
  "maxResults": 5000
}

Step 3 — Run it

Press Start. There is no portal, no CAPTCHA and no paging in the run, so it is quick: load the snapshot, filter it, push the rows.

Zero rows is a real answer — the registry has nothing matching those filters. Before blaming the actor, check the usual suspects: a city spelled differently from how the state filed it, a city and zipCode that don’t overlap, a statuses value that isn’t one of NM CID’s words, a licence number with a typo.

The one failure you might see is a free notice row. If the snapshot is missing, or more than 45 days old, the run does not serve old data and does not fall back to a live search: it returns a single row with notice_type: "blocked" saying the roster is temporarily unavailable, charges nothing, and asks you to re-run later. A date in expiresAfter / expiresBefore that isn’t YYYY-MM-DD gets a free notice row too, saying so.

Step 4 — Read the output

Each run returns a labelled table, not raw JSON:

The output fields returned by New Mexico Contractor License Lookup & List Scraper (NM CID)
The output view — every field the actor returns, named and typed.

Every row looks like this:

{
  "state": "NM",
  "license_number": "396966",
  "business_name": "ADAMS & SMITH, INC.",
  "person_name": null,
  "license_type": "Contractor",
  "status": "Active",
  "issue_date": null,
  "expiration_date": "12/31/2027",
  "city": "LINDON",
  "county": null,
  "address": "1380 W CENTER ST",
  "zip_code": "84042",
  "phone": null,
  "bond_amount": null,
  "bond_company": null,
  "insurance_company": null,
  "matched_by": "statewide",
  "source_url": "https://public.psiexams.com/search.jsp"
}
FieldExample valueMeaning
stateNMAlways ‘NM’ for this actor
license_number396966NM CID contractor license number
statusActiveLicense status (e.g. Active, Cancelled)
license_typeContractorAlways ‘Contractor’ (NM CID’s contractor company category)
business_nameADAMS & SMITH, INC.Licensed business/company name
address1380 W CENTER STPrincipal place of business street address
cityLINDONBusiness city
zip_code84042Business ZIP code
expiration_date12/31/2027License expiry date
matched_bystatewideHow the row was selected: statewide, business_name or license_number

Licence number, business name, status and expiry are filled on every row; address, city and ZIP on about 99.9% of them. status and expiration_date are what most people came for, and the sweep date in the run log tells you how far to trust them — they are the registry’s answer on that date, not today’s. license_number is the column to key on afterwards; business names get re-filed and re-spelled, licence numbers don’t.

Watch the nulls. phone, email, county, bond_amount, bond_company, insurance_company, issue_date and person_name are null on every row. That isn’t missing data on our side: the portal’s search results don’t carry them, so no run will return them. source_url points at the search portal rather than the individual record because the portal has no per-record URL.

And expect out-of-state addresses. The registry lists the business address as filed, so the sample row is a New Mexico licence held by a company in Lindon, Utah — and among Active licences, El Paso (362) is the fifth most common city, after Albuquerque, Santa Fe, Las Cruces and Rio Rancho. That’s the source telling the truth, not a parsing bug.

Step 5 — Export it

Open the Dataset tab and export to CSV, JSON, or Excel — or pull the same rows from the API, which is what you want if this is going to run on a schedule.

What it costs

One event: $0.004 per licence returned, from 2026-11-10 (until then, $0.01 per licence). There is no per-search fee. A run that matches nothing costs nothing, and a free notice row is never charged. At $0.004, 1,000 licences is $4.00 and the 3,754 Active Albuquerque licences are $15.02. Apify’s platform compute is billed separately, per your plan.

Where the data comes from

The New Mexico Construction Industries Division (CID) contractor registry isn’t hosted by the state at all — it lives on PSI Exams, the testing vendor that runs the state’s licensing e-services, at public.psiexams.com. It’s an old Java web app: a plain HTML form POST with no API, no per-record URLs, a distorted-text image CAPTCHA (Java’s SimpleCaptcha) on the search, and a cap of 300 results per search.

That shape is why runs read a snapshot instead of the portal. Once a month our producer sweeps the registry end to end, reusing one solved CAPTCHA answer across the session’s searches and narrowing licence-number prefixes until every search fits under the 300-result cap, and publishes the result. A run reads the latest copy; if that copy is missing or more than 45 days old, you get the free notice row rather than stale data. What “verified” means explains how the actor itself is checked.

See it used

If the contractor turns out not to be a New Mexico one, or you don’t yet know which state they’re licensed in, reach for Multi-State Contractor & Trade License Lookup instead — it checks the same contractor across several states in one run. And if you want the same shape of bulk export for another state, Virginia Contractor License Lookup (DPOR Bulk) does it from DPOR’s published files.

Last updated 2026-10-23