# TX Disabled Veteran (DV) HUB Vendors (NIGP, County) (`j0401/tx-hub-certified`) Actor

Texas Comptroller HUB directory - best for disabled-veteran (DV) HUB vendors. Eligibility group, county, status, NIGP class. Note: certified HUBs are ~99% DV; woman-/minority-owned certifications are mostly historical.

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

## Pricing

$1.00 / 1,000 hub vendor records

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## TX ESBD Procurement Opportunities

Pull **Texas Electronic State Business Daily (ESBD)** solicitations - the official Texas state procurement portal - with **structured NIGP commodity codes**, full-corpus search, and change monitoring.

Built for **AI agents, developers, and procurement tools** that need a clean, queryable data layer over Texas state & local government bidding opportunities.

### 👋 First time here? Start with the right tool

There are 8 actors in the Texas procurement family - one per job. Don't guess; match your goal:

| Your goal | Start here |
|---|---|
| **Find bids / RFPs / contracts** matching keywords, NIGP codes, agency or status | **[TX Government Contracts & Bids Search](https://apify.com/j0401/tx-esbd-search)** (`tx-esbd-search`) - start here |
| **Check one specific bid** by its bid number | **[TX Solicitation Lookup by Bid Number](https://apify.com/j0401/tx-esbd-get)** (`tx-esbd-get`) |
| **Monitor** new & changed solicitations on a schedule | **[TX Procurement Change Monitor](https://apify.com/j0401/tx-esbd-changes)** (`tx-esbd-changes`) |
| **Who won** Texas state contracts, at what amounts | **[TX Government Contract Awards & Winners](https://apify.com/j0401/tx-esbd-awards)** (`tx-esbd-awards`) |
| **Find / vet a vendor** - HUB, SDV, small business, NIGP capability, performance | **[TX Vendor Directory (CMBL)](https://apify.com/j0401/tx-cmbl-vendors)** (`tx-cmbl-vendors`) |
| **Find disabled-veteran (DV) HUB vendors** - eligibility, county, NIGP | **[TX Disabled Veteran (DV) HUB Vendors](https://apify.com/j0401/tx-hub-certified)** (`tx-hub-certified`) |
| **Statewide contracts** - who's on each SPD/TxSmartBuy contract, by NIGP or vendor ID | **[TX Statewide Contracts (TxSmartBuy)](https://apify.com/j0401/tx-smartbuy-contracts)** (`tx-smartbuy-contracts`) |
| **Pull the raw full corpus** (query + monitor modes) - power users | **[TX ESBD Procurement Opportunities](https://apify.com/j0401/sled-tx-procurement)** (`sled-tx-procurement`) |

If you're a first-time user, **recommended start: [TX Government Contracts & Bids Search](https://apify.com/j0401/tx-esbd-search)** (`tx-esbd-search`) - the most common task is finding matching bids.

### Predictable, low-cost pricing

- **From $0.001 per record** - the disabled-veteran (DV) HUB vendor directory costs a tenth of a cent per record; a single bid lookup is one cent.
- **No surprise bills** - every run is capped (main/search/awards/cmbl/hub/contracts $5 / changes $10 / get $1) so even a huge query can't run up a big charge.
- **Free change monitoring on first run** - the first `changes` run just establishes your baseline (no charge); you only pay for the alerts delivered after that.

### Why this exists

Texas publishes all state solicitations on [txsmartbuy.gov](https://www.txsmartbuy.gov) but only via an interactive web portal. Existing scrapers either:

- filter by keyword and drop the **NIGP commodity codes** (the most useful classification for matching your business),
- or only surface *new* opportunities, discarding the full history.

This suite treats the TX ESBD **native JSON API** as a first-class data source and exposes it as three semantic MCP tools.

### What you get

Every solicitation record is normalized with **structured NIGP codes** (not a raw string):

```json
{
  "platform": "tx-esbd",
  "agency": "Parks & Wildlife Department - 802",
  "agencyNumber": "802",
  "title": "17ft Center Console Mud Boat Packages",
  "bidNumber": "802-27-75102-BR",
  "status": "Awarded",
  "publishedDate": "7/24/2026",
  "closeDate": "8/7/2026 2:00 PM",
  "nigpCodes": [
    { "code": "12021", "description": "Boats, 21 Feet And Under" },
    { "code": "12063", "description": "Motors, Outboard, Gasoline" },
    { "code": "12090", "description": "Trailers, Boat" }
  ],
  "url": "https://www.txsmartbuy.gov/esbd/802-27-75102-BR",
  "created": "7/24/2026 8:25 am",
  "lastModified": "8/27/2026 4:10 pm"
}
```

Fields: `platform`, `agency`, `agencyNumber`, `title`, `bidNumber`, `status`, `publishedDate`, `closeDate`, `nigpCodes` (structured), `url`, `created`, `lastModified`.

**Statuses:** `Posted` / `Awarded` / `Addendum Posted` / `Closed` / `No Award`

### Actors

Every actor is **pay-per-event** - you pay only for the records delivered (each actor's pricing tab shows its cap):

| Actor | What it does | Price |
|---|---|---|
| **[TX Government Contracts & Bids Search, NIGP (AI-Ready)](https://apify.com/j0401/tx-esbd-search)** (`tx-esbd-search`) | Search by keywords / NIGP codes / agencies / status over the corpus. | $0.02 / matching record |
| **[TX Solicitation Lookup by Bid Number (ESBD)](https://apify.com/j0401/tx-esbd-get)** (`tx-esbd-get`) | Fetch a single solicitation by bid number. | $0.01 / record |
| **[TX Procurement Change Monitor (ESBD Alerts)](https://apify.com/j0401/tx-esbd-changes)** (`tx-esbd-changes`) | New & updated solicitations since the previous run (field-level diff). | $0.03 / change alert |
| **[TX Government Contract Awards & Winners (ESBD)](https://apify.com/j0401/tx-esbd-awards)** (`tx-esbd-awards`) | Who won Texas state contracts - winners, amounts, HUB status, VPTS performance grades. Our **highest-value dataset**. | $0.0175 / award record |
| **[TX Vendor Directory (CMBL)](https://apify.com/j0401/tx-cmbl-vendors)** (`tx-cmbl-vendors`) | The full Texas Comptroller vendor list (~45k) - HUB, SDV, small-business flags, performance scores, NIGP capability, VPTS grade. Filter by keyword, city, category. | $0.0035 / vendor record |
| **[TX Disabled Veteran (DV) HUB Vendors](https://apify.com/j0401/tx-hub-certified)** (`tx-hub-certified`) | HUB directory - best for disabled-veteran (DV) vendors. Eligibility group, county, status, NIGP class. Caveat: currently-certified HUBs are ~99% DV; minority-owned certifications are mostly historical. | $0.001 / HUB vendor record |
| **[TX Statewide Contracts (TxSmartBuy) - Vendors, NIGP, VID](https://apify.com/j0401/tx-smartbuy-contracts)** (`tx-smartbuy-contracts`) | Comptroller statewide (SPD/TxSmartBuy) contracts - who's on each contract, with NIGP codes and exact vendor-ID enriched contractor profiles. | $0.02 / contract record |
| **[TX State Procurement Data (ESBD, NIGP Codes)](https://apify.com/j0401/sled-tx-procurement)** (`sled-tx-procurement`) | The raw engine: full-corpus pull (query) and change diffing (monitor) with structured NIGP output. For developers who want the underlying data layer directly. | $0.02 / solicitation page (query or monitor) |

> **For `monitor` needs, use `tx-esbd-changes`** - it is purpose-built for change detection with field-level diff at $0.03/alert (cap $10), rather than `sled`'s `monitor` mode at its flat $0.02/page (cap $5). Use `sled` in `monitor` mode only if you need the raw JSON structure or a custom integration.

### For developers: the underlying data layer

The semantic actors (search / get / changes) are thin, focused views over one corpus. **`sled-tx-procurement` is the engine underneath them** - a raw, unopinionated data layer you can build your own pipeline on:

- **`mode: query`** - pull any slice of the full ~59k corpus with structured NIGP codes, filter server-side-equivalent by keyword / NIGP / agency / status, and get clean JSON records.
- **`mode: monitor`** - diff against a stored snapshot and emit only what changed (new / updated with `oldValue` / `newValue`), so you can run your own alerting without the semantic wrapper.
- **Deterministic and inspectable** - the exact same normalized schema the semantic tools use, no hidden transforms, no black box. What you get from the API is what your pipeline consumes.

The MCP tools are conveniences over this layer; if you prefer to wire the data yourself (Apify API - your database - your dashboards), this is the access point. Every other actor in this family is a packaged query against it.

### Scanning depth & full-corpus chunking

`pages` is **scan depth from the newest record**, not a page offset - setting `pages: 2500` scans every record (~40 min). main/search/changes/get run on a 30-min timeout, so for those a full scan **must be chunked** by date window or NIGP code (see below). `tx-esbd-awards` runs on a 60-min timeout and can do a full scan in one run.

**Option A - date windows** (via `publishedAfter` / `publishedBefore`, YYYY-MM-DD):

```json
{"pages": 2500, "publishedAfter": "2026-01-01", "publishedBefore": "2026-03-31"}
{"pages": 2500, "publishedAfter": "2026-04-01", "publishedBefore": "2026-06-30"}
```

Run one chunk per quarter; each finishes well inside the timeout. The `_meta` record on every run reports the scanned date ranges, so you can confirm a chunk was fully covered.

**Option B - NIGP code ranges** (via `nigpCodes`):

```json
{"pages": 2500, "nigpCodes": ["90000"]}   // Professional Services
{"pages": 2500, "nigpCodes": ["91000"]}   // Building Maintenance
```

**Measured scan times** (so you can size chunks): 100 pages ~ 95 s, 200 pages ~ 3 min, 500 pages ~ 8 min. For main/search/changes/get (30-min timeout) stay under ~1800 pages per run; `tx-esbd-awards` (60-min timeout) can run the full 2500.

> Note: the source sorts solicitations by **last modified**, not posted date. `publishedAfter` filters correctly but a shallow scan can still miss old-posted records that were recently modified - use the `_meta` scan ranges to verify coverage.

### MCP server

The three semantic tools are exposed via **Apify's hosted MCP** - no self-hosting needed.

```json
{
  "mcpServers": {
    "tx-esbd": {
      "type": "http",
      "url": "https://mcp.apify.com?tools=j0401/tx-esbd-search,j0401/tx-esbd-get,j0401/tx-esbd-changes",
      "headers": { "Authorization": "Bearer <APIFY_TOKEN>" }
    }
  }
}
```

Tools available to your AI assistant:

- **`j0401--tx-esbd-search`** - `keywords`, `nigpCodes`, `agencies`, `statuses`, `pages`, `limit`
- **`j0401--tx-esbd-get`** - `bidNumber`, `pages`
- **`j0401--tx-esbd-changes`** - `pages`, `snapshotKey`

Compatible with Claude Desktop, Cursor, VS Code, Windsurf, and any MCP client. Your `APIFY_TOKEN` from [Apify Console -> Settings -> Integrations](https://console.apify.com/settings/integrations).

#### Talk to your AI assistant in plain English

Once the MCP tools are connected, you can ask your agent in natural language:

> "Find Texas RFPs published in the last 7 days with NIGP code 92500 (Engineering Services), limit to 10."

> "What is the current status and close date of bid UTSA129?"

> "Have any addenda or deadline changes been posted in Texas procurement this week?"

The agent calls the MCP tools behind the scenes and returns structured answers you can feed straight into a spreadsheet, CRM, or another agent.

### Use cases

- **Government contractors** - find bids matching your NAICS/NIGP codes so you never miss an opportunity in your category.
- **Procurement AI startups** - use the MCP server as a ready-made Texas data layer for your agent.
- **Sales teams** - identify which agencies award in your category for lead generation.
- **Award intelligence** - run `tx-esbd-awards` for the **result, not the rumor**: who actually won contracts in your NIGP category, at what amounts, and their HUB / VPTS performance grades. This is outcome data - the closest thing to a "who won the deal" answer - useful for competitive intelligence, win/loss analysis and market sizing, not just lead generation.
- **Change alerts** - run `tx-esbd-changes` on a schedule (Apify scheduler) to get notified of new postings and deadline changes. First run establishes a baseline (no charge); subsequent runs diff against it. Use a unique `snapshotKey` per deployment to keep baselines separate.
- **AI workflows** - feed structured opportunities directly into your agent's context without scraping HTML.

### Notes

- **Data source:** [Texas Comptroller - ESBD](https://www.txsmartbuy.gov/esbd). All data is from public state records.
- **No login, no anti-bot** - uses the official public JSON API.
- **Full corpus** - ~59,000 active solicitations. `pages` = 24 records each; set `pages: 2500` for the full snapshot (~40 min scan).
- **Keyword search includes NIGP descriptions** - searching "dental" also finds solicitations classified under NIGP *Dental Services*, even when the title doesn't say "dental".
- **Default `pages: 20`** (search) / `50` (get, changes) - covers the newest ~480-1,200 records quickly. Raise it to search deeper; each run reports how many records it scanned so you know if results may be truncated.

### Vendor profiles (CMBL + VPTS)

The **CMBL actor** returns each vendor's **registration profile** (HUB / SDV /
small-business / QISV flags, business category, NIGP classification, performance
scores) plus their **VPTS performance grade**, linked by **exact vendor ID** - no
name guessing, so matches are exact (no false positives). Vendors without a
VPTS record are returned with `"vpts": null`, never a guessed grade.

The **awards actor** also enriches winners with a VPTS grade when a name match is
found - but note that ESBD awards carry no vendor ID, so this is a **name-based
match** (roughly 3-4 in 10 awards find a VPTS record; the rest are `vpts: null`).
For exact vendor-ID-linked performance, use the CMBL actor.

No subscription. You only pay for the records delivered.

### License

MIT - see [LICENSE](./LICENSE).

### Disclaimer

This product is an independent data service and is **not affiliated with, endorsed by, or sponsored by** the State of Texas or any government agency. All solicitation data is public government information. We recommend verifying any opportunity on the official portal before acting.

# Actor input Schema

## `keywords` (type: `array`):

Only return vendors whose name, description, city or contact matches any keyword (case-insensitive). E.g. "construction", "IT", "Houston".

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

Default A = currently certified only (~1,500 HUBs, almost all DV disabled-veteran). D = de-certified, I = inactive, X = expired, ALL = every status (includes ~13k de-certified). Tip: if your county/keyword search returns empty with A, try ALL - the vendor may exist but be expired/de-certified.

## `eligibility` (type: `array`):

Only return vendors in these HUB eligibility groups: AI American Indian, AS Asian Pacific American, BL Black American, DV Disabled Veteran, HI Hispanic American, WO Woman-Owned. E.g. \["DV"], \["HI","WO"].

## `counties` (type: `array`):

Only return vendors in these Texas counties (case-insensitive substring). E.g. \["Travis"], \["Harris","Dallas"].

## `nigpCodes` (type: `array`):

Only return vendors classified under these NIGP classes. Accepts 3-digit class ("005") or ESBD 5-digit codes ("94828", same format as tx-esbd records); the item part is ignored because hub\_clas.csv only carries class-level data. Joins hub\_clas.csv on the vendor VID. E.g. \["948"] for Dental Services.

## `highwayDistricts` (type: `array`):

Only return vendors flagged for these Texas highway districts (1-25) under a matching NIGP class. From the hub\_clas district bitmap.

## `sdv` (type: `boolean`):

Only return Service-Disabled Veteran (SDV) vendors (SDV FLAG = Y).

## `smallBusiness` (type: `boolean`):

Only return vendors flagged as small business (SMALL BUSINESS FLAG = Y).

## `txOfficeOnly` (type: `boolean`):

Only return vendors with a Texas office (TEXAS OFFICE FLAG = Y).

## `hasNigp` (type: `boolean`):

Only return vendors with at least one NIGP classification in hub\_clas.

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

Cap the number of vendor records pushed. Default 200 keeps the bill predictable (~$0.20). 0 = unlimited (status=ALL covers ~15.5k records - the bill can be high; only use 0 when you need the whole list).

## Actor input object example

```json
{
  "status": "A",
  "sdv": false,
  "smallBusiness": false,
  "txOfficeOnly": false,
  "hasNigp": false,
  "maxResults": 200
}
```

# Actor output Schema

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

HUB-certified vendor records - name, eligibility group, status, county, NIGP class - 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-hub-certified").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-hub-certified").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-hub-certified --silent --output-dataset

```

## MCP server setup

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

```

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/fADIQippS7dQhj9LG/builds/hvTCtdOb70WB1yAxe/openapi.json
