# USA Spending Federal Awards Scraper (`scrapyx/usaspending-scraper`) Actor

Search every US federal award on USAspending.gov -- contracts, grants, loans, direct payments, IDVs. Filter by agency, recipient, keyword, NAICS/PSC/CFDA, place, amount, disaster codes. Keyset pagination past 50k; full award detail with subawards and executive comp. Keyless.

- **URL**: https://apify.com/scrapyx/usaspending-scraper.md
- **Developed by:** [Ibnu Adzim](https://apify.com/scrapyx) (community)
- **Categories:** Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.10 / 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

## USAspending.gov Scraper (Federal Contracts, Grants, Loans)

Search **[USAspending.gov](https://www.usaspending.gov)** — the US Treasury's
official record of **every federal award**: contracts, grants, loans, direct
payments and IDVs. Keyless, no login; US government work is public domain.

- **`awards`** — the `spending_by_award` search. Pick an **award group**
  (contracts / grants / loans / direct-payments / IDVs / other) and filter by
  agency, recipient, keyword, NAICS / PSC / CFDA code, place of performance,
  amount band, recipient business type, or disaster-relief code. **Keyset
  pagination** from the first request — no 50,000-result ceiling.
- **`award-detail`** — a list of `generated_internal_id`s → the full award
  record each: total obligation & outlay, sub-award count, recipient UEI /
  parent, executive compensation, CFDA programs, competition & set-aside
  detail, place & period of performance.

| Record type | One per | Carries |
| --- | --- | --- |
| `SEARCH_SUMMARY` | search run | `awardGroup`, `awardTypeCodes`, `filtersApplied`, `resultsReturned`, `pagesFetched` |
| `AWARD` | award | `generatedInternalId`, `awardId`, `recipientName`, `awardAmount` / `loanValue`, `awardingAgency`, `startDate` / `endDate`, `naicsCode`, `pscCode`, `cfdaNumber`, `defCodes`, `usaspendingUrl` — plus obligation/outlay, sub-awards, executive comp etc. on `award-detail` |
| `ERROR` | bad input / missing award | `_error` + `_errorDetail` |

Every `AWARD` row carries the verbatim API record in `raw` (drop with
`slimOutput`).

### Things this API will mislead you about

Each is measured, and each has a scenario in
`tests/smoke/usaspending-scraper_traps.sh` (10/10 passing).

**`page`-based pagination stops at 50,000 results** (`page × limit`). Past it
the API returns HTTP 422 telling you to switch to keyset. This Actor keyset-
paginates (`last_record_sort_value` + `last_record_unique_id`) from the first
request, so it has no ceiling.

**`award_type_codes` must all be from ONE group** — a contract code plus a
grant code → HTTP 422. The `awardGroup` input picks a consistent set; only a
`rawFilters` override can break this.

**The `sort` field must also be in the requested `fields`** — handled
automatically. And the sort field must be valid *for the award group*: loans
have no `Award Amount` (use `Loan Value`). Each group has a sensible default.

**`fields` names differ by award group** — contracts expose `NAICS` / `PSC`,
grants `CFDA Number`, loans `Loan Value` / `Subsidy Cost`. A name that is
wrong for the group comes back `null`, not an error.

**`time_period` is optional** — omitting it searches back to FY2008. This
Actor defaults to the last 5 years unless you give dates.

**A bad `generated_internal_id` is an honest HTTP 404.** A transient HTML 4xx
under a request burst (a proxy hiccup, not a validation error) is retried.

**Agency names are matched exactly, case included** — USAspending answers
`"department of defense"` with **0 awards and no error** (the correctly
capitalised name returned 322). This Actor looks every `awardingAgency` /
`fundingAgency` up in USAspending's own agency list first, so any
capitalisation, the usual abbreviations (`dod`, `NASA`, `hhs`) and an
unambiguous word (`commerce`, `energy`) work; an ambiguous word (`defense`)
lists the candidates, and an
unknown name stops the run with the list of valid names instead of an empty
result. The summary shows the names actually sent (`agencyNamesResolved`).

**"Awards in 2026" includes awards from years ago** — the default
`dateType` (`action_date`) matches any award with activity in the window,
and `awardAmount` is the award's lifetime amount. Use
`dateType: new_awards_only` for awards first signed in the window, and read
`baseObligationDate` (the first obligation, i.e. the signing date) rather
than `startDate`, which is the period of performance and is often backdated.

**Many contract descriptions carry an `IGF::..::IGF` code** (an
inherently-governmental-function marker) at the start, the end, or as the
whole text. `description` is kept verbatim; `igfCode` holds the marker and
`descriptionClean` the text without it.

**The summary gives the total** — `matchingAwards` is USAspending's own
count for the same filters, next to `resultsReturned`. If a request fails
after some pages, the rows already read are kept and the summary says
`stoppedBecause: error_after_partial_results`.

### Notes on cost

`awards`: one request per 100 results. `award-detail`: one request per id.
No proxy needed.

# Actor input Schema

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

`awards` runs the spending\_by\_award search. `award-detail` fetches the full record for specific award ids.

## `awardGroup` (type: `string`):

`awards` mode. USAspending requires all award types to be from ONE group. This picks the type codes and the group-appropriate output fields.

## `awardIds` (type: `array`):

`award-detail` mode. One per line: a `generated_internal_id` (`CONT_AWD_...`, `CONT_IDV_...`, `ASST_NON_...`, `ASST_AGG_...`) from an `awards` row, or a `https://www.usaspending.gov/award/...` URL.

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

`awards` filter. Free-text match across award descriptions and recipient names.

## `recipientSearchText` (type: `array`):

`awards` filter. Match the recipient (company / organisation) name, e.g. `Lockheed Martin`.

## `awardingAgency` (type: `array`):

`awards` filter. Top-tier agency by name or abbreviation, any capitalisation: `DOD`, `nasa`, `Department of Health and Human Services`. Names are checked against USAspending's own agency list (an unknown name stops the run with the valid list, instead of silently returning nothing).

## `fundingAgency` (type: `array`):

`awards` filter. Funding agency, same rules as awarding agency (name or abbreviation, any case).

## `fromDate` (type: `string`):

`awards` filter. `YYYY-MM-DD`. Defaults to 5 years ago if neither date is given (the API otherwise searches back to FY2008).

## `toDate` (type: `string`):

`awards` filter. `YYYY-MM-DD`. Defaults to today.

## `dateType` (type: `string`):

`awards` filter. Which date the window applies to: `action_date` (default), `date_signed`, `last_modified_date`, `new_awards_only`.

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

`awards` filter.

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

`awards` filter.

## `placeOfPerformanceState` (type: `string`):

`awards` filter. 2-letter US state code (`CA`, `TX`).

## `placeOfPerformanceCountry` (type: `string`):

`awards` filter. 3-letter code (`USA`).

## `recipientLocationState` (type: `string`):

`awards` filter. 2-letter US state code.

## `recipientLocationCountry` (type: `string`):

`awards` filter. 3-letter code.

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

`awards` filter (contracts/IDVs). Industry codes, e.g. `336414` (space vehicle manufacturing). Prefixes work (`3364`).

## `pscCodes` (type: `array`):

`awards` filter (contracts/IDVs). Product/service codes, e.g. `AR62`, `R425`.

## `cfdaNumbers` (type: `array`):

`awards` filter (grants/direct payments/loans). e.g. `81.049`, `93.243`.

## `recipientTypeNames` (type: `array`):

`awards` filter. e.g. `small_business`, `woman_owned_business`, `minority_owned_business`, `nonprofit`, `higher_education`.

## `defCodes` (type: `array`):

`awards` filter. Supplemental-appropriation codes — COVID-19 relief is `L`,`M`,`N`,`O`,`P`,`U`; infrastructure (IIJA) is `Z`,`1`.

## `setAsideTypeCodes` (type: `array`):

`awards` filter (contracts). e.g. `SBA` (small business), `8AN` (8(a)), `SDVOSBC` (service-disabled veteran).

## `rawFilters` (type: `object`):

Merged into the `filters` object verbatim. See api.usaspending.gov/docs (spending\_by\_award).

## `sort` (type: `string`):

`awards` mode. A display field name, e.g. `Award Amount`, `Start Date`, `Recipient Name`. Must be valid for the award group (loans have no `Award Amount`). Default is the group's amount field.

## `order` (type: `string`):

`awards` mode. `desc` (largest / newest first) or `asc`.

## `slimOutput` (type: `boolean`):

By default every AWARD row carries the verbatim API record in `raw`.

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

`awards` mode cap. Keyset pagination is used, so this can exceed 50,000 (the `page`-offset ceiling does not apply).

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

Parallel in-flight requests (matters for `award-detail` mode).

## `minRequestInterval` (type: `number`):

Politeness pacing for a government API. USAspending's limits are generous.

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

Optional. No anti-bot layer, so a proxy is OFF by default.

## Actor input object example

```json
{
  "mode": "awards",
  "awardGroup": "contracts",
  "dateType": "",
  "order": "desc",
  "slimOutput": false,
  "maxResults": 1000,
  "maxConcurrency": 3,
  "minRequestInterval": 0.4,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `items` (type: `string`):

One row per scraped record. See the dataset's default view for field definitions.

# 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("scrapyx/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 = {}

# Run the Actor and wait for it to finish
run = client.actor("scrapyx/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 '{}' |
apify call scrapyx/usaspending-scraper --silent --output-dataset

```

## MCP server setup

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