# Texas Business Scraper (`normdata/texas-business-scraper`) Actor

Search 3.4M+ registered Texas businesses from the state franchise-tax open data: name, entity type, county, city, NAICS, SOS file number, charter date and status. Build a filtered B2B lead or KYB list, look up a company for its officers and registered agent, or monitor new registrations.

- **URL**: https://apify.com/normdata/texas-business-scraper.md
- **Developed by:** [Norm Data](https://apify.com/normdata) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $11.90 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

![Norm Data](https://i.ibb.co/rGbhM5Y8/Chat-GPT-Image-Sep-8-2026-02-20-50-PM.png)

## Texas Business Scraper

Search **3.4 million registered Texas businesses** from the state's official open data with no
API key and no login. Every entity on the **franchise-tax register**: taxpayer and Secretary of
State file number, entity type, county, city, **NAICS industry**, charter (formation) date,
**right-to-transact status** and **sales-tax-permit** standing. Build a filtered **B2B lead** or
**KYB** list, look up a company for its **officers and registered agent**, or run a **monitor**
for newly registered Texas businesses.

Here is one real row (search, no enrichment):

```json
{
  "taxpayer_number": "32107661392",
  "name": "TC ADVISORS LLC",
  "organizational_type_code": "CL",
  "entity_category": "llc",
  "entity_type": "Limited liability company",
  "is_llc": true,
  "sos_file_number": "0806754854",
  "sos_charter_date": "2026-08-19",
  "right_to_transact": "Active",
  "is_active": true,
  "responsibility_beginning_date": "2026-08-19",
  "entity_age_years": 0,
  "is_new": true,
  "is_out_of_state": false,
  "address": "2007 ENCINO CIR # B, AUSTIN, TX, 78723",
  "city": "AUSTIN",
  "state": "TX",
  "zip": "78723",
  "county_code": "227",
  "county": "Travis",
  "naics_code": "541611",
  "naics_industry": "Professional, scientific, and technical services",
  "comptroller_url": "https://comptroller.texas.gov/taxes/franchise/account-status/search",
  "scraped_at": "2026-09-10T23:55:26.226Z"
}
```

With `includeOfficers` (always on for look-up) each row also carries `registered_agent_name`,
`registered_agent_address`, `mailing_address`, `sos_status`, `report_year` and an `officers`
array of `{ name, title, year, address }`.

### What it does

Reads the Texas franchise-tax register from `data.texas.gov` (Socrata, keyless), decodes the
county and organizational-type codes, and normalizes every entity into a flat row. Three modes:

- **Search** filters the register by name, entity category, county, city, ZIP, NAICS,
  right-to-transact status, out-of-state, charter date or franchise-responsibility date, and
  optionally whether the entity also holds a sales-tax permit.
- **Look up** resolves 11-digit taxpayer numbers, 9-digit EIN/FEI numbers, SOS file numbers or
  names, one row per identifier, always with officers and the registered agent. Unresolved
  identifiers come back as an `error` row.
- **Monitor** returns entities with a new franchise-tax responsibility or a new sales-tax
  permit since a date, each tagged with the change type.

Missing source values are returned as `null`, never invented.

### Why this scraper

- **List building, not just look-up.** Filter 3.4M entities by county, city, ZIP, NAICS
  industry, entity type, charter date and status. Other Texas business Actors only resolve
  names you already have.
- **Officers and registered agent.** The officers/directors array with titles and the
  registered agent, pulled from the Comptroller account-status service, as an opt-in
  enrichment.
- **Right-to-transact and status.** `right_to_transact`, `is_active` and the SOS status, so you
  can drop forfeited or not-in-good-standing entities from a lead list.
- **A real new-business monitor.** New franchise-tax registrations plus new sales-tax permits
  since a date, tagged, with standard per-result billing and no lookback cap.
- **Decoded, not raw.** County codes to county names, organizational-type codes to LLC /
  corporation / partnership, NAICS to an industry sector, plus `entity_age_years` and an
  `is_new` flag.
- **No API key, no login, no browser.** The base register is a keyless Socrata API and the
  detail service is a keyless JSON endpoint.

### How it compares

| Capability | This actor | Other Texas business scrapers on Apify |
|---|:--:|:--:|
| Look up by taxpayer / EIN / SOS file number or name | yes | yes |
| Officers + registered agent | yes | some |
| **Filtered list by county / city / ZIP / NAICS / status** | **yes** | **no** |
| **Charter-date and franchise-responsibility-date ranges** | **yes** | **no** |
| Sales-tax-permit standing + outlet count | yes | rare |
| New-business monitor (franchise + sales-tax permit) | yes | some |
| Decoded county, entity type and industry | yes | rare |
| Declared dataset schema + free-plan preview | yes | rare |

### Use cases

- **B2B lead generation.** New LLCs in a county and industry, with address and, on enrichment,
  the officers and agent.
- **KYB and onboarding.** Confirm a Texas counterparty is registered and in good standing, and
  keep the SOS file number, charter date and officers on file.
- **Sales territory and market research.** Count businesses by county, city or NAICS, or find
  multi-outlet operators.
- **New-business monitoring.** Schedule the monitor mode for a weekly feed of newly registered
  entities.
- **Skip tracing and investigations.** Resolve an entity to its registered agent and officer
  addresses.
- **Data enrichment.** Attach Texas registration status and NAICS to CRM or vendor records.

### Quickstart

Search: new consulting LLCs in Austin chartered since 2025.

```json
{
  "mode": "search",
  "city": ["AUSTIN"],
  "entityCategory": ["llc"],
  "naics": ["5416"],
  "charteredAfter": "2025-01-01",
  "maxItems": 200
}
```

Search with officers, restaurants in Harris county that also hold a sales-tax permit:

```json
{ "mode": "search", "county": ["Harris"], "naics": ["722"], "hasSalesTaxPermit": true, "includeOfficers": true, "maxItems": 500 }
```

Look up a batch:

```json
{ "mode": "lookup", "identifiers": ["32014898749", "WHATABURGER", "0800333885"] }
```

Monitor new registrations in the last 2 weeks:

```json
{ "mode": "monitor", "since": "14 days", "events": ["new_franchise_taxpayer", "new_sales_tax_permit"], "maxItems": 1000 }
```

### Input reference

| Field | Applies to | Description |
|---|---|---|
| `maxItems` | all | Ceiling on rows written. |
| `mode` | all | `search`, `lookup` or `monitor`. |
| `name` | search | Taxpayer (legal) name contains. |
| `entityCategory` | search | `llc`, `corporation`, `partnership`, `association`, `trust`. |
| `organizationalType` | search | Exact two-letter Comptroller org-type codes. |
| `county` | search | County name(s) or numeric code(s). |
| `city` | search | Taxpayer city, exact (case-insensitive). |
| `zip` | search | ZIP prefix(es). |
| `naics` | search | NAICS code prefix(es). |
| `rightToTransact` | search | `any`, `active`, `not_active`. |
| `outOfStateOnly` | search | Taxpayer address outside Texas. |
| `hasSalesTaxPermit` | search | Also holds an active sales-tax permit. |
| `charteredAfter` / `charteredBefore` | search | SOS charter-date window (ISO). |
| `responsibleAfter` / `responsibleBefore` | search | Franchise-responsibility-date window (ISO). |
| `includeOfficers` | search | Add officers + registered agent + SOS detail. Billed separately. |
| `identifiers` | lookup | Taxpayer numbers, EIN/FEI numbers, SOS file numbers, or names. |
| `since` | monitor | ISO date or `"30 days"` / `"2 weeks"`. |
| `events` | monitor | `new_franchise_taxpayer`, `new_sales_tax_permit`. |
| `appToken` | all | Optional free Socrata token for large runs. |

### Output reference (selected)

| Field | Description |
|---|---|
| `taxpayer_number` / `sos_file_number` | Identifiers. |
| `name` | Legal (taxpayer) name. |
| `organizational_type_code` / `entity_category` / `entity_type` / `is_llc` / `is_corporation` / `is_partnership` | Entity type. |
| `sos_charter_date` / `responsibility_beginning_date` / `entity_age_years` / `is_new` | Timing. |
| `right_to_transact` / `is_active` / `sos_status_code` | Standing. |
| `is_out_of_state` | Domicile. |
| `address` / `city` / `state` / `zip` / `county_code` / `county` | Location. |
| `naics_code` / `naics_industry` | Industry (present on about a quarter of records). |
| `exempt_reason_code` / `exempt_begin_date` | Franchise-tax exemption (nonprofits and similar). |
| `has_sales_tax_permit` / `sales_tax_outlet_count` | Sales-tax standing (when checked). |
| `fei_number` / `dba_name` / `state_of_formation` / `sos_status` / `registered_agent_name` / `registered_agent_address` / `mailing_address` / `report_year` / `officers` / `officer_count` | Added only with `includeOfficers` (always on in look-up). |
| `change_type` | Monitor mode change tag. |
| `query` / `error` | Set on an unresolved look-up row. |
| `comptroller_url` / `scraped_at` | The Comptroller search page and a collection timestamp. |

### Run via API and CLI

```bash
curl -X POST "https://api.apify.com/v2/acts/USERNAME~texas-business-scraper/run-sync-get-dataset-items?token=<TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"mode":"lookup","identifiers":["32014898749"]}'
```

```bash
apify call USERNAME/texas-business-scraper --input '{"mode":"search","county":["Travis"],"entityCategory":["llc"],"maxItems":1000}'
```

### Fetch results

```bash
curl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&clean=true&format=json"
curl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&clean=true&format=csv"
```

### Billing and limits

- **Pay per result.** Billed per entity row written.
- **Officer enrichment** adds a separate event, charged only when officer data is found. Look up
  mode always enriches.
- **No charge on failure.** A run that produces zero rows fails with a message and is not
  billed.
- An unresolved look-up identifier still writes one `error: "not found"` row and is billed as a
  base row.
- **Free Apify plans** run the built-in 10-row sample only.
- The base register is a Socrata API capped at 50,000 rows per query; this Actor pages it in
  2,000-row chunks, so a large filtered run is paced by the source, not by any per-record work.

### FAQ and troubleshooting

**Do I need an API key?** No. `data.texas.gov` and the Comptroller account-status service are
both keyless. A free Socrata token only raises the shared rate limit for very large runs.

**Why did my run return zero rows?** No entity matched the filters. Loosen them or widen the
date ranges. A zero-row run fails and is not billed.

**Why is `naics_industry` sometimes empty?** The franchise-tax register carries a NAICS code on
only part of its records. When it is present the Actor maps it to an industry sector.

**Why is `sos_charter_date` in the future for a new entity?** The state forward-dates some new
filings. `entity_age_years` is clamped to zero in that case.

**What is "right to transact"?** Whether the entity currently has the right to conduct business
in Texas. Entities that have forfeited it for unpaid franchise tax show `not active`.

**Does this cover the Texas Secretary of State corporate registry (SOSDirect)?** No. SOSDirect
is a paid, per-search service. This Actor uses the free franchise-tax and sales-tax open data
plus the free Comptroller account-status service.

**How current is the data?** The open-data files refresh on the state's schedule, roughly
weekly. It is not real time.

**Is this an official Texas tool?** No. Independent, not affiliated with the Texas Comptroller
or the Secretary of State. It reads only published open data.

### Local development

```bash
bun install
bun test                       # offline: parsing, normalisation, code decode, input logic
bun run src/main.ts            # reads storage/key_value_stores/default/INPUT.json
bun scripts/verify-live.mjs    # hits data.texas.gov + comptroller.texas.gov, checks every mode
```

# Actor input Schema

## `maxItems` (type: `integer`):

Caps how many rows this run writes. Starts at 10 for a quick sample; raise it for a full run.

## `mode` (type: `string`):

Search filters the 3.4M+ franchise-tax register into a list. Look up resolves exact identifiers or names and adds officers and the registered agent. Monitor returns businesses with a new franchise-tax responsibility or a new sales-tax permit since a date.

## `name` (type: `string`):

Match businesses whose taxpayer (legal) name contains this text.

## `entityCategory` (type: `array`):

Coarse entity category, derived from the Comptroller organizational-type code.

## `organizationalType` (type: `array`):

Advanced: exact two-letter Comptroller organizational-type codes (e.g. CL for a Texas LLC, CI for a Texas profit corporation).

## `county` (type: `array`):

Texas county name(s) (e.g. Travis, Harris, Dallas) or numeric county code(s).

## `city` (type: `array`):

Taxpayer city, matched exactly (case-insensitive). Add several for an OR match.

## `zip` (type: `array`):

One or more ZIP prefixes, e.g. 787 for the Austin area.

## `naics` (type: `array`):

Industry filter by NAICS code prefix, e.g. 23 for construction, 5416 for consulting, 722 for food service. NAICS is present on a subset of records.

## `rightToTransact` (type: `string`):

Filter by whether the entity currently has the right to transact business in Texas.

## `outOfStateOnly` (type: `boolean`):

Only entities whose taxpayer address is outside Texas.

## `hasSalesTaxPermit` (type: `boolean`):

Set true for entities that also hold an active Texas sales-tax permit (retail / taxable sales), or false for those that do not. Adds a lookup against the sales-tax-permit register.

## `charteredAfter` (type: `string`):

ISO date (2026-01-01). Only entities whose SOS charter (formation) date is on or after this.

## `charteredBefore` (type: `string`):

ISO date. Only entities chartered on or before this.

## `responsibleAfter` (type: `string`):

ISO date. Only entities that became liable for franchise tax on or after this.

## `responsibleBefore` (type: `string`):

ISO date.

## `includeOfficers` (type: `boolean`):

Add the officers/directors array, the registered agent, the mailing address and the SOS registration status for each row, from the Comptroller account-status service. One extra request per row. Billed as a separate event, only when officer data is found. Look up mode always includes this.

## `identifiers` (type: `array`):

11-digit Texas taxpayer numbers, 9-digit federal EIN/FEI numbers, SOS file numbers, or company names. Names may match several entities.

## `since` (type: `string`):

ISO date (2026-09-01) or a window like "30 days" / "2 weeks". Monitor returns entities with a matching change on or after this.

## `events` (type: `array`):

Which new-business signals to include. Leave empty for both.

## `appToken` (type: `string`):

A free data.texas.gov (Socrata) app token raises the shared rate limit. Only needed for very large runs.

## Actor input object example

```json
{
  "maxItems": 10,
  "mode": "search",
  "city": [
    "AUSTIN"
  ],
  "rightToTransact": "any",
  "outOfStateOnly": false,
  "includeOfficers": false
}
```

# Actor output Schema

## `results` (type: `string`):

One dataset row per Texas business entity (or per look-up identifier), with taxpayer and SOS file number, entity type, county, city, NAICS industry, charter date, right-to-transact status, sales-tax-permit standing and, when requested, officers and the registered agent.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "maxItems": 10,
    "mode": "search",
    "city": [
        "AUSTIN"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("normdata/texas-business-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "maxItems": 10,
    "mode": "search",
    "city": ["AUSTIN"],
}

# Run the Actor and wait for it to finish
run = client.actor("normdata/texas-business-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "maxItems": 10,
  "mode": "search",
  "city": [
    "AUSTIN"
  ]
}' |
apify call normdata/texas-business-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,normdata/texas-business-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/e32GShwOndhVaeHt5/builds/Cs33GViBqoCPoiEw1/openapi.json
