TX Sales Tax Permits - Active Permit Holders avatar

TX Sales Tax Permits - Active Permit Holders

Pricing

from $0.03 / 1,000 tx sales tax permit records

Go to Apify Store
TX Sales Tax Permits - Active Permit Holders

TX Sales Tax Permits - Active Permit Holders

Texas Comptroller active sales-tax permit register (public data, 887k permits across 702k taxpayers): outlet name and address, NAICS industry code, city-limits flag, permit and first-sales dates - plus the taxpayer's own registration address and county.

Pricing

from $0.03 / 1,000 tx sales tax permit records

Rating

0.0

(0)

Developer

Wenhao Yang

Wenhao Yang

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Categories

Share

Low cost

From $0.00005 per record, down to $0.00003 at Gold - pay per record delivered, and nothing for the query. Every active sales-tax permit in Texas, billed by the permit.

The Texas Comptroller's register of businesses permitted to collect sales tax: 887,244 permits held by 702,193 taxpayers, refreshed daily.

What you get

Each row is one outlet permit - a business can hold many.

whotaxpayer number and registered name, plus the outlet's trade name and number
where it sellsoutlet street address, city, state, ZIP, county, and whether it sits inside city limits
where it is registeredthe taxpayer's own mailing address, city, state, ZIP and county
industrythe outlet's NAICS code
whenpermit issue date and first-sales date

The two addresses are the point

Every row carries two addresses, and they are not copies of each other. One is where the business is registered; the other is where this particular permit is. They disagree on 518,696 rows for the street address - over half the register - and on 259,054 for the county, of which 162,162 are a genuine county-to-county difference (the rest are rows where the taxpayer's county was never reported).

That gap is the product: "registered in Austin, selling in Houston" is answerable here, and a dataset carrying one address would silently tell you the wrong city for more than half of Texas permits.

Modes

  • permits (default) - individual permits, newest permit first
  • aggregate - one count row per group: by county, NAICS sector, organization type, city-limits status, or permit year

Filter by taxpayer number, business name, city, ZIP, county (by name or Comptroller code), NAICS industry, inside/outside city limits, and issue / first-sales dates.

Example inputs

Every outlet permit one taxpayer holds - taxpayerNumber is the exact 11-digit Comptroller number, so one call returns that business's whole permit list.

{ "taxpayerNumber": "17515166332", "maxResults": 10 }

Full-service restaurants in Houston - naicsCode takes the 6-digit industry, city is a case-insensitive substring.

{ "city": "HOUSTON", "naicsCode": "722511", "maxResults": 10 }

Retail outlets inside Harris County city limits - countyCode=101 is Harris, inCityLimits=Y is the city-limits flag.

{ "countyCode": "101", "inCityLimits": "Y", "maxResults": 10 }

The industry mix - aggregate=true and groupBy=naicsSector roll the register up by NAICS sector.

{ "aggregate": true, "groupBy": "naicsSector" }

Why this is hard

The county is a code, and the codes are numbered the hard way. The Comptroller numbers Texas's 254 counties by name with the spaces removed - so LA SALLE collates as LASALLE and lands after Lampasas, not up with the other La- counties. Sorting the 254 names alphabetically puts ten of them in the wrong slot, which is how a county lookup quietly returns the neighbouring county's permits. This register resolves the code to a county name against a table checked both ways, and the aggregate carries the name alongside the code.

96,896 permit rows (23,820 taxpayers) have no county reported - the code comes through as 000. That is not a missing value to paper over; it is the register saying the county was not given, and it is kept distinguishable from a real county rather than folded into one.

The industry code is a number, not a string. It looks like a text identifier and behaves like one to a reader, but treating it as text fails at the source - every text operation on it is rejected. Groups and prefixes have to be expressed numerically.

And the organization-type field is 62 two-letter codes with no legend anywhere in the dataset. There is no published mapping from CL / IS / CT to anything a buyer could act on, so it is offered only as a count dimension - never as a filter you would have to guess the codes for.

Output

One schema in every mode: each record carries the full field set, empty where the source has nothing, and dates arrive as YYYY-MM-DD. Every record carries sourceUpdatedAt, the register's own last-refresh timestamp. Aggregate rows use the same schema, with groupKey / groupCount filled.

Example output

aggregate=true, groupBy=naicsSector - one row per industry sector; sector 45 is retail trade. Aggregate rows keep the permit schema, with groupKey / groupCount / groupBy filled and the permit fields empty:

{
"firstSalesDate": "",
"inCityLimits": "",
"naicsCode": "",
"outletAddress": "",
"outletCity": "",
"outletCountyCode": "",
"outletCountyName": "",
"outletName": "",
"outletNumber": "",
"outletState": "",
"outletZip": "",
"permitIssueDate": "",
"sourceUpdatedAt": "2026-09-19T08:05:21Z",
"taxpayerAddress": "",
"taxpayerCity": "",
"taxpayerCountyCode": "",
"taxpayerCountyName": "",
"taxpayerId": "",
"taxpayerName": "",
"taxpayerState": "",
"taxpayerZip": "",
"platform": "tx-sales-tax-permits",
"source": "tx-comptroller-sales-tax-permits",
"groupKey": "45",
"groupCount": "191979",
"groupBy": "naicsSector"
}

Notes

  • Public open data from the Texas Comptroller. No login, no scraping.
  • Charges are metered per record delivered, so a single taxpayer lookup costs a fraction of a cent.