# SAM.gov Contract Opportunities Scraper: US Federal Tenders (`nexus-scrapers/sam-gov-opportunities`) Actor

Scrape SAM.gov contract opportunities: US federal government tenders, RFPs, RFQs, solicitations, sources sought and award notices. Filter by NAICS, PSC, set-aside (8(a), SDVOSB, WOSB, HUBZone), agency, state or response deadline. Official public SAM.gov data, no API key. JSON, CSV or Excel.

- **URL**: https://apify.com/nexus-scrapers/sam-gov-opportunities.md
- **Developed by:** [Nexus Scrapers](https://apify.com/nexus-scrapers) (community)
- **Categories:** Lead generation, Business, AI
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$3.00 / 1,000 contract opportunity notices

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 Scraper - US Federal Tenders, Solicitations & Awards

Search and export **US federal contract opportunities** from [SAM.gov](https://sam.gov) as clean, normalized JSON, CSV or Excel: solicitations, sources sought, presolicitations, special notices, sole-source justifications and **award notices with the awardee and the awarded amount**. Filter by keyword, **NAICS code**, **PSC code**, **set-aside type**, agency, place-of-performance state, posting date and response deadline. **No SAM.gov API key, no login, no proxy and no browser needed.**

The Actor reads the **official public daily data extract** that SAM.gov itself distributes (SAM.gov Data Services, "Contract Opportunities"), not the rate-limited Opportunities API. The file is sorted newest first, so the Actor downloads only as much as it needs: the default run (20 newest solicitations) reads about 0.1 MB and finishes in 4 seconds.

Each result follows the same **tender schema v1** used by the other Actors of this procurement family (EU TED, UK Find a Tender & Contracts Finder), so US, UK and EU notices can be loaded into one table.

### Who is it for

- **Government contractors and small businesses** (8(a), HUBZone, SDVOSB, WOSB, total small-business set-asides) who need a daily list of open bids in their NAICS/PSC codes, states and agencies, with the response deadline.
- **Capture and business-development teams** tracking sources-sought notices and presolicitations months before the RFP, and who won what (award notices).
- **Analysts and market researchers** measuring federal buying by agency, NAICS, set-aside or state.
- **AI agents and MCP users**: the dataset schema describes every field, so an agent can query federal opportunities in plain language.

### What you get

One dataset item per notice, with:

- notice id, link to the sam.gov page, native notice type (Solicitation, Sources Sought, Award Notice, ...) and the normalized type
- title and description (HTML stripped, truncated at 1,500 characters), solicitation number
- department, sub-tier agency, contracting office and its location
- **NAICS code, PSC code, set-aside type**, contract nature (supplies / services / works)
- posting date, **response deadline** (with time and offset when published), archive date
- place of performance (city, state, ZIP, country)
- for award notices: **awardee**, **awarded amount (USD)**, award date and award number
- optional: the contracting officer's contact as published in the notice (see [Privacy](#data-licence-and-privacy))

The full field reference is in [SCHEMA.md](./SCHEMA.md) and in the Actor's dataset schema.

### Where the data comes from, and what it does not contain

The extract (`ContractOpportunitiesFullCSV.csv`, about 215 MB, about 70,000 records) is regenerated by SAM.gov once a day. Please know its limits before you rely on it:

- It contains **active notices only** (all records have Active = Yes), not the full historical archive. Closed and expired notices drop out. Award notices are included while they are active.
- It is **one day behind**: the newest notices are those posted up to the previous day.
- Attachments (statements of work, RFQ PDFs) are **not** in the extract; use the `url` to open the notice. There is no estimated contract value for solicitations (SAM.gov does not publish one in the extract).
- The awardee is published as a single text (name followed by street, city, state, ZIP); the Actor keeps it as published and additionally parses the state and ZIP into `samAwardeeState` / `samAwardeeZip`.
- Amendments and updates appear as separate records of the same solicitation (same `samSolicitationNumber`).

### Use cases

- **Daily bid alerts**: new solicitations in your NAICS/PSC codes and states, open for response, small-business set-asides only. Schedule the Actor and send the dataset to Slack, e-mail or a spreadsheet.
- **Pipeline intelligence**: sources-sought notices and presolicitations show what an agency will buy.
- **Competitor and award tracking**: award notices with awardee and amount (filter by amount range).
- **Teaming and subcontracting**: find the awardees of large contracts in your field.
- **AI agents (MCP)**: ask in natural language, get structured notices back.

### Input

All filters are optional and combined with AND.

| Field | Description |
|---|---|
| `keyword` | Word or phrase in title, description or solicitation number; separate alternatives with commas |
| `naicsCodes` | NAICS codes with prefix matching: `54` = professional/technical services, `541512` = computer systems design |
| `pscCodes` | Product and Service Codes with prefix matching: `D3` = IT services, `7030` = software, `Y1` = building construction |
| `noticeTypes` | `contract-notice` (default: Solicitation and Combined Synopsis/Solicitation), `prior-information` (Presolicitation, Sources Sought), `contract-award`, `contract-modification`, `voluntary-ex-ante` (sole-source Justifications), `other` (Special Notice, surplus sales). Empty list = all |
| `samNoticeTypes` | Exact SAM.gov types, e.g. only `Sources Sought` |
| `setAsides` | `SBA`, `8A`, `HZC`, `SDVOSBC`, `WOSB`, `EDWOSB`, `NONE`, ... |
| `agencies` | Words in the department, sub-tier or office name: `army`, `veterans` |
| `states` | Place-of-performance states, two letters: `VA`, `TX` |
| `daysBack` | Posted in the last N days (default 7; 0 = no limit, scans the whole extract) |
| `dateFrom` / `dateTo` | Explicit posting date range, `YYYY-MM-DD` |
| `openForResponseOnly` | Drop notices whose response deadline has passed |
| `deadlineFrom` / `deadlineTo` | Response deadline window |
| `minAwardValue` / `maxAwardValue` | Award amount range in USD (award notices only) |
| `includeContacts` | Add the primary/secondary point of contact as published (default off) |
| `maxItems` | Maximum results (default 20, maximum 10,000, newest first) |

#### Example: open small-business IT bids in Virginia and Maryland

```json
{
  "noticeTypes": ["contract-notice"],
  "naicsCodes": ["5415"],
  "setAsides": ["SBA", "SDVOSBC"],
  "states": ["VA", "MD"],
  "openForResponseOnly": true,
  "daysBack": 14,
  "maxItems": 100
}
```

#### Example: sources-sought notices about cybersecurity

```json
{
  "noticeTypes": [],
  "samNoticeTypes": ["Sources Sought"],
  "keyword": "cybersecurity, zero trust",
  "daysBack": 30
}
```

#### Example: who won contracts above one million dollars

```json
{
  "noticeTypes": ["contract-award"],
  "minAwardValue": 1000000,
  "agencies": ["veterans"],
  "daysBack": 30,
  "maxItems": 200
}
```

### Output example

Real record (posted on 30 October 2026), description shortened. Fields starting with `sam` are SAM.gov-specific extras; all other fields are shared with the other procurement Actors. SAM.gov has no CPV codes, so `cpvCodes` is empty and the classification is in `samNaicsCode` / `samPscCode`.

```json
{
  "schemaVersion": "1.0",
  "source": "SAM_GOV",
  "sourceId": "ecf63283c97e4d4f8047f3497c6801bc",
  "url": "https://sam.gov/workspace/contract/opp/ecf63283c97e4d4f8047f3497c6801bc/view",
  "documentUrls": { "html": "https://sam.gov/workspace/contract/opp/ecf63283c97e4d4f8047f3497c6801bc/view", "pdf": null, "xml": null },
  "noticeType": "contract-notice",
  "noticeTypeCode": "Combined Synopsis/Solicitation",
  "procedureType": null,
  "contractNature": "supplies",
  "title": "HID ID/Access Cards",
  "description": "** THIS IS A BRAND NAME REQUIREMENT ** for Requirement: HID ID/Access Cards ** AUTHORIZED RESELLERS ONLY ** ...",
  "language": "en",
  "buyer": { "name": "NATIONAL AERONAUTICS AND SPACE ADMINISTRATION", "country": "US", "city": "STENNIS SPACE CENTER", "nutsCode": null, "buyerType": "central-government" },
  "cpvCodes": [],
  "mainCpv": null,
  "mainCpvDivision": null,
  "estimatedValue": null,
  "lots": null,
  "publicationDate": "2026-10-30",
  "submissionDeadline": "2026-11-06T07:00:00-06:00",
  "awardInfo": null,
  "placeOfPerformance": { "country": "US", "city": "Hampton", "nutsCode": null },
  "scrapedAt": "2026-11-04T22:00:00+00:00",
  "samSolicitationNumber": "80NSSC27948561Q",
  "samDepartment": "NATIONAL AERONAUTICS AND SPACE ADMINISTRATION",
  "samSubTier": "NATIONAL AERONAUTICS AND SPACE ADMINISTRATION",
  "samOffice": "NASA SHARED SERVICES CENTER",
  "samNaicsCode": "541519",
  "samPscCode": "7A20",
  "samSetAsideCode": "SBA",
  "samSetAside": "Small Business Set Aside - Total",
  "samPopState": "VA",
  "samPopZip": "23681",
  "samArchiveDate": "2026-11-21",
  "samPrimaryContact": null
}
```

For award notices `awardInfo` is filled, for example:

```json
"awardInfo": {
  "winners": [{ "name": "GENTRY CONTROLS & CONSULTING LLC Lago Vista TX 78645 USA", "country": "US" }],
  "awardedValue": { "amount": 3295000, "currency": "USD" },
  "awardDate": "2026-11-03"
}
```

Notice type mapping: Solicitation and Combined Synopsis/Solicitation = `contract-notice`; Presolicitation and Sources Sought = `prior-information`; Award Notice = `contract-award`; Modification/Amendment/Cancel = `contract-modification`; Justification and J\&A (sole source) = `voluntary-ex-ante`; Special Notice, Sale of Surplus Property, Consolidate/Bundle = `other`. The native type is always in `noticeTypeCode`.

### Pricing

Pay only for the results you get. Set **Maximum results** (and the run's maximum cost) to control spending: the Actor stops as soon as either limit is reached. Runs that find no notices return no results and charge nothing. See the Pricing tab of this Actor for the current price.

Measured platform cost: the default run (20 results) takes about 4 seconds; a 500-result run also takes about 4 seconds. Scanning the entire extract for a rare keyword takes about 4 seconds in the cloud as well.

### API, MCP and AI agents

Every Apify Actor can be called over the API, and this one is also available as a tool for AI agents.

**Apify API (Python)**

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("nexus-scrapers/sam-gov-opportunities").call(run_input={
    "naicsCodes": ["5415"], "states": ["VA"], "openForResponseOnly": True, "maxItems": 50,
})
for n in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(n["publicationDate"], n["buyer"]["name"], n["title"], n["submissionDeadline"])
```

**Apify API (JavaScript)**

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('nexus-scrapers/sam-gov-opportunities').call({ keyword: 'cybersecurity', maxItems: 50 });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

### FAQ

**Do I need a SAM.gov account or an api.data.gov key?** No. The Actor reads the public bulk extract, which needs neither. (The official Opportunities API needs a key and is rate-limited for non-federal users; this Actor does not use it.)

**Why are there no closed or old notices?** The public extract holds active notices only. For history, run the Actor on a schedule and keep the datasets.

**How fresh is the data?** The extract is regenerated once a day (around 04:30 GMT). The dataset's status message shows the extract's timestamp.

**Why is the awardee one long string?** SAM.gov publishes name and address in one field; the Actor does not guess where the name ends. State and ZIP are parsed separately.

**Why is `estimatedValue` always null?** Solicitation values are not part of the public extract.

**Can I get the attachments?** No, only the notice data and the link to the notice page.

**Is it allowed?** The Actor downloads a file that SAM.gov publishes for public use, once per run, and does not scrape the website or use a SAM.gov login. See below.

### Data licence and privacy

- **Source**: SAM.gov Data Services, "Contract Opportunities" public extract (privacy = Public), listed on [data.gov](https://catalog.data.gov/dataset/contract-opportunities-from-sam-gov). The content is created by US federal agencies (US Government works). The data.gov entry does not state an explicit licence, and SAM.gov's [Terms of Use](https://sam.gov/about/terms-of-use) forbid web scraping and bots against the website; this Actor does not scrape the website, it downloads the published extract. You are responsible for your own use of the data under the SAM.gov terms.
- **Awardee names and addresses** in award notices may include Dun & Bradstreet "Open Data" fields, which SAM.gov asks users to attribute to D\&B and not to share in bulk. If you plan to republish award data, check the terms first.
- **Personal data**: by default no contact names, e-mails or phone numbers are output. With `includeContacts` the Actor adds the point of contact exactly as the agency published it in the notice (a named government official); use it only for business correspondence about that notice.
- The Actor is not affiliated with or endorsed by the US General Services Administration or SAM.gov.

# Actor input Schema

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

Word or phrase that must appear in the title, description or solicitation number (case-insensitive). Separate alternatives with a comma: 'solar, photovoltaic' matches either. Leave empty to search everything.

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

North American Industry Classification System codes with prefix matching: '54' = all professional and technical services, '541512' = computer systems design.

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

Product and Service Codes with prefix matching: 'D3' = IT and telecom services, '7030' = software, 'Y1' = construction of buildings.

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

Which kinds of notices to return. Leave empty for all types.

## `samNoticeTypes` (type: `array`):

Optional exact SAM.gov notice types, for example only 'Sources Sought'. Combined with the notice types above (AND), so set 'Notice types' to empty to use this alone.

## `setAsides` (type: `array`):

Only notices reserved for these small-business programs (a notice matches if any of its set-aside codes is selected). Use NONE for notices with no set-aside.

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

Words that must appear in the department, sub-tier agency or office name, case-insensitive: 'army', 'veterans', 'general services'. A notice matches if any entry matches.

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

Two-letter US state codes of the place of performance, e.g. VA, TX, DC. Notices without a stated state are excluded when this filter is set.

## `daysBack` (type: `integer`):

Only notices posted in the last N days. Ignored if 'Posted from' or 'Posted to' is set. Use 0 for no date limit (the whole extract is then scanned, about 215 MB).

## `dateFrom` (type: `string`):

Earliest posting date, format YYYY-MM-DD. Overrides 'last N days'.

## `dateTo` (type: `string`):

Latest posting date (inclusive), format YYYY-MM-DD.

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

Exclude notices whose response deadline has already passed. Notices without a deadline are kept.

## `deadlineFrom` (type: `string`):

Earliest response deadline, YYYY-MM-DD. Notices without a deadline are excluded when set.

## `deadlineTo` (type: `string`):

Latest response deadline (inclusive), YYYY-MM-DD.

## `minAwardValue` (type: `number`):

Only award notices with an awarded amount at or above this value. Setting an award filter excludes all non-award notices.

## `maxAwardValue` (type: `number`):

Only award notices with an awarded amount at or below this value.

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

Add the primary and secondary point of contact (title, name, e-mail, phone) exactly as published in the official notice. Off by default; these are named public officials, use them for business correspondence about the notice only.

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

Maximum number of notices to return, newest first. You are charged per result, so keep this low while testing.

## Actor input object example

```json
{
  "keyword": "cybersecurity, zero trust",
  "naicsCodes": [
    "5415"
  ],
  "pscCodes": [
    "D3"
  ],
  "noticeTypes": [
    "contract-notice"
  ],
  "agencies": [
    "army",
    "navy"
  ],
  "states": [
    "VA",
    "MD"
  ],
  "daysBack": 7,
  "dateFrom": "2026-10-01",
  "dateTo": "2026-10-31",
  "openForResponseOnly": false,
  "deadlineFrom": "2026-11-15",
  "deadlineTo": "2026-12-31",
  "minAwardValue": 100000,
  "maxAwardValue": 5000000,
  "includeContacts": false,
  "maxItems": 20
}
```

# Actor output Schema

## `overview` (type: `string`):

All notices in the default dataset, opened on the Overview table (posted date, type, title, agency, NAICS, set-aside, deadline, link).

## `awards` (type: `string`):

The same dataset opened on the Awards view: awardee, amount and award number from Award Notices.

# 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 = {
    "noticeTypes": [
        "contract-notice"
    ],
    "daysBack": 7,
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("nexus-scrapers/sam-gov-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 = {
    "noticeTypes": ["contract-notice"],
    "daysBack": 7,
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("nexus-scrapers/sam-gov-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 '{
  "noticeTypes": [
    "contract-notice"
  ],
  "daysBack": 7,
  "maxItems": 20
}' |
apify call nexus-scrapers/sam-gov-opportunities --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nexus-scrapers/sam-gov-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/LMVa65SVuo5ym6gnH/builds/xhAGKK6Pya1WnhtUq/openapi.json
