# Government Contract Scraper - USAspending (`datalayer/federal-contract-awards`) Actor

USAspending has no period-of-performance filter, and sorting by end date returns 1995 one way and 3017 the other. So you cannot ask which contracts expire soon. This computes it, flags the corrupt dates, and ranks expiring awards by value with incumbent, outlay rate and vendor concentration.

- **URL**: https://apify.com/datalayer/federal-contract-awards.md
- **Developed by:** [Datalayer](https://apify.com/datalayer) (community)
- **Categories:** Business, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.70 / 1,000 awards

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/platform/actors/running/actors-in-store#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

## USAspending Scraper — Federal Contracts & Recompetes

Scrape **US federal contract awards** from USAspending, with the thing the API
will not give you: **which contracts are about to end**.

That moment is the whole basis of a government-sales pipeline. It is when an
incumbent can be displaced, when a recompete goes out, and when a bid team needs
to already be in the room. USAspending publishes every award — and cannot filter
on it.

### Why this is not a thin API wrapper

Two facts, both verified live on 2026-08-14:

**1. There is no period-of-performance filter.** `time_period.date_type` accepts
only `action_date`, `date_signed`, `last_modified_date` and `new_awards_only`.
Ask for anything else and the API returns 422 and lists them. So *"expiring in
the next 180 days"* cannot be requested. It has to be pulled and computed.

**2. Sorting by End Date does not rescue you.** Ascending, the first page comes
back with an award that **starts in 1999 and ends in 1995**. Descending, the top
rows are **3017-04-30**, 2100-12-31 and 2099-12-31. Both ends of that sort are
data-entry garbage, so a naive "sort by end date" recompete list is worthless.

This actor therefore computes `daysUntilEnd` itself, flags implausible dates
rather than trusting them, and keeps them out of the radar. In a live sample of
100 top-value contracts, **1 carried a corrupt date**.

### What you get

**The recompete radar.** Every award ending inside your window, biggest money
first, with the incumbent, the sub-agency and the value. A live run on
2026-08-14 surfaced:

| Incumbent | Value | Ends | Days | Sub-agency |
|---|---|---|---|---|
| The Boeing Company | $22.4B | 2026-09-30 | 47 | NASA |
| TriWest Healthcare Alliance | $8.4B | 2026-12-31 | 139 | Defense Health Agency |
| The Boeing Company | $7.6B | 2026-08-31 | 17 | Department of the Navy |
| Chemonics International | $6.7B | 2026-11-28 | 106 | USAID |

**Outlay rate.** How much of the award has actually been paid out. A contract at
5% outlay two months from its end date is not really being delivered — that gap
is a bid signal, and it is one join the API makes you do yourself.

**Vendor concentration per agency.** What share of an agency's spend in your
slice went to its single largest contractor. In the same live run, NASA sat at
**67.9%** to one vendor and DoD at 26.4%. High concentration is both a
competitive warning and a target.

**Grants too.** Contracts, IDVs, grants, loans and direct payments are all
supported. Assistance awards carry CFDA numbers instead of NAICS, and the actor
requests the right field set per family rather than asking for columns that come
back null.

### Who uses this

- **Government-sales and capture teams** — building a recompete pipeline instead
  of waiting for a solicitation to appear.
- **Competitive intel** — watching a named competitor's book of business and
  when it expires.
- **Small business and set-aside contractors** — filtering to SBA, 8(a) or
  SDVOSB work in their NAICS.
- **Analysts and journalists** — agency spend concentration and vendor share.

### Input

| Field | Type | Default | Notes |
|---|---|---|---|
| `awardTypes` | array | `["contracts"]` | contracts, idvs, grants, loans, direct\_payments |
| `recompeteWindowDays` | integer | `180` | Computed locally — the API cannot filter on it |
| `expiringOnly` | boolean | `false` | Drop award rows outside the window |
| `agency` | string | `""` | Exact top-tier name, e.g. `Department of Defense` |
| `keywords` | array | `[]` | Free-text search across the award |
| `naicsCodes` / `pscCodes` | array | `[]` | Contracts and IDVs only |
| `setAsideTypes` | array | `[]` | e.g. `SBA`, `8AN`, `SDVOSBC` |
| `recipientSearch` | string | `""` | Watch one contractor |
| `placeOfPerformanceStates` | array | `[]` | Two-letter state codes |
| `minAwardAmount` / `maxAwardAmount` | integer | `0` | 0 means no bound |
| `fromDate` / `toDate` | string | `""` | Action date; defaults to the last two years |
| `maxAwardsPerType` | integer | `200` | 100 per page, largest first |

Agency summaries are always computed on **everything** collected, even with
`expiringOnly` on — otherwise the concentration figures would describe your
filter rather than the agency.

### Output

**`award`** — `awardId`, `recipientName`, `awardAmount`, `totalOutlays`,
`outlayRatePercent`, `awardingAgency`, `awardingSubAgency`, `fundingAgency`,
`startDate`, `endDate`, `durationDays`, `daysUntilEnd`, `isExpiringSoon`,
`isExpired`, `hasImplausibleDates`, NAICS/PSC, place of performance, `awardUrl`.

**`recompete`** — the expiring subset, repeated as its own row type so the
pipeline reads on its own, sorted biggest money first.

**`agency_summary`** — `awards`, `totalAwardValue`, `medianAwardValue`,
`distinctRecipients`, `topRecipient`, `topRecipientSharePercent`,
`expiringSoonAwards`, `expiringSoonValue`, `awardsWithImplausibleDates`.

### Limits

- `daysUntilEnd` reflects the **current** period of performance. An option year
  exercised after the run will move it.
- Award amounts can be **negative** on a de-obligation. That is real data, not a
  parsing error, and the outlay rate is suppressed rather than reported as
  nonsense.
- USAspending data lags contract actions by days to weeks.

### Pricing

Pay per event. $0.001 per award, $0.01 per recompete, $0.05 per agency summary.

# Actor input Schema

## `awardTypes` (type: `array`):

Contracts are definitive awards. IDVs are the vehicles orders are placed against. Grants, loans and direct payments are assistance awards and carry CFDA numbers instead of NAICS.

## `agency` (type: `string`):

Exact top-tier agency name, e.g. Department of Defense, Department of Veterans Affairs. Leave empty for all.

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

Free-text search across the award, e.g. cybersecurity, cloud migration.

## `recipientSearch` (type: `string`):

Restrict to one contractor, e.g. Booz Allen. Useful for watching a competitor's book of business.

## `expiringOnly` (type: `boolean`):

Drop award rows that are not inside the recompete window. Agency summaries are still computed across everything.

## `recompeteWindowDays` (type: `integer`):

An award counts as expiring if its period of performance ends within this many days. USAspending cannot filter on this, so it is computed from the returned dates.

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

Industry codes, e.g. 541512 for computer systems design. Contracts and IDVs only.

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

Product and service codes, e.g. D307. Contracts and IDVs only.

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

e.g. SBA for small business, 8AN for 8(a), SDVOSBC for service-disabled veteran-owned. Leave empty for all.

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

Two-letter US state codes, e.g. VA, MD. Leave empty for all.

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

Filter out small awards. 0 means no minimum.

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

0 means no maximum.

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

ISO date. Filters on award action date, the only date USAspending will filter on. Defaults to two years ago.

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

ISO date. Defaults to today.

## `includeAwards` (type: `boolean`):

Return one row per award.

## `includeRecompetes` (type: `boolean`):

Return the expiring awards again as their own row type, sorted biggest money first.

## `includeAgencySummary` (type: `boolean`):

Per-agency spend, vendor concentration and expiring value.

## `maxAwardsPerType` (type: `integer`):

USAspending serves 100 per page. Awards come back largest first.

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

Optional. USAspending is a public API and does not require a proxy.

## Actor input object example

```json
{
  "awardTypes": [
    "contracts"
  ],
  "agency": "",
  "keywords": [],
  "recipientSearch": "",
  "expiringOnly": false,
  "recompeteWindowDays": 180,
  "naicsCodes": [],
  "pscCodes": [],
  "setAsideTypes": [],
  "placeOfPerformanceStates": [],
  "minAwardAmount": 0,
  "maxAwardAmount": 0,
  "fromDate": "",
  "toDate": "",
  "includeAwards": true,
  "includeRecompetes": true,
  "includeAgencySummary": true,
  "maxAwardsPerType": 200,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `recompetes` (type: `string`):

Contracts ending inside the window, biggest money first. The displacement pipeline.

## `awards` (type: `string`):

Every matching award with days until end, outlay rate and NAICS/PSC.

## `agencies` (type: `string`):

Per-agency spend, vendor concentration and expiring value.

## `csv` (type: `string`):

Everything as a CSV download.

## `runSummary` (type: `string`):

Counts, the window used, and how many awards carry corrupt dates.

# 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 = {
    "recompeteWindowDays": 180,
    "maxAwardsPerType": 200
};

// Run the Actor and wait for it to finish
const run = await client.actor("datalayer/federal-contract-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 = {
    "recompeteWindowDays": 180,
    "maxAwardsPerType": 200,
}

# Run the Actor and wait for it to finish
run = client.actor("datalayer/federal-contract-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 '{
  "recompeteWindowDays": 180,
  "maxAwardsPerType": 200
}' |
apify call datalayer/federal-contract-awards --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,datalayer/federal-contract-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/ajPF9xBSDeppcB11B/builds/ToqCELRaQAIc043C7/openapi.json
