# TX Government Contract Awards & Winners (ESBD) (`j0401/tx-esbd-awards`) Actor

Who won Texas state contracts - award winners, amounts, HUB status and vendor performance (VPTS) grades. Search by NIGP, agency or contractor.

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

## Pricing

$10.00 / 1,000 award 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?

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

## TX Government Contract Awards & Winners, ESBD (`tx-esbd-awards`)

**Who actually won the contract.** This actor returns the award record behind a Texas state solicitation - the winning vendors, the amounts, their **HUB status**, and their **VPTS vendor performance grade** where a match exists.

It answers the question the opportunity feed can't: not *what is being bought*, but *who got it, for how much, and how they performed*.

### Low cost

**From $0.01 per award record** - you are charged per award record delivered, never for the query itself. Runs are capped at **$5**.

Most award records carry several winner lines; **each contractor is billed as one record**, so you pay for the winners you receive rather than for the solicitations scanned.

### What you get

```json
{
  "platform": "tx-esbd",
  "bidNumber": "802-27-75102-BR",
  "title": "17ft Center Console Mud Boat Packages",
  "agency": "Parks & Wildlife Department - 802",
  "nigpCodes": [{ "code": "12021", "description": "Boats, 21 Feet And Under" }],
  "contractor": {
    "name": "GULF COAST MARINE LLC",
    "value": 29266.0,
    "hubStatus": "HUB",
    "awardDate": "8/27/2026",
    "vpts": { "vendorId": "17001234567", "grade": "A" }
  }
}
```

Fields: `platform`, `bidNumber`, `title`, `agency`, `nigpCodes` (structured), `contractor.name`, `contractor.value`, `contractor.hubStatus`, `contractor.awardDate`, `contractor.vpts.vendorId`, `contractor.vpts.grade`.

### Filters

| Filter | What it does |
|---|---|
| `nigpCodes` | Award records in one or more NIGP codes. |
| `agencies` | Restrict to one or more agencies. |
| `publishedAfter` / `publishedBefore` | Date window (`YYYY-MM-DD`) - for chunking the corpus. |
| `includeVpts` | Attach the VPTS performance grade (default on). |
| `refreshVpts` | Re-pull the VPTS index instead of using the cached one. |
| `pages` | Scan depth from the newest record (24 records per page). Default `20`. |
| `maxResults` | Cap the number of output records. |

### Example inputs

**Who won in a commodity code** - `nigpCodes` matches the structured code; widen `pages` to reach further back:

```json
{ "nigpCodes": ["96145"], "pages": 250 }
```

**Awards handed out by one agency:**

```json
{ "agencies": ["529"], "pages": 100 }
```

**Awards inside one date window** - `pages` sets the scan depth from the newest record:

```json
{ "pages": 50, "publishedAfter": "01/01/2026", "publishedBefore": "12/31/2026", "maxResults": 50 }
```

**Skip the performance lookup** for a lighter, faster scan:

```json
{ "pages": 20, "includeVpts": false, "maxResults": 50 }
```

### Read the VPTS grade correctly

`contractor.vpts` is attached by **matching the winner's name** against the VPTS performance register. The ESBD award record carries **no vendor ID**, so this can only ever be a name match - measured across three recent runs, **26.6%** of award winners (83 of 312) find a confident VPTS record, and the rest come back as `"vpts": null`. A null is "no confident match", never a guessed grade.

**For exact, ID-linked vendor performance, use the CMBL actor instead** - there the join is on the vendor's ID, so it is exact rather than probabilistic.

### Why this is hard

