# SAM.gov Federal Contract Opportunities Scraper (`lumul/sam-gov-federal-contract-opportunities-scraper`) Actor

Scrape U.S. federal contract opportunities, RFPs, Sources Sought, and Award Notices from SAM.gov with NO API key required. Filter by NAICS code, SBA/SDVOSB/8(a) set-aside, state, notice type, and keyword. Extracts full PWS/SOW text, direct RFP attachment links, and POC emails.

- **URL**: https://apify.com/lumul/sam-gov-federal-contract-opportunities-scraper.md
- **Developed by:** [Lumul](https://apify.com/lumul) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 contract 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?

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 Scraper (No API Key, RFPs & POCs)

Extract active and historical U.S. federal contract opportunities, **Solicitations (RFPs/RFQs)**, **Sources Sought / RFIs**, **Presolicitations**, **Combined Synopsis/Solicitations**, **Special Notices**, **Award Notices**, and **Sole Source Justifications (J\&As)** directly from **SAM.gov**—with **zero SAM.gov API keys required**.

Built for **GovCon capture teams**, **BD agencies**, **proposal automation pipelines**, and **AI / MCP agents**, this Actor bypasses SAM.gov's restrictive 10-request/day public API limit to deliver clean, schema-locked JSON with full Performance Work Statement (PWS) text, direct attachment download links, and verified Contracting Officer contact details.

***

### Why Use This SAM.gov Scraper?

- **No SAM.gov API Key Required:** Skip the SAM.gov system account registration, entity validation delays, and 10–1,000 request/day public API rate limits. Run immediately on demand or on a schedule.
- **Direct RFP & SOW Attachment Download Links (`attachmentLinks`):** Automatically resolves direct, unauthenticated download URLs for every attached PDF, Word document, Excel pricing matrix, and SF-30 amendment—ready to feed directly into LLM/RAG bid-scoring pipelines.
- **Verified Contracting Officer Contacts (`pointOfContact`):** Extracts primary and secondary Point of Contact names, `.mil` / `.gov` email addresses, phone numbers, titles, and fax numbers for immediate GovCon capture and RFI outreach.
- **Dual-Speed Execution for AI & MCP Agents (`includeFullDescription`):**
  - **Full Capture Mode (`includeFullDescription: true`):** Fetches, strips HTML/entities, and normalizes complete multi-page Performance Work Statements (PWS) and Statements of Work (SOW).
  - **MCP Fast-Scan Mode (`includeFullDescription: false`):** Bypasses secondary description/resource requests for sub-second discovery scans across hundreds of notices.
- **Multi-NAICS & Socioeconomic Set-Aside Filtering:** Filter by single or multiple NAICS prefixes/codes (e.g., `541511`, `541512`, `541519`), Set-Aside codes (`SBA`, `8A`, `SDVOSBC`, `WOSB`, `HZC`), U.S. State (`VA`, `MD`, `DC`), Notice Types, and Posted Date windows.
- **Crash-Resilient & Deduplicated:** Persists pagination and deduplication state across Apify container migrations so long runs never emit duplicate `noticeId` records or lose progress.

***

### What Data Can You Extract? (19 Locked Fields)

Every record pushed to the dataset is strictly validated against a 19-field schema:

| Field | Type | Description |
| :--- | :--- | :--- |
| `noticeId` | `string` | Unique 32-character SAM.gov opportunity identifier |
| `title` | `string` | Cleaned, quote-normalized contract opportunity title |
| `solicitationNumber` | `string \| null` | Official agency solicitation / RFQ / RFP number (e.g., `36C26026Q1017`) |
| `department` | `string \| null` | Top-level Federal Department (e.g., `DEPT OF DEFENSE`, `VETERANS AFFAIRS, DEPARTMENT OF`) |
| `subTierAgency` | `string \| null` | Sub-tier agency or command (e.g., `DEPT OF THE NAVY`, `DEFENSE LOGISTICS AGENCY`) |
| `office` | `string \| null` | Contracting office name and code |
| `noticeType` | `string` | Standardized type (`Solicitation`, `Presolicitation`, `Combined Synopsis/Solicitation`, `Sources Sought`, `Special Notice`, `Award Notice`, `Justification`) |
| `naicsCode` | `string \| null` | Primary NAICS code (e.g., `541511`, `541519`, `236220`) |
| `setAsideCode` | `string \| null` | SBA Set-Aside code (e.g., `SBA`, `SDVOSBC`, `8A`, `WOSB`, `NONE`) |
| `setAsideDescription` | `string \| null` | Full FAR Set-Aside description (e.g., `Total Small Business Set-Aside (FAR 19.5)`) |
| `postedDate` | `string` | ISO-8601 publication timestamp |
| `responseDeadLine` | `string \| null` | ISO-8601 proposal/response due date with timezone offset |
| `active` | `boolean` | `true` if the opportunity is currently active on SAM.gov |
| `pointOfContact` | `array<object>` | Array of contact objects (`fullName`, `email`, `phone`, `title`, `type`, `fax`) |
| `placeOfPerformance` | `object` | Structured location object (`city`, `state`, `country`, `zip`) |
| `uiLink` | `string` | Direct link to view the opportunity on SAM.gov |
| `descriptionText` | `string \| null` | Full HTML-sanitized, whitespace-normalized solicitation/PWS body text |
| `attachmentLinks` | `array<string>` | Direct download URLs for all public RFP/SOW/amendment files |
| `scrapedAt` | `string` | ISO-8601 UTC timestamp when the record was extracted |

***

### Input Parameters

| Parameter | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `keyword` | `string` | `"software development"` | Search keywords for contract opportunities |
| `naicsCodes` | `array<string>` | `["541511"]` | Filter by one or more NAICS codes or prefixes (e.g., `["541511", "541512"]`) |
| `noticeTypes` | `array<string>` | All types | Filter by notice types (`Solicitation`, `Presolicitation`, `Combined Synopsis/Solicitation`, `Sources Sought`, `Special Notice`, `Award Notice`, `Justification`) |
| `setAside` | `string` | Any | Filter by SBA set-aside code (e.g., `SBA`, `8A`, `SDVOSBC`, `WOSB`, `HZC`, `NONE`) |
| `state` | `string` | Any | Two-letter U.S. state/territory code for Place of Performance (e.g., `VA`, `MD`, `DC`) |
| `activeOnly` | `boolean` | `true` | Fetch only currently active contract opportunities |
| `postedFrom` | `string` | Any | Start date filter in `YYYY-MM-DD` format |
| `postedTo` | `string` | Any | End date filter in `YYYY-MM-DD` format |
| `includeFullDescription` | `boolean` | `true` | Set to `true` to fetch full PWS/SOW description text and attachment download URLs, or `false` for fast metadata-only scans |
| `maxItems` | `integer` | `25` | Maximum number of contract opportunities to extract |
| `limit` | `integer` | `100` | Page size per API request |
| `pageSize` | `integer` | `100` | Alias for `limit` (custom page size override for pagination) |
| `proxyConfiguration` | `object` | Apify Proxy | Optional proxy configuration |

***

### Input Configuration Examples

#### 1. Capture Team Daily RFP & Sources Sought Monitor (Full Descriptions + Attachments)

```json
{
  "keyword": "software development",
  "naicsCodes": ["541511", "541512", "541519"],
  "setAside": "SBA",
  "noticeTypes": [
    "Sources Sought",
    "Presolicitation",
    "Solicitation",
    "Combined Synopsis/Solicitation"
  ],
  "activeOnly": true,
  "includeFullDescription": true,
  "maxItems": 100
}
```

#### 2. Fast-Scan Mode for AI & MCP Agents (Metadata + POCs Only)

Set `"includeFullDescription": false` when an AI agent needs to rapidly triage titles, agencies, deadlines, and Contracting Officer emails before selectively fetching full RFPs:

```json
{
  "keyword": "cybersecurity",
  "activeOnly": true,
  "includeFullDescription": false,
  "maxItems": 50
}
```

***

### Sample Output Record

```json
{
  "noticeId": "f50d635e4b9d4404916c47df2357fc66",
  "title": "Admin Management, Data Management, Software Development (Quality Assurance Inspection Software for EMS)",
  "solicitationNumber": "36C26026Q1017",
  "department": "VETERANS AFFAIRS, DEPARTMENT OF",
  "subTierAgency": "VETERANS AFFAIRS, DEPARTMENT OF",
  "office": "260-NETWORK CONTRACT OFFICE 20 (36C260)",
  "noticeType": "Combined Synopsis/Solicitation",
  "naicsCode": "541519",
  "setAsideCode": "SDVOSBC",
  "setAsideDescription": "Service-Disabled Veteran-Owned Small Business (SDVOSB) Set-Aside (FAR 19.14)",
  "postedDate": "2026-10-13T22:26:14+00:00",
  "responseDeadLine": "2026-11-03T17:00:00-08:00",
  "active": true,
  "pointOfContact": [
    {
      "fullName": "Tyrone Whalen, Contract Specialist",
      "email": "tyrone.whalen@va.gov",
      "phone": null,
      "title": null,
      "type": "primary",
      "fax": null
    },
    {
      "fullName": "Danielle Carrico",
      "email": "danielle.carrico@va.gov",
      "phone": null,
      "title": null,
      "type": "secondary",
      "fax": null
    }
  ],
  "placeOfPerformance": {
    "city": null,
    "state": "OR",
    "country": "USA",
    "zip": "97239"
  },
  "uiLink": "https://sam.gov/opp/f50d635e4b9d4404916c47df2357fc66/view",
  "descriptionText": "Amendment 0001- Answer Questions submitted from vendors by questions deadline of 10/05/2026 and adding attachment 1 revised RFQ 36C26026Q1017 The is for the acquisition of admin management, data management, software development (Quality Assurance Inspection Software for EMS)",
  "attachmentLinks": [
    "https://sam.gov/api/prod/opps/v3/opportunities/resources/files/7bfc532463ae431e9691354505f1bd82/download?&status=public",
    "https://sam.gov/api/prod/opps/v3/opportunities/resources/files/8d4538ae37f045d890881c5479afbee1/download?&status=public",
    "https://sam.gov/api/prod/opps/v3/opportunities/resources/files/83bc8d042ae24ecaa4ae84307d8a1e3e/download?&status=public"
  ],
  "scrapedAt": "2026-10-20T17:57:20.230Z"
}
```

***

### Integrations: MCP Server, n8n & Clay

#### Connect to Claude Desktop, Cursor, or Windsurf (Apify MCP Server)

Give your AI assistant real-time access to live federal contracts via the official `@apify/actors-mcp-server`:

```json
{
  "mcpServers": {
    "sam-gov-contracts": {
      "command": "npx",
      "args": [
        "-y",
        "@apify/actors-mcp-server",
        "--actors",
        "lumul/sam-gov-federal-contract-opportunities-scraper"
      ],
      "env": {
        "APIFY_TOKEN": "your_apify_api_token"
      }
    }
  }
}
```

#### Automated Bid / No-Bid Pipeline in n8n or Make.com

1. **Schedule Trigger:** Run every weekday morning at 7:00 AM EST.
2. **Apify Node:** Run this Actor with your target `naicsCodes`, `setAside`, and `postedFrom` set to today's date.
3. **LLM Node (OpenAI / Anthropic):** Pass `title`, `descriptionText`, and `responseDeadLine` against your company capability statement to score **Bid / No-Bid (0–100)**.
4. **Slack / CRM Node:** Post high-scoring opportunities directly to Slack or HubSpot with one-click `attachmentLinks` and `pointOfContact[0].email`.

#### GovCon Lead Generation in Clay.com

Import the dataset into Clay to enrich `pointOfContact` `.mil` and `.gov` Contracting Officer emails, match `solicitationNumber` to incumbent contractors on Award Notices, and automate Sources Sought / RFI capability statement submissions before solicitations drop.

# Actor input Schema

## `keyword` (type: `string`):

Search keywords for contract opportunities.

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

Array of 6-digit NAICS codes as strings to filter by (e.g. \['541511']).

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

Notice types to filter by (e.g. \['Solicitation', 'Presolicitation', 'Sources Sought', 'Special Notice']).

## `setAside` (type: `string`):

Optional filter for set-aside type (e.g. 'SBA', '8A', 'WOSB', 'SDVOSBC').

## `state` (type: `string`):

Optional US state code like 'VA' or 'CA'.

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

Set to true to only fetch currently active opportunities.

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

Start date for searching opportunities in YYYY-MM-DD format. Must be between 2000-01-01 and one year from today.

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

End date for searching opportunities in YYYY-MM-DD format. Must be between 2000-01-01 and one year from today.

## `includeFullDescription` (type: `boolean`):

Set to true to fetch full text descriptions and attachment URLs for each result.

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

Maximum number of opportunities to fetch. Minimum 1.

## `limit` (type: `integer`):

Custom page size override for pagination. Defaults to 100. Useful for testing.

## `pageSize` (type: `integer`):

Alias for limit. Custom page size override for pagination. Defaults to 100. Useful for testing.

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

Select proxies to be used by your scraper.

## Actor input object example

```json
{
  "keyword": "software development",
  "naicsCodes": [
    "541511"
  ],
  "activeOnly": true,
  "includeFullDescription": true,
  "maxItems": 25
}
```

# Actor output Schema

## `results` (type: `string`):

Dataset containing extracted SAM.gov contract opportunities validated against the 19-field schema (noticeId, title, solicitationNumber, agency hierarchy, NAICS, set-aside, deadlines, POC contacts, sanitized PWS descriptionText, and direct attachmentLinks).

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

JSON execution summary stored in the Key-Value Store (RUN_SUMMARY) containing total records extracted, pages fetched, active filter parameters, and peak memory telemetry.

# 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 = {
    "keyword": "software development",
    "naicsCodes": [
        "541511"
    ],
    "activeOnly": true,
    "includeFullDescription": true,
    "maxItems": 25
};

// Run the Actor and wait for it to finish
const run = await client.actor("lumul/sam-gov-federal-contract-opportunities-scraper").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 = {
    "keyword": "software development",
    "naicsCodes": ["541511"],
    "activeOnly": True,
    "includeFullDescription": True,
    "maxItems": 25,
}

# Run the Actor and wait for it to finish
run = client.actor("lumul/sam-gov-federal-contract-opportunities-scraper").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 '{
  "keyword": "software development",
  "naicsCodes": [
    "541511"
  ],
  "activeOnly": true,
  "includeFullDescription": true,
  "maxItems": 25
}' |
apify call lumul/sam-gov-federal-contract-opportunities-scraper --silent --output-dataset

```

## MCP server setup

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

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/kRW7gYWNZ1nKjO2nQ/builds/I1sOKanxCYuI3Ci9w/openapi.json
