# USAspending Federal Awards Scraper (`haketa/usaspending-scraper`) Actor

USAspending scraper & API: search US federal contracts, grants and awards and export recipient, agency, amount, award type, dates, place of performance and NAICS. Government-contract intelligence and B2B lead generation — fast, no login.

- **URL**: https://apify.com/haketa/usaspending-scraper.md
- **Developed by:** [Haketa](https://apify.com/haketa) (community)
- **Categories:** Lead generation, Developer tools
- **Features:** Limited permissions
- **Stats:** 5 total users, 0 monthly users, 96.6% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.50 / 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?

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

<h1 align="center">🏛️ USAspending Scraper — Federal Contracts, Grants, UEI & Executive Compensation</h1>

<p align="center">
  <img alt="Platform" src="https://img.shields.io/badge/Made%20for-Apify-97D700?style=for-the-badge">
  <img alt="Source" src="https://img.shields.io/badge/Data-USAspending.gov%20%F0%9F%87%BA%F0%9F%87%B8-003366?style=for-the-badge">
  <img alt="No Key" src="https://img.shields.io/badge/No%20API%20Key-No%20Proxy%20Needed-4C8BF5?style=for-the-badge">
  <img alt="Scale" src="https://img.shields.io/badge/Scale-1%2C000%2B%20to%20100K%2B%20Awards-8A2BE2?style=for-the-badge">
  <img alt="Export" src="https://img.shields.io/badge/Export-JSON%20%7C%20CSV%20%7C%20Excel%20%7C%20API-FF7A00?style=for-the-badge">
</p>

<p align="center"><b>Turn 8,000,000+ US federal contracts, IDVs, grants, and loans into an outbound-ready B2G intelligence database — with recipient UEI, full headquarters address, congressional district, 3-tier NAICS hierarchy, set-aside program, and FFATA executive compensation.</b></p>

**Turn US federal procurement data into a ready-to-use B2G lead & market intelligence database.** This **USAspending scraper** extracts federal **contracts, IDVs (Indefinite Delivery Vehicles / IDIQs / GWACs), grants, loans, direct payments, and other financial assistance** from [USAspending.gov](https://www.usaspending.gov) — complete with the winning company's **Unique Entity ID (`UEI`), parent UEI, full registered address, business categories (Small Business, 8(a), WOSB, HUBZone, SDVOSB), 3-tier NAICS hierarchy, PSC code, set-aside classification, competition metrics, subaward totals, place of performance, awarding & funding agency hierarchy, and disclosed FFATA executive compensation**. No login, no API key, no proxy required.

Export to **JSON, CSV, Excel (XLSX), or API**.

> 🦅 Built for **B2G & GovCon sales teams, GovTech founders, M\&A and private-equity analysts, defense/healthcare/energy strategists, small-business set-aside contractors (8(a) / WOSB / SDVOSB / HUBZone), compliance officers, and investigative researchers** who want structured federal-spending intelligence at a fraction of the cost of GovWin IQ, Bloomberg Government, or Deltek.

***

### ⚡ At a glance

| Feature | Details |
| :--- | :--- |
| 🏛️ **All 6 award categories** | `contracts`, `idvs` (IDIQ/GWAC/BPA), `grants`, `loans`, `other_financial_assistance`, and `direct_payments` |
| 🎯 **Precision B2G targeting** | Filter by Keywords, Awarding Agency (30+ top-tier agencies), Recipient Name, NAICS (built-in + custom), Set-Aside Program (19 codes), HQ State, Performance State, Date Range, and Dollar Amount |
| 🏢 **Recipient & UEI enrichment** | `recipient.name`, `recipient.uei`, `parentName`, `parentUei`, `businessCategories[]`, and full HQ address (`addressLine1`, `city`, `stateCode`, `zip5`/`zip4`, `county`, `congressionalCode`) |
| 👔 **Executive compensation** | Disclosed FFATA top officers (`executiveCompensation`: `[{ name, amount }]`) with automatic null-slot stripping |
| 📊 **Procurement & competition** | `awardAmount`, `totalObligation`, `baseAndAllOptions`, `totalOutlay`, `naics` (2/4/6-digit hierarchy), `psc`, `setAside`, `competition` (`extentCompeted`, `numberOfOffers`, `solicitationProcedures`) |
| 🔄 **Unlocked 1,000+ pagination** | Paginates `100 awards/page` with parallel detail enrichment (`maxConcurrency` up to `20`) and zero artificial caps when `maxRecords: 1000+` is set |
| 📋 **Dual dataset views** | Pre-built **Awards** table view (1 row per award) + **Recipients + executives** unwound view (1 row per disclosed executive) |
| 💾 **Export & CRM sync** | Bulk export JSON, CSV, Excel, or push via Apify API into Salesforce, HubSpot, Clay, Apollo, Smartlead, Make, Zapier, and n8n |

***

### 🔎 Why scrape USAspending?

The United States federal government is the largest single buyer of goods, services, R\&D, and infrastructure on Earth — obligating over **$7 trillion annually** across defense, cybersecurity, cloud computing, healthcare, construction, energy, and scientific research. Every contract modification, grant award, and IDV task order is recorded on USAspending.gov.

However, the web interface is designed for manual lookup rather than revenue operations or data engineering:

1. **Buried entity & executive fields:** Search result tables omit the recipient's **full street address**, **parent UEI**, **business category flags**, **competition offer counts**, and **FFATA executive compensation** (`officers` names and salaries) — those require fetching each individual `/awards/{internalId}/` detail endpoint.
2. **Awkward bulk exports:** Official bulk downloads dump massive, multi-gigabyte zipped CSVs with hundreds of raw treasury columns that require hours of ETL cleaning just to answer *"Which 8(a) or SDVOSB cybersecurity contractors in Virginia won DoD contracts over $1M this year?"*

This **USAspending scraper** bridges that gap: it queries the official search API with your exact ICP filters, paginates cleanly across hundreds or thousands of awards (`100 per page`), fetches the deep per-award detail record in parallel, and outputs both a clean nested JSON structure and flat CRM-ready columns (`recipientName`, `recipientUei`, `recipientState`, `agencyName`, `naicsCode`, `setAsideDescription`, `performanceState`).

**Common reasons teams scrape USAspending:**

- 🎯 **B2G & GovCon outbound lead generation** — build targeted lists of federal prime contractors by NAICS, agency, state, and set-aside status, complete with `UEI`, physical HQ address, and named executives (`executiveCompensation`).
- 🤝 **Subcontracting & teaming partner discovery** — small businesses (`8(a)`, `WOSB`, `SDVOSB`, `HUBZone`) identify large primes winning contracts with high `baseAndAllOptions` ceilings and active `subawardCount` activity.
- 🔔 **Competitor contract-win monitoring** — schedule weekly runs filtered by `recipientSearchText` (e.g. `"Booz Allen"`, `"Leidos"`, `"Palantir"`) or `naicsCodes` to track competitor obligations and agency expansion.
- 💼 **M\&A & private-equity deal sourcing** — screen privately held defense, IT, and engineering contractors by obligated federal revenue (`awardAmount`), contract backlog (`baseAndAllOptions` minus `totalOutlay`), and sole-source moat (`competition.extentCompeted`).
- 🧪 **Grant & non-dilutive R\&D intelligence** — pull NIH, NSF, DOE, DoD SBIR/STTR, and USDA grants (`awardTypeCategories: ["grants"]`) to find funded biotech, climate-tech, and university labs.

***

### ✨ What this USAspending scraper does

- ✅ **Covers all 6 federal spending categories** — `contracts`, `idvs`, `grants`, `loans`, `other_financial_assistance`, and `direct_payments`.
- ✅ **12 combinable ICP filter dimensions** — filter by `keywords`, `recipientSearchText`, `agencyNames` (30 top-tier federal agencies), `naicsCodes` (31 popular 6-digit codes + `naicsCodesCustom` for any 2/4/6-digit code), `setAsideTypes` (19 small-business set-aside codes), `recipientLocationStates`, `placeOfPerformanceStates`, `timePeriodStart`/`End`, and `minAwardAmount`/`maxAwardAmount`.
- ✅ **Unlocked 1,000+ pagination** — steps through `spending_by_award` at `100 records/page` (`page=1, 2, 3…`) with zero hard caps when `maxRecords` is set to `1000`, `5000`, or higher.
- ✅ **Deep per-award detail enrichment (`scrapeAwardDetails: true`)** — fetches `/api/v2/awards/{internalId}/` in parallel to enrich every row with UEI, parent UEI, full address, congressional district, business categories, 3-tier NAICS hierarchy, PSC code, set-aside details, competition metrics, subaward totals, and FFATA executive compensation.
- ✅ **Fast listing-only mode (`scrapeAwardDetails: false`)** — skips per-award detail requests to stream summary rows 10× faster for massive industry discovery sweeps.
- ✅ **Clean FFATA executive array** — strips empty/null officer padding slots so `executiveCompensation` contains only real disclosed executives (`[{ name, amount }]`) or `[]`.
- ✅ **No proxy or API key required** — runs directly against public federal endpoints with configurable `maxConcurrency` (`1`–`20`) and `requestDelay`.

***

### 🎯 Use cases

| Persona | How they use USAspending Federal Awards Scraper |
| :--- | :--- |
| 📈 **B2G & GovCon Sales Teams** | Prospect companies that just won a $500K–$50M federal contract (funded buyers with immediate hiring, software, and compliance budgets). |
| 🛡️ **Small-Business Set-Aside Firms** | Filter by `setAsideTypes: ["8A", "SDVOSBC", "WOSB", "HUBZ"]` and `naicsCodes` to see which agencies and offices are actively awarding set-aside contracts. |
| 🏦 **Private Equity & M\&A Analysts** | Map market share, contract renewal dates (`periodOfPerformance.currentEndDate`), and disclosed C-suite pay (`executiveCompensation`) across niche NAICS codes. |
| 🧬 **B2B Biotech & Lab Suppliers** | Scrape HHS / NIH / NSF `grants` to target freshly funded principal investigators and research institutions. |
| 📰 **Journalists & Policy Researchers** | Audit federal spending flows by state (`placeOfPerformanceStates`), congressional district (`congressionalCode`), and sole-source competition status. |

***

### 📥 Input

Every input field is optional. With default prefill (`awardTypeCategories: ["contracts"]`, `keywords: ["cybersecurity"]`, `maxRecords: 50`), a run completes in **~10–15 seconds**. Running with an empty `{}` input returns the top 100 federal contracts from the last fiscal year sorted by award amount.

| Field | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `awardTypeCategories` | array | `["contracts"]` | Categories to extract: `contracts`, `idvs`, `grants`, `loans`, `other_financial_assistance`, `direct_payments`. |
| `keywords` | array | `[]` (`prefill: ["cybersecurity"]`) | Free-text keywords matched across award descriptions (e.g. `["cloud", "zero trust", "AI"]`). |
| `recipientSearchText` | string | `""` | Contractor or grantee company name substring (e.g. `"Lockheed"`, `"Booz Allen"`, `"Palantir"`). |
| `agencyNames` | array | `[]` (All agencies) | Pick one or more of 30 top-tier awarding agencies (`Department of Defense`, `Department of Veterans Affairs`, `NASA`, etc.). |
| `naicsCodes` | array | `[]` | Pick from 31 built-in 6-digit NAICS industry codes (`541512` Computer Systems Design, `541330` Engineering, etc.). |
| `naicsCodesCustom` | array | `[]` | Any additional 2-, 4-, or 6-digit NAICS codes to combine with `naicsCodes`. |
| `setAsideTypes` | array | `[]` | Small-business set-aside codes (`SBA`, `8A`, `8AN`, `WOSB`, `EDWOSB`, `HUBZ`, `SDVOSBC`, `SDVOSBS`, `VSA`, etc.). |
| `recipientLocationStates` | array | `[]` | Filter by contractor headquarters US state/territory (`VA`, `MD`, `DC`, `CA`, `TX`, etc.). |
| `placeOfPerformanceStates` | array | `[]` | Filter by US state/territory where the work is performed. |
| `timePeriodStart` | string | Last fiscal year | Start date (`YYYY-MM-DD`, prefilled `2024-10-01`). |
| `timePeriodEnd` | string | Today | End date (`YYYY-MM-DD`). |
| `minAwardAmount` | integer | `0` | Minimum award obligation amount in USD (`0` = no floor). |
| `maxAwardAmount` | integer | `0` | Maximum award obligation amount in USD (`0` = no ceiling). |
| `sortBy` | string | `"Award Amount"` | Sort field: `"Award Amount"`, `"Start Date"`, `"End Date"`, `"Recipient Name"`, or `"Award ID"`. |
| `sortOrder` | string | `"desc"` | `"desc"` (largest/newest first) or `"asc"`. |
| `scrapeAwardDetails` | boolean | `true` | Fetch the full per-award detail record (UEI, HQ address, NAICS hierarchy, competition, executives). Set `false` for fast summary discovery. |
| `maxRecords` | integer | `100` (`prefill: 50`) | Maximum awards to collect. Set `1000`–`10000+` for deep sweeps, or `0` for unlimited (when filters are active). |
| `requestDelay` | integer | `250` | Delay in milliseconds between requests (`250` ms default). |
| `maxConcurrency` | integer | `5` | Parallel detail-fetching workers (`1`–`20`). |
| `proxyConfiguration` | object | Off | Optional Apify Proxy configuration. Not needed for standard runs (`useApifyProxy: false`). |

#### Example input — 1,000+ DoD IT & cybersecurity set-aside contracts

```json
{
  "awardTypeCategories": ["contracts"],
  "agencyNames": ["Department of Defense", "Department of Homeland Security"],
  "naicsCodes": ["541512", "541511", "541519"],
  "setAsideTypes": ["8A", "SDVOSBC", "WOSB", "HUBZ"],
  "recipientLocationStates": ["VA", "MD", "DC"],
  "timePeriodStart": "2024-10-01",
  "minAwardAmount": 250000,
  "sortBy": "Award Amount",
  "sortOrder": "desc",
  "scrapeAwardDetails": true,
  "maxRecords": 1500,
  "maxConcurrency": 10
}
```

***

### 📤 Output

Each award is pushed to the dataset with both rich nested objects and flat top-level convenience fields. Below is a real record from a verified run:

```json
{
  "awardId": "HT940216C0001",
  "internalAwardId": "CONT_AWD_HT940216C0001_9700_-NONE-_-NONE-",
  "category": "contract",
  "type": "D",
  "typeDescription": "DEFINITIVE CONTRACT",
  "description": "MANAGED CARE SUPPORT SERVICES",
  "awardAmount": 51269205263.03,
  "totalObligation": 51269205263.03,
  "baseAndAllOptions": 56620536577.19,
  "totalOutlay": 42150112000.0,
  "dateSigned": "2016-07-29",
  "periodOfPerformance": {
    "startDate": "2016-08-01",
    "currentEndDate": "2025-12-31",
    "potentialEndDate": "2025-12-31 00:00:00"
  },
  "awardingAgency": {
    "toptierName": "Department of Defense",
    "toptierCode": "097",
    "toptierAbbrev": "DOD",
    "subtierName": "Defense Health Agency",
    "subtierCode": "97DH",
    "officeName": "DEFENSE HEALTH AGENCY"
  },
  "fundingAgency": {
    "toptierName": "Department of Defense",
    "subtierName": "Defense Health Agency"
  },
  "recipient": {
    "name": "HUMANA GOVERNMENT BUSINESS INC",
    "uei": "ZE6ZM6NKSV43",
    "parentName": "HUMANA INC",
    "parentUei": "ZE6ZM6NKSV43",
    "businessCategories": [
      "Category Business",
      "Corporate Entity Not Tax Exempt",
      "Not Designated a Small Business",
      "U.S.-Owned Business"
    ],
    "location": {
      "addressLine1": "500 W MAIN STREET",
      "addressLine2": null,
      "city": "LOUISVILLE",
      "state": "KENTUCKY",
      "stateCode": "KY",
      "country": "UNITED STATES",
      "countryCode": "USA",
      "zip5": "40202",
      "zip4": "2946",
      "county": "JEFFERSON",
      "congressionalCode": "03"
    }
  },
  "placeOfPerformance": {
    "city": "LOUISVILLE",
    "state": "KENTUCKY",
    "stateCode": "KY",
    "country": "UNITED STATES",
    "countryCode": "USA",
    "county": "JEFFERSON",
    "zip5": "40201",
    "congressionalCode": "03"
  },
  "naics": {
    "code": "524114",
    "description": "DIRECT HEALTH AND MEDICAL INSURANCE CARRIERS",
    "midtierCode": "5241",
    "midtierDescription": "Insurance Carriers",
    "toptierCode": "52",
    "toptierDescription": "Finance and Insurance"
  },
  "psc": {
    "code": "Q201",
    "description": "SUPPORT- MEDICAL: HEALTHCARE"
  },
  "setAside": {
    "code": "NONE",
    "description": "NO SET ASIDE USED."
  },
  "competition": {
    "extentCompeted": "A",
    "extentCompetedDescription": "FULL AND OPEN COMPETITION",
    "numberOfOffers": 4,
    "solicitationProcedures": "NP"
  },
  "subawardCount": 12,
  "subawardTotalAmount": 18450000.0,
  "executiveCompensation": [
    { "name": "KAREN MORAN", "amount": 1409718 },
    { "name": "KEVIN REGENHOLD", "amount": 607266 },
    { "name": "MELANIE BUEHLER", "amount": 604450 }
  ],
  "recipientName": "HUMANA GOVERNMENT BUSINESS INC",
  "recipientUei": "ZE6ZM6NKSV43",
  "recipientState": "KY",
  "agencyName": "Department of Defense",
  "naicsCode": "524114",
  "naicsDescription": "DIRECT HEALTH AND MEDICAL INSURANCE CARRIERS",
  "setAsideDescription": "NO SET ASIDE USED.",
  "performanceState": "KY",
  "awardDetailUrl": "https://www.usaspending.gov/award/CONT_AWD_HT940216C0001_9700_-NONE-_-NONE-/",
  "scrapedAt": "2026-11-10T03:00:00.000Z"
}
```

#### 📋 Output field reference

##### 🏛️ Award Identity, Financials & Timeline

| Field | Type | Coverage | Description |
| :--- | :--- | :--- | :--- |
| `awardId` | string | 🟢 High (100%) | Official procurement instrument ID (`PIID` for contracts/IDVs, `FAIN`/`URI` for grants/loans). |
| `internalAwardId` | string | 🟢 High (100%) | Unique USAspending generated award ID (`generated_unique_award_id`, primary key). |
| `category` / `type` / `typeDescription` | string | 🟢 High (100%) | Award category (`contract`, `idv`, `grant`) and subtype (`DEFINITIVE CONTRACT`, `BPA CALL`, `PROJECT GRANT`). |
| `description` | string | 🟢 High (~97%) | Scope of work / procurement description. |
| `awardAmount` / `totalObligation` | number | 🟢 High (100%) | Total federal dollars obligated on the award. |
| `baseAndAllOptions` | number | 🟢 High (~95%) | Total potential contract ceiling including all option years. |
| `totalOutlay` | number | 🟡 Conditional (~51%) | Actual cash outlays disbursed to date (populated once treasury outlays post). |
| `dateSigned` | string | 🟢 High (100%) | Date the initial award was signed (`YYYY-MM-DD`). |
| `periodOfPerformance` | object | 🟢 High (100%) | `{ startDate, currentEndDate, potentialEndDate }`. |
| `subawardCount` / `subawardTotalAmount` | number | 🟢 High (~95%) | Total count and dollar volume of reported subcontracts/subgrants. |
| `awardDetailUrl` | string | 🟢 High (100%) | Direct URL to the award profile on `usaspending.gov`. |

##### 🏢 Recipient Entity, UEI, HQ Location & Executives

| Field | Type | Coverage | Description |
| :--- | :--- | :--- | :--- |
| `recipient.name` / `recipientName` | string | 🟢 High (100%) | Legal name of the winning contractor or grantee. |
| `recipient.uei` / `recipientUei` | string | 🟢 High (~99%) | 12-character SAM.gov Unique Entity Identifier (`UEI`). |
| `recipient.parentName` / `parentUei` | string | 🟢 High (~92%) | Ultimate parent company name and parent UEI. |
| `recipient.businessCategories` | array of strings | 🟢 High (~99%) | SAM.gov socio-economic and entity classifications (e.g. `Small Business`, `Women Owned Business`, `Veteran Owned Business`). |
| `recipient.location` | object | 🟢 High (~99%) | Full HQ address: `addressLine1`, `addressLine2`, `city`, `state`, `stateCode`, `zip5`, `zip4`, `county`, `countryCode`, `congressionalCode`. |
| `executiveCompensation` | array of objects | 🟡 Conditional (~35%) | Array of `{ name, amount }` for top 5 officers when the contractor meets FFATA disclosure thresholds (`[]` otherwise). |

##### 🎯 Agency, NAICS, PSC, Set-Aside & Competition

| Field | Type | Coverage | Description |
| :--- | :--- | :--- | :--- |
| `awardingAgency` | object | 🟢 High (100%) | `{ toptierName, toptierCode, toptierAbbrev, subtierName, subtierCode, officeName }`. |
| `fundingAgency` | object | 🟢 High (~98%) | `{ toptierName, subtierName }` providing the treasury funds. |
| `placeOfPerformance` | object | 🟢 High (~99%) | `{ city, state, stateCode, county, zip5, countryCode, congressionalCode }` where work is executed. |
| `naics` | object | 🟢 High (~98%) | 3-tier NAICS hierarchy: `code`/`description` (6-digit), `midtierCode`/`midtierDescription` (4-digit), `toptierCode`/`toptierDescription` (2-digit). |
| `psc` | object | 🟢 High (~98%) | `{ code, description }` Federal Product or Service Code. |
| `setAside` / `setAsideDescription` | object / string | 🟢 High (~86%) | Small-business set-aside code and description (for contracts). |
| `competition` | object | 🟢 High (~95%) | `{ extentCompeted, extentCompetedDescription, numberOfOffers, solicitationProcedures }`. |

***

### 🔁 Pagination & 1,000+ scale

- **Unlocked 1,000+ discovery pagination:** The scraper POSTs to `/api/v2/search/spending_by_award/` at `100 records per page` (`page=1, 2, 3…`), following `page_metadata.hasNext` until `discovered.length >= maxRecords` or all matching awards are retrieved.
- **Honors explicit `maxRecords` on unfiltered runs:** Even if you leave all narrowing filters blank and set `maxRecords: 1000`, the scraper honors your explicit `1000` limit rather than clamping down to `100` (the 100-award sample cap only applies when `maxRecords === 0` on a completely unfiltered run).
- **Parallel detail worker pool:** Discovered awards are enriched concurrently (`maxConcurrency` default `5`, adjustable up to `20`), completing `50` detailed awards in **~12 seconds** and `500` detailed awards in **~35 seconds**.

***

### ⚙️ How to use

1. Open **USAspending Federal Awards Scraper** in the **Apify Console**.
2. Choose your **Award types** (`contracts`, `idvs`, `grants`, etc.) and set any targeting filters (**Awarding agencies**, **Industry NAICS**, **Small-business set-asides**, **Contractor location states**, **Keywords**, or **Minimum award amount**).
3. Keep **Include full award details** (`scrapeAwardDetails: true`) enabled for UEI, address, and executive compensation, or disable it for ultra-fast summary sweeps.
4. Set **Max results** (`maxRecords`: `50` prefilled for a fast `<15s` test run, or `1000+` for full pipeline extraction).
5. Click **Start** and export from the **Awards** or **Recipients + executives** dataset views to **CSV, Excel, or JSON**.

#### Run via Apify API (cURL)

```bash
curl -X POST "https://api.apify.com/v2/acts/haketa~usaspending-scraper/runs?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "awardTypeCategories": ["contracts"],
    "agencyNames": ["Department of Defense"],
    "naicsCodes": ["541512"],
    "minAwardAmount": 500000,
    "scrapeAwardDetails": true,
    "maxRecords": 1000,
    "maxConcurrency": 10
  }'
```

***

### 🐍 Programmatic usage (Python & Node.js)

#### Python (`apify-client`)

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")

run_input = {
    "awardTypeCategories": ["contracts"],
    "agencyNames": ["Department of Defense"],
    "naicsCodes": ["541512", "541330"],
    "setAsideTypes": ["8A", "SDVOSBC", "WOSB"],
    "minAwardAmount": 250000,
    "scrapeAwardDetails": True,
    "maxRecords": 1000,
}

run = client.actor("haketa/usaspending-scraper").call(run_input=run_input)

for award in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(f"{award.get('awardId')} | {award.get('recipientName')} (UEI: {award.get('recipientUei')}) | ${award.get('awardAmount')}")
```

#### Node.js (`apify-client`)

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

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });

const run = await client.actor('haketa/usaspending-scraper').call({
    awardTypeCategories: ['contracts', 'grants'],
    keywords: ['cybersecurity', 'artificial intelligence'],
    scrapeAwardDetails: true,
    maxRecords: 500,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(`Extracted ${items.length} federal awards:`, items[0]);
```

***

### 💡 Tips for best results

- 🔑 **Use `recipientUei` as your master B2G join key:** Every federal contractor has a unique 12-character SAM.gov `UEI`. Join `recipientUei` with SAM.gov entity data, SBA Dynamic Small Business Search, or Clay/Apollo enrichment.
- 👔 **Switch to the "Recipients + executives" dataset tab:** The built-in `recipients` dataset view automatically unwinds `executiveCompensation` so each row is a named C-suite officer with their declared compensation and company UEI.
- ⚡ **Tune `maxConcurrency: 10` and `requestDelay: 100` for 1,000+ detail runs:** The USAspending API handles 10 concurrent detail fetches smoothly, cutting 1,000-record run times to under 60 seconds.

***

### ⚠️ Honest limitations

- **FFATA executive compensation threshold:** Under the Federal Funding Accountability and Transparency Act (FFATA), contractors are only required to disclose top-5 executive pay if ≥80% and ≥$25M of their revenue comes from federal awards and compensation isn't already public via SEC filings. Consequently, `executiveCompensation` is populated on ~25–60% of awards and `[]` on the rest.
- **Assistance vs. procurement fields:** Grants and loans (`grants`, `loans`) use `FAIN`/`URI` instead of `PIID` and do not carry contract-specific `setAside`, `psc`, or `competition.numberOfOffers` fields.

***

### ❓ FAQ

**How many federal awards can I scrape in a single run?**
Tens of thousands. Set `maxRecords: 1000`, `5000`, or `10000+` — the scraper paginates 100 awards per page until your target is reached.

**Do I need an API key, SAM.gov account, or proxy?**
No. USAspending.gov endpoints are public-domain US government infrastructure and run cleanly without API keys or proxies.

**Why should I keep `scrapeAwardDetails: true` enabled?**
The summary search endpoint only returns 14 basic columns (no UEI, no street address, no business categories, no competition offer counts, and no executive compensation). Enabling `scrapeAwardDetails: true` fetches the full `/api/v2/awards/{id}/` record for every award.

**Are there duplicate awards in the output?**
No. Every award is keyed by its unique `generated_internal_id` (`internalAwardId`), ensuring 0% duplicates across pages.

***

### 🔗 Related scrapers

- [EPA ECHO Facility Compliance Scraper](https://apify.com/haketa/epa-echo-scraper) — US facility inspections, violations, and enforcement history.
- [NPI Registry Scraper (7M+ US Healthcare Providers)](https://apify.com/haketa/nppes-npi-registry-scraper) — US healthcare providers and organizations by NPI, taxonomy, and state.
- [H1B Visa Database Scraper](https://apify.com/haketa/h1b-visa-database-scraper) — DOL H1B visa sponsor employers and salary disclosures.

***

### 📋 Changelog

#### v1.2 (2026-11) — Unlocked 1,000+ Unfiltered Pagination & Fast Prefill

- **Unlocked 1,000+ unfiltered runs:** Fixed `NO_FILTER_RUN` logic in `src/main.js` so explicit user `maxRecords > 100` (e.g. `maxRecords: 1000`) is always honored even when no narrowing filter is set; the 100-award sample guard now triggers only when `maxRecords === 0` on an unfiltered run.
- **Fast prefill execution:** Tuned `maxRecords` prefill to `50` so full-detail Console test runs finish in **~12 seconds**.

#### v1.1 (2026-10) — Executive Compensation Unwind View & NAICS Hierarchy

- Added the `recipients` dataset view unwinding `executiveCompensation` into one row per disclosed officer.
- Added 3-tier `naics` hierarchy (`code`, `midtierCode`, `toptierCode`) and stripped null officer slots.

#### v1.0 (2026-09) — Initial Release

- Initial release supporting all 6 federal award categories, 12 filter dimensions, and parallel `/api/v2/awards/` detail enrichment.

# Changelog

This Actor's version history is a separate document: https://apify.com/haketa/usaspending-scraper/changelog.md

# Actor input Schema

## `awardTypeCategories` (type: `array`):

Which categories of federal spending to pull. Pick one or more. Leave as-is to focus on contracts.

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

Optional free-text search across award descriptions. Great for finding specific topics such as cybersecurity, cloud migration, AI, or logistics. Leave empty to browse everything.

## `recipientSearchText` (type: `string`):

Optional. Type part of a contractor / company name to find every award they won (for example Lockheed, Booz Allen, or Microsoft).

## `agencyNames` (type: `array`):

Pick one or more federal agencies to focus on. Leave empty to include every agency.

## `naicsCodes` (type: `array`):

Pick one or more industries to focus on. Leave empty to include every industry.

## `naicsCodesCustom` (type: `array`):

Advanced: add any other NAICS industry codes not in the list above (2 / 4 / 6 digit). Combined with the picks above.

## `setAsideTypes` (type: `array`):

Focus on awards reserved for specific small-business programs. Leave empty to include all awards.

## `recipientLocationStates` (type: `array`):

Only include contractors headquartered in these states. Leave empty for nationwide.

## `placeOfPerformanceStates` (type: `array`):

Only include awards performed in these states. Leave empty for nationwide.

## `timePeriodStart` (type: `string`):

Only include awards active on/after this date. Leave empty to use the last full fiscal year.

## `timePeriodEnd` (type: `string`):

Only include awards active on/before this date. Leave empty for today.

## `minAwardAmount` (type: `integer`):

Only include awards worth at least this much. 0 = no minimum.

## `maxAwardAmount` (type: `integer`):

Only include awards worth at most this much. 0 = no maximum.

## `sortBy` (type: `string`):

How to order the results.

## `sortOrder` (type: `string`):

Show largest/latest first, or smallest/oldest first.

## `scrapeAwardDetails` (type: `boolean`):

Pull the full record for each award — recipient UEI, full address, NAICS hierarchy, set-aside type, executive compensation, place of performance and more. Turn OFF for ultra-fast bulk discovery.

## `maxRecords` (type: `integer`):

Maximum number of awards to return. 0 = unlimited (millions of awards exist, so a limit is recommended).

## `requestDelay` (type: `integer`):

Politeness delay between requests.

## `maxConcurrency` (type: `integer`):

How many award records to fetch in parallel.

## `proxyConfiguration` (type: `object`):

Optional. Runs fine without a proxy — only enable one if you are running very large volumes.

## Actor input object example

```json
{
  "awardTypeCategories": [
    "contracts"
  ],
  "keywords": [
    "cybersecurity"
  ],
  "recipientSearchText": "",
  "agencyNames": [],
  "naicsCodes": [],
  "naicsCodesCustom": [],
  "setAsideTypes": [],
  "recipientLocationStates": [],
  "placeOfPerformanceStates": [],
  "timePeriodStart": "2024-10-01",
  "timePeriodEnd": "",
  "minAwardAmount": 0,
  "maxAwardAmount": 0,
  "sortBy": "Award Amount",
  "sortOrder": "desc",
  "scrapeAwardDetails": true,
  "maxRecords": 50,
  "requestDelay": 250,
  "maxConcurrency": 5,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

Open to view, filter and export all scraped results from this run (JSON, CSV, Excel).

# 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 = {
    "awardTypeCategories": [
        "contracts"
    ],
    "keywords": [
        "cybersecurity"
    ],
    "recipientSearchText": "",
    "agencyNames": [],
    "naicsCodes": [],
    "naicsCodesCustom": [],
    "setAsideTypes": [],
    "recipientLocationStates": [],
    "placeOfPerformanceStates": [],
    "timePeriodStart": "2024-10-01",
    "timePeriodEnd": "",
    "sortBy": "Award Amount",
    "sortOrder": "desc",
    "scrapeAwardDetails": true,
    "maxRecords": 50,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("haketa/usaspending-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 = {
    "awardTypeCategories": ["contracts"],
    "keywords": ["cybersecurity"],
    "recipientSearchText": "",
    "agencyNames": [],
    "naicsCodes": [],
    "naicsCodesCustom": [],
    "setAsideTypes": [],
    "recipientLocationStates": [],
    "placeOfPerformanceStates": [],
    "timePeriodStart": "2024-10-01",
    "timePeriodEnd": "",
    "sortBy": "Award Amount",
    "sortOrder": "desc",
    "scrapeAwardDetails": True,
    "maxRecords": 50,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("haketa/usaspending-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 '{
  "awardTypeCategories": [
    "contracts"
  ],
  "keywords": [
    "cybersecurity"
  ],
  "recipientSearchText": "",
  "agencyNames": [],
  "naicsCodes": [],
  "naicsCodesCustom": [],
  "setAsideTypes": [],
  "recipientLocationStates": [],
  "placeOfPerformanceStates": [],
  "timePeriodStart": "2024-10-01",
  "timePeriodEnd": "",
  "sortBy": "Award Amount",
  "sortOrder": "desc",
  "scrapeAwardDetails": true,
  "maxRecords": 50,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call haketa/usaspending-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,haketa/usaspending-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/XNVXkVdY53fTzRd21/builds/rFRXbj2eSp4278lJs/openapi.json