Two separate sources have to be reconciled: the solicitation record (which knows what was bought and by whom, by **name only**) and the VPTS performance register (which knows how vendors performed, keyed by a vendor ID the award record doesn't carry). Bridging them with a name match is the only option the data allows - so the honest engineering move is to report **when** a match was found rather than to silently attach the nearest name.

The award detail also lives behind a second API call per solicitation - which is why the scan depth and per-run cost behave differently here than in the plain search actor.

### Example output

**`{"nigpCodes": ["94828"]}`** - one award record: the solicitation, its winning contractor, and the VPTS line attached where a match exists:

```json
{
  "platform": "tx-esbd",
  "bidNumber": "HHS0017561",
  "title": "On-site Total Intravenous Anesthesia at  Austin State Supported Living Center (AuSSLC)",
  "agency": "Health & Human Services Commission - 529",
  "agencyNumber": "529",
  "status": "Awarded",
  "nigpCodes": [
    {
      "code": "94828",
      "description": "Dental Services"
    }
  ],
  "publishedDate": "6/22/2026",
  "closeDate": "7/8/2026 10:30 AM",
  "url": "https://www.txsmartbuy.gov/esbd/HHS0017561",
  "internalId": "530056",
  "contractor": {
    "name": "Deepsedation",
    "address": "1401 Lavaca st #724",
    "value": 40000,
    "hubStatus": "2",
    "hubStatusText": "NOT CERTIFIED",
    "awardDate": "9/17/2026",
    "awardStatus": "Full Award",
    "vpts": {
      "vendorId": "18520751746",
      "vendorName": "DEEPSEDATION P C",
      "grade": "A",
      "reportCount": "2",
      "datePublished": "11/20/2025"
    }
  }
}
```

A winner with no confident VPTS match comes back as `"vpts": null` - never a guessed grade.

### The rest of the Texas family

| Your goal | Actor |
|---|---|
| **Find bids** by keyword, NIGP, agency, status | [`tx-esbd-search`](https://apify.com/j0401/tx-esbd-search) |
| **Check one specific bid** by its number | [`tx-esbd-get`](https://apify.com/j0401/tx-esbd-get) |
| **Monitor** new & changed solicitations on a schedule | [`tx-esbd-changes`](https://apify.com/j0401/tx-esbd-changes) |
| **Who won** state contracts, at what amounts | **`tx-esbd-awards`** - you are here |
| **Find / vet a vendor** - HUB, SDV, small business, NIGP capability | [`tx-cmbl-vendors`](https://apify.com/j0401/tx-cmbl-vendors) |
| **Find disabled-veteran (DV) HUB vendors** | [`tx-hub-certified`](https://apify.com/j0401/tx-hub-certified) |
| **Statewide contracts** - who's on each SPD/TxSmartBuy contract | [`tx-smartbuy-contracts`](https://apify.com/j0401/tx-smartbuy-contracts) |
| **Pull the raw full corpus** (query + monitor) - power users | [`sled-tx-procurement`](https://apify.com/j0401/sled-tx-procurement) |

### Typical questions

- "Who won contracts in **NIGP 12021** this year, and for how much?"
- "Which agencies award to **HUB** vendors in my category?"
- "What is the **average award size** in my commodity code?"
- "Is my competitor winning - and what is their **VPTS performance grade**?"

### Notes

- **Data source:** [Texas Comptroller - ESBD](https://www.txsmartbuy.gov/esbd) awards + TxSmartBuy Vendor Performance Tracking System (VPTS). Public state records.
- **No login, no anti-bot** - uses the official public JSON API.

### 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 award data is public government information.

# Actor input Schema

## `pages` (type: `integer`):

Each page = 24 solicitations. Default 20 = newest ~480 records (fast, ~2 min; keeps daily auto-test well inside Apify's 5-min limit). 2500 = full corpus (~59,300 records) - a full scan takes ~45 min and needs the 3600s run timeout (already set).

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

Only return awards whose solicitation matches these NIGP codes (e.g. 005, 918, 55091).

## `agencies` (type: `array`):

Only return awards from these agencies (by agency number or name).

## `publishedAfter` (type: `string`):

Only awards from solicitations published on/after this date (MM/DD/YYYY).

## `publishedBefore` (type: `string`):

Only awards from solicitations published on/before this date (MM/DD/YYYY).

## `includeVpts` (type: `boolean`):

Look up each winning contractor in the VPTS vendor-performance index and attach their A-F grade, vendor ID and report count when a name match is found. Note: ESBD awards carry no vendor ID, so this is a name-based match - it finds a VPTS record for roughly 3-4 in 10 awards (the rest have no match, left as vpts=null). For exact vendor-ID-linked performance, use the CMBL actor.

## `refreshVpts` (type: `boolean`):

Fetch the full VPTS vendor-performance index instead of reusing the 24h KV-store cache. ~90s extra per run; leave off for repeat runs.

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

Cap the number of award records pushed (0 = unlimited).

## `concurrency` (type: `integer`):

Parallel HTTP requests while scanning and fetching details.

## Actor input object example

```json
{
  "pages": 20,
  "includeVpts": true,
  "refreshVpts": false,
  "maxResults": 0,
  "concurrency": 5
}
```

# Actor output Schema

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

Contract award records - winning contractor, amount, HUB status, VPTS grade - 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-esbd-awards").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-esbd-awards").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-esbd-awards --silent --output-dataset

```

## MCP server setup

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

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/IUwShnF1FMxy2Qsfi/builds/fR8vXHPDpdjOunbHO/openapi.json
