# SAM.gov Contract Opportunities (Official Daily Extract) (`betteratoms/sam-gov-opportunities-official-extract`) Actor

Filter every active U.S. federal contract opportunity from SAM.gov's official public daily extract by keyword, NAICS, set-aside, notice type, state, agency and posting date. No API key, no login, no website scraping.

- **URL**: https://apify.com/betteratoms/sam-gov-opportunities-official-extract.md
- **Developed by:** [Better Atoms Technologies LLP](https://apify.com/betteratoms) (community)
- **Categories:** Lead generation, Business, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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: Official Daily Extract

Get every **active U.S. federal contract opportunity** from SAM.gov as clean JSON, CSV or Excel. Filter by keyword, NAICS code, set-aside, notice type, place-of-performance state, agency and posting date. You don't need an API key, a login or a browser.

The actor reads SAM.gov's **official public "Contract Opportunities" daily extract**, the bulk download SAM.gov publishes for reuse at sam.gov/data-services. It does **not** crawl the SAM.gov website or its internal search API.

### Why use this actor

- **Terms-friendly source:** it uses the public extract SAM.gov provides for downloading, not website scraping.
- **Full coverage:** each run scans all active notices (71,333 on 17 Oct 2026), with no 10,000-result search cap.
- **Reliable:** one plain HTTPS download, so there are no proxies, CAPTCHAs or browser breakage.
- **Monitor mode:** schedule it daily and receive only notices you haven't seen before.
- **Privacy by default:** point-of-contact fields are left out unless you turn them on.

### Who it's for

Small businesses and BD teams bidding on federal work, GovCon consultants, newsletter publishers, and anyone feeding federal RFPs into Slack, Google Sheets, a CRM or an AI agent.

### Input

| Field | What it does |
|---|---|
| `keywords` | Whole-word / phrase match on title + description (any of them) |
| `naicsCodes` | NAICS prefix match. `5415` matches 541511, 541512, … |
| `noticeTypes` | Solicitation, Combined Synopsis/Solicitation, Presolicitation, Sources Sought, Special Notice, Award Notice, … |
| `setAsideCodes` | e.g. `SBA`, `8A`, `HZC`, `SDVOSBC`, `WOSB`, `EDWOSB`, `NONE` |
| `states` | Place-of-performance state codes, e.g. `VA`, `TX` |
| `agencyContains` | Matches department / sub-tier / office, e.g. `VETERANS`, `DEFENSE` |
| `postedWithinDays` | Default 7. Use 0 for no date filter |
| `openForResponseOnly` | Drop notices whose response deadline has passed |
| `includeDescription`, `descriptionMaxChars` | Description text and how long it can be |
| `includeContacts` | Off by default. Adds the official points of contact SAM.gov publishes |
| `onlyNewSinceLastRun`, `stateKey` | Monitor mode for scheduled runs |
| `maxItems` | Maximum results (default 100) |

#### Example: open IT solicitations set aside for small business

```json
{
  "naicsCodes": ["5415"],
  "setAsideCodes": ["SBA"],
  "noticeTypes": ["Solicitation", "Combined Synopsis/Solicitation"],
  "postedWithinDays": 30,
  "openForResponseOnly": true,
  "maxItems": 500
}
```

### Output (one item per notice)

```json
{
  "noticeId": "bf20cc34e02949c789d832f179c22c1a",
  "title": "Mt Shasta-McCloud Ranger Districts Janitorial",
  "solicitationNumber": "127EAY27Q0002",
  "type": "Combined Synopsis/Solicitation",
  "department": "AGRICULTURE, DEPARTMENT OF",
  "subTier": "FOREST SERVICE",
  "office": "Shasta-Trinity National Forest",
  "postedDate": "2026-10-16 12:17:15",
  "responseDeadline": "2026-10-19T17:00:00-07:00",
  "naicsCode": "561720",
  "classificationCode": "S201",
  "setAsideCode": "SBA",
  "setAside": "Small Business Set Aside - Total",
  "popCity": "Mount Shasta", "popState": "CA", "popZip": "96067", "popCountry": "USA",
  "active": true,
  "awardNumber": null, "awardDate": null, "awardAmount": null, "awardee": null,
  "url": "https://sam.gov/opp/bf20cc34e02949c789d832f179c22c1a/view",
  "description": "…",
  "source": "SAM.gov Contract Opportunities public extract",
  "sourceExtractLastModified": "Sat, 17 Oct 2026 03:30:44 GMT"
}
```

`sample_output.json` holds 10 real items from the local test run.

### Pricing

Pay per result: **$1.50 per 1,000 opportunities** plus **$0.01 per run start**. Runs with no matches cost only the start fee. Use `maxItems` to cap spend.

### Notes and limits

- SAM.gov refreshes the extract once a day, so this is a daily feed, not a real-time one.
- The extract covers **active** notices. For archived history, use SAM.gov's official archive extracts or API.
- The data comes from SAM.gov and is provided as-is. Always confirm details on the linked SAM.gov notice before you bid.
- This actor is not affiliated with or endorsed by GSA or SAM.gov.

### Local development

```bash
pip install -r requirements.txt
## edit storage/key_value_stores/default/INPUT.json, then:
python -m src
## end-to-end test (4 runs against the live extract, with assertions):
python tests/run_local_test.py
```

# Actor input Schema

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

Return opportunities whose title or description contains ANY of these words or phrases (case-insensitive). Leave empty for no keyword filter.

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

e.g. 541511 or just 5415 to match every code starting with 5415.

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

Leave empty for all notice types.

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

SAM.gov set-aside codes, e.g. SBA (total small business), 8A, HZC (HUBZone), SDVOSBC, WOSB, EDWOSB, NONE.

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

Two-letter state codes, e.g. VA, TX.

## `agencyContains` (type: `array`):

Matches department, sub-tier or office name (case-insensitive), e.g. DEFENSE, VETERANS, NASA.

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

0 = no date filter.

## `openForResponseOnly` (type: `boolean`):

Drop notices whose response deadline has already passed (notices without a deadline are kept).

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

Include the notice description text in each result.

## `descriptionMaxChars` (type: `integer`):

Truncate descriptions to this many characters. 0 = no limit.

## `includeContacts` (type: `boolean`):

Off by default. When on, adds the contracting office's published point-of-contact fields exactly as SAM.gov publishes them.

## `onlyNewSinceLastRun` (type: `boolean`):

Remembers notice IDs already returned (per stateKey) and skips them on later runs.

## `stateKey` (type: `string`):

Name for the remembered state, so different saved searches don't clash.

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

Maximum number of opportunities to return (each returned opportunity is a billable result).

## Actor input object example

```json
{
  "keywords": [
    "software",
    "cybersecurity"
  ],
  "postedWithinDays": 7,
  "openForResponseOnly": false,
  "includeDescription": true,
  "descriptionMaxChars": 1500,
  "includeContacts": false,
  "onlyNewSinceLastRun": false,
  "stateKey": "default",
  "maxItems": 100
}
```

# Actor output Schema

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

Dataset containing all output rows

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

RUN_SUMMARY record with counts and timing for this run

# 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": [
        "software",
        "cybersecurity"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("betteratoms/sam-gov-opportunities-official-extract").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": [
        "software",
        "cybersecurity",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("betteratoms/sam-gov-opportunities-official-extract").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": [
    "software",
    "cybersecurity"
  ]
}' |
apify call betteratoms/sam-gov-opportunities-official-extract --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,betteratoms/sam-gov-opportunities-official-extract"
        }
    }
}
```

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/hPbuDMthsyHkNJyWK/builds/3irPCgleHjENSzCpC/openapi.json
