← Guides

How-to

How to run Texas Contractor & Trade License Lookup & Export (TDLR)

Step-by-step: the exact input, what each field does, and the rows that come back from TDLR (Socrata), for one licence or a statewide export by licence type.

You have a Texas trade shop — an electrician, an A/C crew — and you need the licence on the record before they start work, or before you pay them. Start with the thing most people get wrong: Texas has no statewide general-contractor licence. The state licenses trades, through the Texas Department of Licensing & Regulation (TDLR). “Is this contractor licensed in Texas” is not a question the state can answer; “does this shop hold a current TDLR electrical or A/C licence” is. The manual way to answer it is TDLR’s own licence search: a box, a button, one record at a time. For a single lookup that’s a minute and it’s free, so do that. What this actor is for is the twelfth lookup, and the one after renewal season, and the list of subs sitting in a spreadsheet that has to be re-checked every year. Since 2026-10-07 it also exports TDLR’s contractor licences by type: leave the search empty and you get every Electrical, A/C, Appliance Installation, Electrical Sign and Elevator Contractor in the state, 36,312 licences when we ran it that day.

What you’ll need

Nothing but an Apify account. The actor talks to TDLR (Socrata) directly.

No API key, no proxy, no CAPTCHA credits, no login. Texas publishes the TDLR licensee file as an official Socrata open-data dataset on data.texas.gov: public JSON, documented, free to query, and filtered server-side with SoQL. Nothing is being worked around here, so there is no third-party cost inside a run and nothing for you to sign up for. (A Socrata app token would raise the shared rate limit, but the actor runs unauthenticated and doesn’t need one at this volume.)

Step 1: Open the actor

Open Texas Contractor & Trade License Lookup & Export (TDLR) on the Apify Store and press Try for free. The actor’s own page on this site lists its live health and pricing.

The Texas Contractor & Trade License Lookup & Export (TDLR) listing on the Apify Store
The listing on the Apify Store. Pricing and the nightly health record are both public.

Step 2: Fill in the input

The input form for Texas Contractor & Trade License Lookup & Export (TDLR) in the Apify Console
The input form, as it appears in the Apify Console.
FieldTypeRequiredWhat it does
querystringnoA Texas TDLR license number, business name, or owner name. Searches exact license number, business-name substring and owner-name substring, unioned and deduped by license #. Leave this and queries empty to run a statewide export by licence type instead.
queriesarraynoLook up many in ONE run. Takes the same values as query. (default [])
licenseType / licenseTypesstring / arraynoStatewide export only: TDLR’s own type name, e.g. ‘Electrical Contractor’ or ‘A/C Contractor’. Empty = the five TDLR contractor types.
county / countiesstring / arraynoStatewide export only: business county, e.g. ‘Travis’ or ‘Harris County’.
city / citiesstring / arraynoStatewide export only: business city, e.g. ‘Austin’. A/C Contractor rows carry no city, so they never match.
zip / zipsstring / arraynoStatewide export only: 5-digit business ZIP. Same caveat as city.
excludeExpiredbooleannoStatewide export only: keep licences expiring today or later. (default false)
expiresAfter / expiresBeforestringnoStatewide export only: YYYY-MM-DD window on the expiration date, for a renewal list.
maxResultsintegernoSearch: cap PER ENTRY (default 50). Statewide export: cap on the whole export (default 500, up to 100,000).

When you search, query is the field people get wrong, because it does several jobs at once. The actor runs your string as an exact match against TDLR’s licence number, then as a substring match against the business name, then against the owner name, and unions the results. So 11484 verifies one specific licence, while ELECTRIC returns every licensee whose registered business or owner name happens to contain that word, which in Texas is a lot of them. A short, common word is a broad survey, not a verification. If you’re checking a specific shop, paste the name as TDLR spelled it (many licensees are filed as a person, SEAY, DANIEL, not a company), or better, paste the licence number.

maxResults is the spend cap, and it is the only thing standing between a one-word query and a bill: you are charged per row returned. Leave it at the default of 50 while you find out how broad your query really is, then widen it once you know.

A working input:

{
  "query": "ELECTRIC",
  "maxResults": 25
}

Step 3: Run it

Press Start. Rows are pushed to the dataset as they’re found, so the run log fills in as it works.

A healthy run is dull and quick. There is no browser, no login and no CAPTCHA: one Socrata call per search index, each requested at your maxResults, deduplicated on licence number and then cut to it. The input above took 2.0 seconds locally on 2026-10-07 and stopped after the business-name index, because that alone filled the 25-row cap. Note what the cap did: all 25 rows were A/C Contractor licences, because a cap takes the first rows in TDLR’s order, not the best ones.

An empty run is nearly always the query, not the actor. A licence number has to match exactly, and a name has to match the way Texas filed it: punctuation, & versus and, “SEAY, DANIEL” rather than “Daniel Seay”. Before you conclude that someone is unlicensed, drop back to a shorter fragment of the name and run it again. And remember the state-level caveat: if you’re looking for a general contractor’s Texas licence, there isn’t one to find. That is Texas, not a failed run.

Step 4: Read the output

Each run returns a labelled table, not raw JSON:

The output fields returned by Texas Contractor & Trade License Lookup & Export (TDLR)
The output view: every field the actor returns, named and typed.

Every row looks like this, a real row from the run above:

