# Sam Gov Contract Opportunity Monitor (`atlia/sam-gov-contract-opportunity-monitor`) Actor

Monitor US federal contract opportunities on SAM.gov with deep filters. Tracks new solicitations, amendments, and awards with keyword, agency, NAICS, and set-aside filters.

- **URL**: https://apify.com/atlia/sam-gov-contract-opportunity-monitor.md
- **Developed by:** [ATLIA USA](https://apify.com/atlia) (community)
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 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.

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 Opportunity Monitor

Monitor US federal contract opportunities published on [SAM.gov](https://sam.gov) with deep filters, incremental runs, and optional award-history enrichment. Built on the **official SAM.gov Contract Opportunities API** — no scraping, no proxies, near-zero platform cost.

### What it does

- **Deep filters** — keywords (title), NAICS codes, set-aside types (8(a), HUBZone, SDVOSB, WOSB…), agencies, notice types (Solicitation, Pre-solicitation, Combined, Sources Sought, Award Notice), posting-date window, contract value, deadline window.
- **Incremental mode** — each scheduled run returns only notices not seen before. Built for daily schedules.
- **Award-history enrichment** (optional) — attaches past contract awards for the same solicitation number.
- **Pay-per-result** — charges one `result` event per notice returned.

### Input

```json
{
  "samGovApiKey": "YOUR_FREE_SAM_GOV_API_KEY",
  "keywords": ["cybersecurity"],
  "naicsCodes": ["541512"],
  "setAsideTypes": ["8(a)", "SDVOSB"],
  "agencies": ["Veterans Affairs"],
  "noticeTypes": ["Solicitation"],
  "postedFrom": "2026-09-01",
  "postedTo": "2026-10-01",
  "deadlineWithinDays": 30,
  "maxResults": 100,
  "incremental": true,
  "includeAwardHistory": false,
  "maxAwardLookups": 25
}
```

Notes:

- `samGovApiKey` can be left empty if you set the `SAM_GOV_API_KEY` actor secret instead (recommended — keeps the key out of run inputs).
- Get a free key: sam.gov → sign in → profile → **Account Details** → enter password → Public API Key.
- `setAsideTypes` accepts friendly names (`8(a)`, `HUBZone`, `SDVOSB`, `SBA`, `WOSB`…) or official codes (`8A`, `HZC`, `SDVOSBC`, `SBA`…).
- The API accepts one value per query for title/NAICS/set-aside/type, so multi-value filters fan out into multiple sub-queries (capped at 16 — narrow filters if you hit the cap).

### Output (dataset record)

```json
{
  "noticeId": "fff7063befcc4554ac85243e4a90c472",
  "title": "…",
  "agency": "DEPT OF DEFENSE / …",
  "office": "…",
  "noticeType": "Solicitation",
  "postedDate": "2026-10-01",
  "responseDeadline": "2026-10-19T10:00:00-05:00",
  "daysUntilDeadline": 18,
  "naicsCode": "541512",
  "setAside": "SDVOSBC",
  "contractValue": { "min": null, "max": 1200000, "currency": "USD" },
  "placeOfPerformance": { "city": "Austin", "state": "TX" },
  "buyerContact": { "name": "…", "email": "…", "phone": "…" },
  "description": "…",
  "solicitationNumber": "36C10X26Q0001",
  "awardHistory": [{ "awardee": "…", "amount": 1100000, "awardDate": "2025-06-15" }],
  "sourceUrl": "https://sam.gov/opp/…/view"
}
```

Buyer contact fields come from the notice's **publicly listed** point of contact. No personal-data scraping.

### Monetization (proposed, pending approval)

- **Pay-per-result: $2 / 1,000 results** (benchmark $1–5). One `result` event per notice.
- Official API → no proxy/residential-IP cost, so margin is high.

### Local development

```bash
npm install            # apify-cli
python3 -m venv .venv && .venv/bin/pip install -r requirements.txt
## integration test against canned real API responses (no key needed):
.venv/bin/python tests/make_fixture.py   # needs the sam-gov skill credential
SAM_GOV_FIXTURE=tests/fixture.json ./node_modules/.bin/apify run --input '{…}'
```

### Deploy

```bash
./node_modules/.bin/apify login     # your Apify account (run once)
./node_modules/.bin/apify push      # builds & deploys to your account
```

Then in Apify Console: set the `SAM_GOV_API_KEY` secret (Actor → Settings → Environment variables), add a daily **Schedule** with `incremental: true`, and configure monetization (Pay-per-result → `result` event at $0.002).

### Limits & honesty

- Public-tier SAM.gov keys are rate-limited (~1,000 requests/day). This actor stays far below that for normal use; `maxAwardLookups` caps enrichment calls.
- Contract-value filtering only applies when the notice publishes amount data — solicitations often don't, and those are kept rather than silently dropped.
- Revenue figures depend on paid-plan users adopting the Actor; most new Actors see little traffic at first. Numbers in planning docs are estimates.

# Actor input Schema

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

Agency name fragments matched against the agency hierarchy (deptname), e.g. Veterans Affairs, Defense.

## `contractValueMax` (type: `integer`):

Applied when the notice carries award-amount data; notices without amount data are kept. 0 disables.

## `contractValueMin` (type: `integer`):

Applied when the notice carries award-amount data; notices without amount data are kept.

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

Keep only notices whose response deadline falls within this many days from now. 0 disables.

## `includeAwardHistory` (type: `boolean`):

Enrich each notice with past contract awards for the same solicitation number (extra API calls).

## `incremental` (type: `boolean`):

Return only notices not seen in previous runs. Made for daily scheduled runs.

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

Title keywords, e.g. cybersecurity, cloud migration. One search runs per keyword.

## `maxAwardLookups` (type: `integer`):

Cap on contract-award API calls per run (rate-limit safety).

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

Maximum notices returned per run.

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

6-digit NAICS codes, e.g. 541512. One search runs per code.

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

Solicitation, Pre-solicitation, Combined Synopsis/Solicitation, Sources Sought, Award Notice.

## `postedFrom` (type: `string`):

Start of posting-date window (YYYY-MM-DD). In incremental mode this is raised to the last run date.

## `postedTo` (type: `string`):

End of posting-date window (YYYY-MM-DD). Defaults to today.

## `samGovApiKey` (type: `string`):

Your free SAM.gov public API key (Account Details page on sam.gov). Leave empty to use the SAM\_GOV\_API\_KEY secret/environment variable instead.

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

Friendly names or raw codes. Valid codes: SBA, SBP, 8A, 8AN, HZC, HZS, SDVOSBC, SDVOSBS, WOSB, WOSBSS, EDWOSB, EDWOSBSS, VSA, VSS. One search runs per code.

## Actor input object example

```json
{
  "agencies": [],
  "contractValueMax": 0,
  "contractValueMin": 0,
  "deadlineWithinDays": 0,
  "includeAwardHistory": false,
  "incremental": true,
  "keywords": [],
  "maxAwardLookups": 25,
  "maxResults": 100,
  "naicsCodes": [],
  "noticeTypes": [
    "Solicitation"
  ],
  "postedFrom": "",
  "postedTo": "",
  "samGovApiKey": "",
  "setAsideTypes": []
}
```

# Actor output Schema

## `results` (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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("atlia/sam-gov-contract-opportunity-monitor").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("atlia/sam-gov-contract-opportunity-monitor").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 atlia/sam-gov-contract-opportunity-monitor --silent --output-dataset

```

## MCP server setup

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

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/48D6fN7IeP2doQqYf/builds/KG08UeBMf4v0WL3P5/openapi.json
