# SAM.gov Contract Opportunities with Past Award Winners (`plainrecordlabs/federal-contract-opportunities`) Actor

Search open US federal contract notices from SAM.gov by keyword, NAICS, set-aside and state. Each notice shows who won past contracts at that agency for that NAICS code, from USAspending.gov. Unofficial tool.

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

## Pricing

from $2.50 / 1,000 contract notices

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

## SAM.gov Contract Opportunities with Past Award Winners

Search open US federal contract notices from SAM.gov by keyword, NAICS code, set-aside, state or agency. Each
notice comes with its market history from USAspending.gov: how many contracts the same agency awarded under the
same NAICS code over about three fiscal years, and the five companies that won the most. Federal data has no
"incumbent" field, so these past winners are the closest public signal of who holds similar work today.

Type a keyword or a NAICS code and press Start. You get one row per open notice, newest first.

> This is an unofficial tool, not affiliated with SAM.gov, GSA, the Treasury or any agency. Always read the full
> notice on SAM.gov before you bid. Notices change and get amended.

### What people use it for

- **Small businesses and government contractors:** a daily list of open bids in your NAICS codes and states.
- **Capture and business development teams:** see who already wins this kind of work at this agency before you
  decide to bid.
- **Consultants and bid services:** fresh, filtered notices for clients, ready for a spreadsheet or a CRM.

### Input

| Field | What it does |
|---|---|
| **Keywords** | Notices whose title or description contains any of these words, like `janitorial` or `HVAC`. |
| **Exclude keywords** | Drop notices that contain any of these words. |
| **Search descriptions too** | Off searches titles only. |
| **NAICS codes** | Notices whose NAICS code starts with any of these, like `541512` or `2362`. |
| **Set-aside codes** | Like `SBA`, `8A`, `HZC`, `SDVOSBC` or `WOSB`. The input form lists them all. |
| **States** | Two-letter codes. Uses the place of performance, or the contracting office's state when the notice gives none. |
| **Agency or office contains** | Like `Army`, `Veterans` or `Forest Service`. |
| **Notice types** | Like `Solicitation`, `Sources Sought` or `Presolicitation`. |
| **Open notices only** | On by default. Turn it off to include award notices from the last 90 days. |
| **Response due within (days)** | Only notices due soon. |
| **Posted within (days)** | Only notices posted recently. |
| **Include past award winners** | Adds the `marketHistory` block. On by default. |
| **Include description text** | Adds the description, up to 8,000 characters. |
| **Max results** | A cap on how many notices one run returns. |
| **Only notices not seen in my earlier runs** | Returns only new notices. Pair with a daily schedule for alerts. |

### Output

One item per notice:

```json
{
  "noticeId": "ff5a815a19f348e8a0606ce16ec022d4",
  "title": "Ross Springs Waterline Replacement",
  "solicitationNumber": "1240LT27Q0022",
  "agency": "AGRICULTURE, DEPARTMENT OF",
  "subTier": "FOREST SERVICE",
  "office": "ASHLEY NATIONAL FOREST",
  "noticeType": "Combined Synopsis/Solicitation",
  "postedDate": "2026-10-23",
  "responseDeadline": "2026-11-21T15:00:00-07:00",
  "daysToDeadline": 28,
  "naicsCode": "237110",
  "pscCode": "Z2NE",
  "setAsideCode": "SBA",
  "setAside": "Small Business Set Aside - Total",
  "state": "UT",
  "stateSource": "place of performance",
  "placeOfPerformance": { "city": "Vernal", "state": "UT", "zip": "84078", "country": "USA" },
  "award": null,
  "description": "The Forest Service is seeking bids to replace...",
  "samUrl": "https://sam.gov/workspace/contract/opp/ff5a815a19f348e8a0606ce16ec022d4/view",
  "marketHistory": {
    "source": "USAspending.gov",
    "awardingAgency": "Forest Service",
    "naicsCode": "237110",
    "period": "FY2024 to FY2027 so far",
    "contractAwards": 140,
    "topRecipients": [
      { "name": "WRIGHT BROS LLC", "uei": "QP8VNJ36KNY4", "obligatedUsd": 5015701 }
    ]
  }
}
```

The figures in the example are illustrative. Real values come from the data.

- `marketHistory` covers the whole agency (for example the Forest Service or the Department of the Army) and the
  notice's NAICS code, not the single office. Large agencies buy a lot, so the top recipients there are often big
  companies. It is context for your bid decision, not a list of who will compete.
- `contractAwards` counts contract award records in USAspending for that agency and code since the start of the
  period, including small orders and modifications. `obligatedUsd` is what each company was obligated in that window.
- `marketHistory` is null when a notice has no NAICS code or its agency could not be matched in USAspending (under
  1% of notices today).
- Contracting officer names, emails and phone numbers are not included. Emails and phone numbers are removed from
  titles and descriptions too. Open `samUrl` to see who to contact.

### Where the data comes from

- **Notices:** the SAM.gov Contract Opportunities public data extract, which SAM.gov rebuilds once a day. We load it
  into our index each morning (UTC). The index holds every active notice with a future deadline plus anything
  posted in the last 90 days, about 39,000 notices.