{
  "state": "TX",
  "license_number": "9637",
  "business_name": "EAGLE ELECTRIC & REFRIGERATION",
  "license_type": "A/C Contractor",
  "status": null,
  "issue_date": null,
  "expiration_date": "09/01/2026",
  "city": null,
  "county": "PECOS",
  "address": null,
  "zip_code": null,
  "phone": null,
  "person_name": "CORRAL, OSCAR LUIS",
  "matched_by": "business_name",
  "source_url": "https://www.tdlr.texas.gov/LicenseSearch/"
}
FieldExample valueMeaning
stateTXAlways ‘TX’ for this actor
license_number9637TDLR license number
business_nameEAGLE ELECTRIC & REFRIGERATIONLicensed business or licensee name
person_nameCORRAL, OSCAR LUISOwner name
license_typeA/C ContractorTDLR license type (e.g. A/C Technician, Electrical Contractor)
expiration_date09/01/2026License expiration date
countyPECOSBusiness county
matched_bybusiness_nameWhich search surfaced this row: license_number, business_name, owner_name, or statewide on an export

Most people came for expiration_date and license_type, and both need reading with care.

expiration_date is the check you can actually make in Texas, because this dataset publishes no status column. There is no “Active” / “Expired” / “Revoked” string to read; what you get is the licence, its type and the date it runs out. An in-date licence present in the feed is your evidence that TDLR holds a current record, not a statement that the licence is in good standing. The sample row is a good example: its expiry date, 09/01/2026, had already passed when we ran it. If you need a status determination, the licence number this actor hands you is what you take to TDLR’s own search. The date arrives as TDLR formats it (US month-first), not ISO, which is worth knowing before you sort a spreadsheet on it.

license_type is the one people skip and shouldn’t. A name search matches names, not trades, so a row coming back tells you TDLR licenses that name, not that they hold the licence you care about. “EAGLE ELECTRIC & REFRIGERATION” holds an A/C Contractor licence, not an electrical one.

Contact details depend entirely on the licence type. TDLR publishes address, city, ZIP and phone only for company-held types: on the 2026-10-07 export, 14,014 of 14,019 Electrical Contractor rows had a phone, while all 20,436 A/C Contractor rows and every individually held licence (A/C Technician, Master Electrician) had none. That is why the sample row above is null from city to phone. Anything TDLR doesn’t publish comes back null rather than blank or guessed.

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.

Export the whole state

Leave query and queries empty and the actor exports licences by type instead of searching. With no type given it takes TDLR’s five contractor types; our local run on 2026-10-07, with maxResults at 100000, returned all 36,312 in 7.4 seconds: 20,436 A/C Contractor, 14,019 Electrical Contractor, 830 Appliance Installation, 655 Electrical Sign and 372 Elevator Contractor. It never widens to the whole register, which is about a million rows and mostly individual tradespeople.

Narrow it with the other fields. {"licenseType": "Electrical Contractor", "county": "Travis"} returned 479 licences that day, and Gregg County returned 69, every one with a street address and a phone. Add excludeExpired to drop lapsed licences (3,885 of the 36,312 had an expiry date before 2026-10-07), or set expiresAfter and expiresBefore for a renewal-season list. Leave maxResults at its default and an export stops at 500 rows, with a log line stating how many matched.

One thing an export does not do is deduplicate: TDLR reuses licence numbers across types, so the 36,312 rows carry 32,598 distinct numbers. Key your own table on licence number plus type.

What it costs

$0.004 per matched licence: 100 verified records is $0.40, 1,000 is $4.00. You pay per row returned, so a search that finds nothing is free. The Travis County electrical contractors are $1.92, and the full five-type export of 36,312 licences is $145.25. Apify’s platform compute is billed separately on your plan, and there is no third-party cost inside the run because the source is a free public API. In practice, verifying one licence number costs a fraction of a cent; the runs that cost money are a one-word name search or an export with maxResults left wide open.

Where the data comes from

This reads TDLR (Socrata) directly. The target is Socrata SODA JSON API (data.texas.gov, TDLR licensees), filtered server-side with SoQL. Every night a canary runs this actor against that live source and diffs the result against a frozen fixture: what “verified” means.

Be straight about this one: it is the easiest tier there is. Texas puts the TDLR licensee file on data.texas.gov deliberately, as a documented Socrata dataset with an open JSON API, no anti-bot and no gate. If you’re comfortable writing a SoQL $where clause you can query it yourself, for free, this afternoon, or export a filtered view from the dataset page. What you’d be paying for here isn’t access, it’s the shape of what comes out: the three searches fired for you, TDLR’s column names mapped onto the same licence record every other actor in this suite returns, nulls where Texas publishes nothing rather than empty strings, and a nightly canary that notices when the state renames a column before your pipeline does.

See it used

Find Texas Electricians by Company Name shortlists Texas electrical licences by company name, and now by county with the export.

Nothing in Texas is one-state forever. If a sub could be registered anywhere and you don’t want to guess the board, Multi-State Contractor & Trade License Lookup runs the same query across Washington, Oregon, Texas and Connecticut in a single run. If what you want is a Texas lead list rather than a licence check, Texas Contractor Directory & Leads Scraper is the sibling built for that job. And if the job is a Florida licence rather than a Texas one, Florida Contractor License Lookup hits DBPR, which (unlike TDLR’s open-data feed) does publish a status column.

Last updated 2026-10-07