# Texas Ag & Timber Exemptions - Sales-Tax Registrations (`j0401/tx-ag-timber-exemptions`) Actor

Texas Comptroller agricultural and timber sales-tax exemption registrations (HB 268, public open data, 419,895 rows): exemption number, taxpayer and mailing address, status, and true issue / expiration date ranges. The registration list, not land valuations.

- **URL**: https://apify.com/j0401/tx-ag-timber-exemptions.md
- **Developed by:** [Wenhao Yang](https://apify.com/j0401) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.03 / 1,000 texas ag & timber exemption records

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?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Texas Ag & Timber Exemptions - Sales-Tax Registration Register

Every agricultural and timber **sales-tax exemption registration** on the
Texas Comptroller's own open data portal (HB 268, 2012). This is the
Comptroller's registration list - the people and entities licensed to claim the
agricultural and timber production sales-tax exemption - **not** the county
appraisal district's agricultural-use land valuation, which is a different
source with different data. **~420k registrations, one row each, refreshed
daily.**

### Low cost

**From $0.00005 per record, down to $0.00003 at Gold.** Pay only for the
records you actually receive - the whole register stays queryable, you are
never billed for the scan behind it.

### What you get

- **The exemption** - its number, its status (active or inactive), when it was
  issued and when it expires
- **The taxpayer** - the name on the exemption, as recorded, with their full
  mailing address including the ZIP+4
- **The use address**, where the Comptroller recorded one separately from the
  mailing address

This is the State's own list of who holds a commercial agricultural or timber
sales-tax exemption registration, where they can be reached, and when it
lapses.

### Modes

- **rows** (default) - exemption records matching your filters
- **aggregate** - counts by status or by state

### Filters

Exemption number, taxpayer name, status, city, state, ZIP, and **true date
ranges** for issued and expiring dates.

### Example inputs

**Active exemptions in one city**

```json
{ "status": "ACTIVE", "city": "HOUSTON", "maxResults": 25 }
```

**What lapses this year** - real date ranges, not year granularity.

```json
{ "expiringAfter": "2026-01-01", "expiringBefore": "2026-12-31", "maxResults": 25 }
```

**Newly issued exemptions in a window**

```json
{ "issuedFrom": "2026-09-01", "issuedTo": "2026-09-30" }
```

**One exemption by number**

```json
{ "exemptionNumber": "32108239230" }
```

### Example output

**An active exemption in Houston** - `status=ACTIVE`, `city=HOUSTON`:

```json
{
 "platform": "tx-ag-timber",
 "source": "tx-comptroller-ag-timber",
 "corpus": "exemptions",
 "recordKind": "exemption",
 "mode": "rows",
 "groupKey": "",
 "groupCount": "",
 "groupBy": "",
 "exemptionNumber": "32108239230",
 "taxpayerName": "COLTON SCOTT",
 "status": "ACTIVE",
 "issueDate": "2026-09-23",
 "expirationDate": "2027-12-31",
 "masterStreetAddress": "6323 DARLINGHURST DR",
 "masterCity": "HOUSTON",
 "masterState": "TX",
 "masterZip": "77085",
 "masterZip4": "3256",
 "agriculturalAddress": "",
 "agriculturalCity": "",
 "agriculturalState": "",
 "agriculturalZip": "",
 "agriculturalZip4": "",
 "sourceUpdatedAt": "2026-09-24"
}
```

**`mode=aggregate`, `groupBy=status`** - the register is overwhelmingly active:

```
ACTIVE    ~419k
INACTIVE    1,261
```

**`mode=aggregate`, `groupBy=state`** - where holders are mailing from:

```
TX     406,097
OK       4,870
NM       1,812
AR       1,747
LA       1,733
```

### Notes on the data, from the source

- **There is not really a second address, and this actor does not pretend
  otherwise.** The taxpayer mailing block (street / city / state / ZIP) is
  populated on essentially every row; the agricultural-use block is populated
  on only **~54.5k rows (13%)**, and on exactly **one** of those does the street
  differ from the mailing street. Where it exists, it is the same address. It is
  exposed as-is and is never sold as a distinguishing field.
- **Date filters here are true ranges.** `permit_issue_date` and
  `permit_expiration_date` are real date columns on this source - unlike most
  government registers, which store dates as text and force year granularity.
- **`permit_status` has exactly two values**, ACTIVE and INACTIVE, matched
  exactly.
- **Rows come back newest-first, and rows with no issue date are last.** 176
  rows carry no issue date; they are pinned to the end rather than heading a
  page.

### Notes

- Public open data from data.tx.gov (Texas Comptroller). No login, no scraping.
- The register is refreshed daily; every record carries `sourceUpdatedAt` = the
  **newest permit issue date** in the feed, so you can see how current it is
  without running anything.
- Charges are metered per record delivered, so a targeted query costs a
  fraction of a cent.

# Actor input Schema

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

rows = records matching your filters (default). aggregate = one count row per group.

## `groupBy` (type: `string`):

Aggregate dimension, only used when mode=aggregate.

## `exemptionNumber` (type: `string`):

Exact exemption number. Blank = any.

## `taxpayerName` (type: `string`):

Taxpayer-name substring, e.g. 'RANCH'. Blank = any.

## `status` (type: `string`):

Exact permit status. Blank = both.

## `city` (type: `string`):

City substring, e.g. 'HOUSTON'. Blank = any.

## `state` (type: `string`):

Two-letter state. Blank = any.

## `zip` (type: `string`):

ZIP prefix, e.g. '770'. Blank = any.

## `issuedFrom` (type: `string`):

YYYY-MM-DD. True date range - this source has real date columns. Blank = any.

## `issuedTo` (type: `string`):

YYYY-MM-DD. Blank = any.

## `expiringAfter` (type: `string`):

YYYY-MM-DD. Blank = any.

## `expiringBefore` (type: `string`):

YYYY-MM-DD. Blank = any.

## `maxResults` (type: `integer`):

Cap records returned for this run. Default 50 keeps the daily auto-test fast. 0 = no cap (the full matching slice, up to 10,000).

## Actor input object example

```json
{
  "mode": "rows",
  "groupBy": "status",
  "exemptionNumber": "",
  "taxpayerName": "",
  "status": "",
  "city": "",
  "state": "",
  "zip": "",
  "issuedFrom": "",
  "issuedTo": "",
  "expiringAfter": "",
  "expiringBefore": "",
  "maxResults": 50
}
```

# Actor output Schema

## `recordsUrl` (type: `string`):

Texas Ag & Timber Exemptions - Land Use Register - as JSON

## `datasetUrl` (type: `string`):

No description

## `runUrl` (type: `string`):

No description

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("j0401/tx-ag-timber-exemptions").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("j0401/tx-ag-timber-exemptions").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 '{}' |
apify call j0401/tx-ag-timber-exemptions --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,j0401/tx-ag-timber-exemptions"
        }
    }
}
```

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/QNtqUQ9u5NONm2WS3/builds/hEUeT6eeDlg6PhfoS/openapi.json