- **Market history:** the USAspending.gov API, refreshed once a week for each agency and NAICS pair.
- This Actor reads our index only. It never scrapes the SAM.gov website.

### FAQ

**How do I export SAM.gov contract opportunities to Excel or CSV?**
Run a search, then download the results from the Storage tab as CSV, Excel or JSON. Each row is one notice with its
deadline, NAICS code, set-aside, place of performance and a link back to SAM.gov.

**How do I get a daily list of new SAM.gov bids in my NAICS codes?**
Enter your NAICS codes and states, turn on **Only notices not seen in my earlier runs**, and add a daily schedule in
Apify Console. Each run then returns only notices you have not had before. A webhook or one of Apify's integrations
can send them on.

**How do I find small business, 8(a), SDVOSB, WOSB or HUBZone set-aside contracts?**
Use **Set-aside codes**: `SBA` for small business, `8A`, `SDVOSBC`, `WOSB` or `HZC`. The input form lists every code.

**Who is the incumbent on this contract?**
Federal data has no incumbent field. `marketHistory` shows the five companies that won the most of this agency's
work under the same NAICS code, which is the closest public signal. Check the notice itself on SAM.gov for any
named incumbent or earlier contract number.

**Do I need a SAM.gov account or API key?**
No. The Actor reads our own index of SAM.gov's public daily extract.

**How current is it?**
Notices load once a day, each morning UTC, from SAM.gov's daily extract. Market history refreshes weekly.

### Pricing

You pay per notice returned. The price is on the Pricing tab. **Max results** caps what one run can cost.

### Feedback

Need a field, a filter or a fix? Open an issue on the Issues tab.

# Actor input Schema

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

Find notices whose title or description contains any of these words, for example "janitorial", "cybersecurity" or "HVAC". Matches the start of a word.

## `excludeKeywords` (type: `array`):

Drop notices whose title or description contains any of these words.

## `searchDescriptions` (type: `boolean`):

On: keywords match the title or the full description. Off: the title only.

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

Keep notices whose NAICS code starts with any of these, for example 541512 or 5415 or 2362.

## `setAsideCodes` (type: `array`):

Keep notices with any of these set-aside codes: SBA (total small business), SBP (partial), 8A, 8AN, HZC (HUBZone), SDVOSBC, SDVOSBS, WOSB, WOSBSS, EDWOSB, VSA, ISBEE, NONE.

## `states` (type: `array`):

Two-letter state codes, for example VA or TX. Uses the place of performance, or the contracting office's state when the notice gives no place.

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

Keep notices whose department, agency or office name contains any of these, for example "Army", "Veterans" or "Forest Service".

## `noticeTypes` (type: `array`):

Keep only these types: Solicitation, Combined Synopsis/Solicitation, Presolicitation, Sources Sought, Special Notice, Award Notice, Justification. Empty = all.

## `openOnly` (type: `boolean`):

Keep only notices whose response deadline is today or later. Turn off to include award notices and notices without a deadline from the last 90 days.

## `deadlineWithinDays` (type: `integer`):

Keep notices due in the next N days. 0 = any deadline.

## `postedWithinDays` (type: `integer`):

Keep notices posted in the last N days. 0 = any.

## `includeMarketHistory` (type: `boolean`):

Add the marketHistory block: contracts awarded by the same agency for the same NAICS code over about three fiscal years, and the top 5 recipients by amount (USAspending.gov).

## `includeDescription` (type: `boolean`):

Add the notice description (up to 8,000 characters, emails and phone numbers removed).

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

Return at most this many notices, newest first. 0 = no limit.

## `onlyNew` (type: `boolean`):

Remembers notice IDs between your runs (in your own key-value store) and returns only new ones. Pair with an Apify schedule for daily alerts.

## Actor input object example

```json
{
  "keywords": [
    "maintenance"
  ],
  "excludeKeywords": [],
  "searchDescriptions": true,
  "naicsCodes": [],
  "setAsideCodes": [],
  "states": [],
  "agencies": [],
  "noticeTypes": [],
  "openOnly": true,
  "deadlineWithinDays": 0,
  "postedWithinDays": 0,
  "includeMarketHistory": true,
  "includeDescription": true,
  "maxResults": 20,
  "onlyNew": false
}
```

# Actor output Schema

## `notices` (type: `string`):

One item per contract notice that matched, with a marketHistory block.

## `summary` (type: `string`):

How many notices were returned, how many carry market history, and when the index was built.

# 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 = {
    "keywords": [
        "maintenance"
    ],
    "maxResults": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("plainrecordlabs/federal-contract-opportunities").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 = {
    "keywords": ["maintenance"],
    "maxResults": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("plainrecordlabs/federal-contract-opportunities").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 '{
  "keywords": [
    "maintenance"
  ],
  "maxResults": 20
}' |
apify call plainrecordlabs/federal-contract-opportunities --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,plainrecordlabs/federal-contract-opportunities"
        }
    }
}
```

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/ah7YpGvOHtUcHD2xH/builds/UjjADYUeaQcNKFlRH/openapi.json
