# SAM.gov Scraper: Federal Contract Opportunities & Awards-No Key (`upward_enterprises/sam-gov-contract-radar`) Actor

$2 per 1,000 opportunities, no API key, no quota. Federal contract opportunities from SAM.gov matched to your NAICS codes, keywords, set-asides, agencies, and states, with contacts, deadlines, and links, plus the largest USAspending awards signed recently for the same codes.

- **URL**: https://apify.com/upward\_enterprises/sam-gov-contract-radar.md
- **Developed by:** [Upward Enterprises](https://apify.com/upward_enterprises) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.20 / 1,000 opportunities

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?

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

## SAM.gov Scraper: Federal Contract Opportunities & Awards (No API Key)

**$2 per 1,000 opportunities ($1.20 on the Gold tier), $1 per 1,000 awards, no start fee, no API key. On a schedule, only rows you have not received before are billed.**

Federal contract opportunities from SAM.gov, matched to the work you actually do. Give it your NAICS codes, keywords, set-asides, states, or agencies, and get every matching notice from the last N days with its deadline, contracting officer contact, place of performance, and link. Turn on awards and it adds the largest contracts USAspending.gov recorded as signed in the look-back window for the same NAICS codes (and states, if you set any): who won, from which agency, for how much.

Built on SAM.gov's public daily extract of every active notice, so there is no API key to create and no 10-requests-a-day quota. The extract is newest first and the Actor stops reading as soon as it passes your date window, so a one-week radar reads about 20 MB and finishes in seconds.

### What you get

**Opportunity rows** (`kind: "opportunity"`), one per matching notice, newest first:

```json
{
  "kind": "opportunity",
  "noticeId": "24aa2d1a239f4cd7b9a767eccea783b5",
  "title": "Custom Software Development for Field Systems",
  "solicitationNumber": "W912-26-R-0001",
  "noticeType": "Solicitation",
  "baseType": "Presolicitation",
  "postedDate": "2026-09-09",
  "responseDeadline": "2026-09-24T14:00:00-04:00",
  "daysToDeadline": 14.3,
  "archiveDate": "2026-10-15",
  "archiveType": "auto15",
  "active": true,
  "department": "DEPT OF DEFENSE",
  "subTier": "DEPT OF THE ARMY",
  "office": "W6QM ACC-APG",
  "cgac": "097",
  "fpdsCode": "2100",
  "aacCode": "W912",
  "naicsCode": "541511",
  "pscCode": "D302",
  "setAside": "Total Small Business Set-Aside (FAR 19.5)",
  "setAsideCode": "SBA",
  "placeOfPerformance": { "street": null, "city": "Des Moines", "state": "IA", "zip": "50309", "country": "USA" },
  "popState": "IA",
  "contractingOffice": { "city": "ABERDEEN PROVING GROUND", "state": "MD", "zip": "21005", "country": "USA", "organizationType": "OFFICE" },
  "primaryContact": { "name": "Jane Doe", "title": "Contract Specialist", "email": "jane.doe@army.mil", "phone": "555-0100" },
  "secondaryContact": null,
  "award": null,
  "additionalInfoLink": null,
  "url": "https://sam.gov/opp/24aa2d1a239f4cd7b9a767eccea783b5/view",
  "description": "The Army requires custom software development and cloud migration services ...",
  "fetchedAt": "2026-09-10T12:00:00.000Z"
}
```

Award notices carry an `award` object with `number`, `date`, `amount`, and `awardee`. Contacts are the contracting officers SAM.gov publishes on the notice. `description` is the full text SAM.gov includes in the extract (SAM.gov itself caps it at roughly 32,000 characters).

**Amendments.** SAM.gov gives every amendment a new notice id and the daily extract keeps the old versions too. By default the Actor delivers one row per notice, the current version, confirmed against SAM.gov's notice history (with the newest posted date as the fallback). `postedDate` is therefore the date the current version was published, so an amended notice re-enters your window. Turn "Collapse amendments" off to get every version.

**Award rows** (`kind: "award"`), when USAspending awards are on, largest first per NAICS code:

```json
{
  "kind": "award",
  "awardId": "W519TC25F0208",
  "recipient": "EXAMPLE FEDERAL SYSTEMS LLC",
  "awardingAgency": "Department of Defense",
  "awardingSubAgency": "Department of the Army",
  "amount": 48250000,
  "startDate": "2026-03-14",
  "endDate": "2031-03-13",
  "description": "ENTERPRISE SOFTWARE MODERNIZATION SUPPORT",
  "naicsCode": "541511",
  "naicsDescription": "CUSTOM COMPUTER PROGRAMMING SERVICES",
  "pscCode": "D302",
  "pscDescription": "IT AND TELECOM- SYSTEMS DEVELOPMENT",
  "popState": "VA",
  "naicsQuery": "541511",
  "url": "https://www.usaspending.gov/award/CONT_AWD_W519TC25F0208_9700_W519TC23D0005_9700",
  "fetchedAt": "2026-09-10"
}
```

Awards are contracts (types A to D) signed in the look-back window, restricted to your place-of-performance states when you set any, sorted by total award amount. An award is delivered once per run even when several of your codes match it. `naicsQuery` says which of your codes produced the row. USAspending filters NAICS at 2, 4, or 6 digits, so a 3- or 5-digit code fetches awards one level up (541 as 54, 54151 as 5415); the opportunity filter still uses your exact prefix.

**One summary row** (`kind: "summary"`, free) reports how many rows were skipped as already delivered (`alreadyDeliveredOpportunities`, `alreadyDeliveredAwards`), how many notices were scanned and matched, how many megabytes were read, the date window, the extract's `extractLastModified` time, why the scan stopped (`stopReason`: `date-window`, `max-items`, `end-of-file`, or `stopped` at your spending cap), how many amendment groups were collapsed, and `awardsErrors` for any NAICS code whose USAspending request failed after retries, so an empty result explains itself.

Filter on `kind` to keep one row type; the Console views **Opportunities** and **Awards** pick the useful columns for each.

### Input

| Field | What it does |
|---|---|
| NAICS codes | 2 to 6 digits each; a shorter code matches everything under it. Empty matches any NAICS. Awards for 3- or 5-digit codes are fetched one level up. |
| Keywords | Case-insensitive, matched in title and description; curly quotes and dashes are folded so plain typing matches. Any keyword matches unless "Require every keyword" is on. |
| Notice types | Solicitation, Combined Synopsis/Solicitation, Presolicitation, Sources Sought, Special Notice, Award Notice, Justification, Consolidate/(Substantially) Bundle, Sale of Surplus Property. Empty means all types, including any new ones SAM.gov adds. |
| Set-asides | SAM.gov set-aside codes such as `SBA`, `8A`, `HZC`, `SDVOSBC`, `WOSB`, `EDWOSB`, `VSA`. Empty means any, including unrestricted. |
| Place-of-performance states | Two-letter codes. Also restricts USAspending awards to these places of performance. Empty means anywhere. |
| Agencies | Text matched against department, sub-tier, and office names. Official names in either order work: "Department of Veterans Affairs" matches the extract's "VETERANS AFFAIRS, DEPARTMENT OF". |
| PSC codes | Product/service code prefixes such as `D302`, `70`, `R4`. |
| Posted within (days) | Default 7. The extract is newest first, so small windows are fast; a year reads the whole file. |
| Skip passed deadlines | Default on. Applies to notices that ask for a response; award notices and justifications keep the closing date they inherit. |
| Active notices only | Default on. |
| Max opportunities | Default 200, newest first. |
| Collapse amendments | Default on. |
| Only new since last run | Default on. Remembers what each snapshot name has delivered (90 days) and skips it next time. Turn off to re-deliver everything in the window. |
| Snapshot name | Which memory "only new" uses; kept on your account as a key-value store named `sam-gov-contract-radar-<name>`. Give each schedule its own name. |
| Include USAspending awards | Default on; needs at least one NAICS code. |
| Awards look-back (months) | Default 12. |
| Max awards per NAICS code | Default 25 unique awards. |

Example: every open small-business solicitation for IT services in Iowa or Nebraska, posted this month, with the top 50 Iowa and Nebraska awards per code:

```json
{ "naicsCodes": ["5415"], "setAsideCodes": ["SBA", "SBP"], "states": ["IA", "NE"], "noticeTypes": ["Solicitation", "Combined Synopsis/Solicitation"], "postedWithinDays": 30, "maxAwardsPerNaics": 50 }
```

### Pricing

| Event | Free | Bronze | Silver | Gold and above |
|---|---|---|---|---|
| Opportunity | $0.002 | $0.0018 | $0.0015 | $0.0012 |
| Award | $0.001 | $0.0009 | $0.00075 | $0.0006 |

With "Only new since last run" on (the default), a daily schedule bills only the notices and awards that appeared since your last run: the first run for two NAICS codes might deliver 40 opportunities and 50 awards for $0.13, and each later day about 5 new notices for a cent. The summary row is free, and so is an empty run. Set a maximum total charge on the run to cap spend; the Actor stops cleanly when it is reached and never delivers rows it could not bill.

### Use cases

- **Business development**: a daily run for your NAICS codes and set-asides into Slack or a spreadsheet, replacing a five-figure subscription.
- **Capture teams**: pull the awards for a NAICS code to see which incumbents and agencies to target.
- **Proposal shops and consultants**: one run per client profile, scheduled, with contacts and deadlines ready to work.
- **AI agents**: ask "what federal IT solicitations opened this week in Iowa" through the Apify MCP server and get rows, not screenshots.

### Data source and limits

- Opportunities come from SAM.gov's public "Contract Opportunities" daily extract, the same file published for data.gov. SAM.gov rebuilds it once a day, observed around 03:30 UTC (23:30 US Eastern), and each build contains notices posted through the previous Eastern calendar day. Schedule daily runs after that (05:00 UTC or later); a run before the rebuild reads the previous day's file, so `postedWithinDays: 1` returns nothing and a longer window is a day behind. The summary row's `extractLastModified` tells you which build a run read.
- If the connection drops mid-download the Actor resumes from where it stopped and refuses to continue if the file was replaced meanwhile, so a run never mixes two builds.
- Awards come from the USAspending.gov API (contracts, types A to D), which has no key and no published quota; the Actor makes one request at a time and retries with backoff. A code whose request still fails is listed in the summary row's `awardsErrors`.
- Attachments are not downloaded. The `url` opens the notice on SAM.gov where attachments live; `additionalInfoLink` is included when the agency provided one.
- Contacts are the official contracting-office contacts published with each notice.
- At the end of each run the Actor reports run counts (rows delivered, events charged, duration, status) to its maintainer's dashboard. It never sends your input, your results, or anything about your account.

### About

Built and maintained by **Upward Enterprises · AI & API Services** (Iowa, USA). Public-data tools for people and AI agents, with pay-per-record pricing and no keys to manage.

### Changelog

- **0.1** (2026-09-10): first release.

# Actor input Schema

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

Your NAICS codes, 2 to 6 digits each. A shorter code matches every notice under it (5415 matches 541511, 541512, ...). USAspending awards are filtered at 2, 4, or 6 digits, so a 3- or 5-digit code fetches awards one level up. Leave empty to match any NAICS.

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

Words or phrases to look for in the title and description, case-insensitive. A notice matches if it contains any of them (or all, see below). Leave empty to skip keyword matching.

## `keywordsMatchAll` (type: `boolean`):

On: a notice must contain all keywords. Off (default): any keyword is enough.

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

Which notice types to include. Empty means all types, including any new ones SAM.gov adds.

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

Set-aside codes to require, e.g. SBA (Total Small Business), SBP (Partial Small Business), 8A, 8AN, HZC, HZS, SDVOSBC, SDVOSBS, WOSB, WOSBSS, EDWOSB, EDWOSBSS, VSA, VSS, ISBEE, BICiv, LAS, IEE. Empty means any, including unrestricted.

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

Two-letter state codes for the place of performance, e.g. IA, TX, VA. Applies to notices and, when awards are on, also restricts USAspending awards to those places of performance. Empty means anywhere.

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

Text to look for in the department, sub-tier, or office name, e.g. "Veterans Affairs", "Department of the Army", "NASA". Official names in either order work ("Department of Defense" and "DEPT OF DEFENSE" both match). Empty means any agency.

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

PSC / FSC codes or prefixes, e.g. D302, 70, R4. Empty means any.

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

Only notices posted in the last N days. The extract is newest first, so small windows are fast.

## `deadlineNotPassed` (type: `boolean`):

Skip notices whose response deadline is already in the past.

## `activeOnly` (type: `boolean`):

Only keep notices SAM.gov marks Active (drops archived and inactive ones).

## `maxItems` (type: `integer`):

Stop after this many matching opportunities (newest first).

## `dedupeAmendments` (type: `boolean`):

SAM.gov gives every amendment a new notice id and the daily extract keeps the old versions too. On (default): deliver only the current version of each notice, confirmed against SAM.gov's notice history. Off: deliver every version.

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

On (default): remember what this input has already delivered (under the snapshot name) and deliver only notices and awards you have not received before, so a daily schedule is billed only for new rows. Off: deliver everything in the window every run.

## `snapshotName` (type: `string`):

Which memory to use for "only new"; kept on your account as a key-value store named sam-gov-contract-radar-<this name>. Give each schedule its own name. Lower-case letters, digits, and hyphens; other characters become hyphens.

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

For each NAICS code you gave, also deliver the largest federal contracts USAspending.gov recorded as signed in the look-back window: who won, which agency, how much. Skipped when no NAICS codes are given.

## `awardsMonths` (type: `integer`):

How many months back to look for USAspending awards signed for your NAICS codes.

## `maxAwardsPerNaics` (type: `integer`):

Largest awards (by amount) to deliver per NAICS code. An award that matches several of your codes is delivered once.

## Actor input object example

```json
{
  "naicsCodes": [
    "541511",
    "541512"
  ],
  "keywords": [],
  "keywordsMatchAll": false,
  "noticeTypes": [],
  "setAsideCodes": [],
  "states": [],
  "agencies": [],
  "pscCodes": [],
  "postedWithinDays": 7,
  "deadlineNotPassed": true,
  "activeOnly": true,
  "maxItems": 200,
  "dedupeAmendments": true,
  "onlyNew": true,
  "snapshotName": "default",
  "includeAwards": true,
  "awardsMonths": 12,
  "maxAwardsPerNaics": 25
}
```

# Actor output Schema

## `all` (type: `string`):

No description

## `opportunityColumns` (type: `string`):

No description

## `awardColumns` (type: `string`):

No description

## `csv` (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 = {
    "naicsCodes": [
        "541511",
        "541512"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("upward_enterprises/sam-gov-contract-radar").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 = { "naicsCodes": [
        "541511",
        "541512",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("upward_enterprises/sam-gov-contract-radar").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 '{
  "naicsCodes": [
    "541511",
    "541512"
  ]
}' |
apify call upward_enterprises/sam-gov-contract-radar --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,upward_enterprises/sam-gov-contract-radar"
        }
    }
}

```

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/52szHftt5nOzUJMaz/builds/FeecvES1JF2LGeQVH/openapi.json
