# SAM.gov Contract Opportunities - Federal Bids & RFPs (`kantolabs/sam-gov-contract-opportunities`) Actor

Find US federal contract opportunities from SAM.gov's official data: solicitations, RFPs, sources sought and awards. Filter by keyword, NAICS, set-aside, type, agency, state and date. Full text, contacts, deadlines. No API key needed. $3 per 1,000.

- **URL**: https://apify.com/kantolabs/sam-gov-contract-opportunities.md
- **Developed by:** [Kanto Labs](https://apify.com/kantolabs) (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

from $3.00 / 1,000 opportunity returneds

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 - Federal Bids, RFPs & Awards

Find **US federal government contract opportunities** from **SAM.gov's official data**:
solicitations, RFPs, RFQs, combined synopsis/solicitations, presolicitations, **sources sought**
(RFIs), special notices and **award notices**. Filter by **keyword, NAICS code, set-aside
(small business, 8(a), HUBZone, SDVOSB, WOSB...), notice type, agency, place of performance and
posted date**, and get clean rows with the **full notice text, response deadline, contracting
officer contact, place of performance and award amount/awardee**.

**No API key needed.** The actor reads the official public Contract Opportunities data file that
SAM.gov publishes every day, so it does not burn anyone's tiny SAM.gov API quota and does not fail
when the API is slow. **$3 per 1,000 opportunities.**

### What you can use it for

- **Daily bid alerts** - schedule it every morning for your NAICS codes and set-asides; send new opportunities to Slack, email, Google Sheets or your CRM.
- **Capture and BD pipelines** - sources sought and presolicitations show what agencies will buy before the RFP.
- **Competitor and market research** - award notices with awardee and amount, by agency and NAICS.
- **Proposal writing with AI** - the full notice text is in each row, ready for an LLM to summarize or score.
- **GovCon newsletters and dashboards** - clean, consistent fields across every notice type.

### Input

| Field | Example | Notes |
|---|---|---|
| Keywords | `software`, `cybersecurity` | ANY keyword, in title or description. |
| NAICS codes | `541511`, `5415`, `236` | Codes or prefixes. |
| Set-aside types | Total Small Business, SDVOSB, 8(a)... | Or "No set-aside" for unrestricted. |
| Notice types | Solicitation, Combined, Sources Sought... | Empty = all. |
| Agencies | `VETERANS AFFAIRS`, `ARMY` | Partial match on department, agency or office. |
| Place of performance states | `VA`, `TX` | |
| Posted within the last N days | `7` | Or exact "Posted from / to" dates. |
| Only open opportunities | on/off | Drops notices whose deadline has passed. |
| Latest version only | on (default) | Amendments are re-posted as new notices; keeps the newest per solicitation. |
| Max opportunities | `100` | Newest first. |
| Include description text | on (default) | Up to 32,000 characters per notice. |
| Data source | Daily extract (default) / Live API | Live API needs your own SAM.gov API key. |

An empty input `{}` returns the 100 newest notices of the last 7 days.

```json
{
    "naicsCodes": ["5415"],
    "setAsides": ["SBA", "SDVOSBC"],
    "noticeTypes": ["solicitation", "combined", "sourcesSought", "presolicitation"],
    "postedWithinDays": 14,
    "openOnly": true,
    "maxResults": 200
}
```

### Output

Real output from a cloud run (description shortened here):

```json
{
  "noticeId": "ec525ac9d9a443cda29176eb2ed33093",
  "title": "Terrainworks NetMap Software Subscription and Dataset Development-One Source",
  "solicitationNumber": "12760426Q0152",
  "noticeType": "Combined Synopsis/Solicitation",
  "postedDate": "2026-09-22 18:06:16",
  "responseDeadline": "2026-09-25T12:00:00-04:00",
  "archiveDate": "2026-10-10",
  "active": true,
  "department": "AGRICULTURE, DEPARTMENT OF",
  "subTier": "FOREST SERVICE",
  "office": "USDA FOREST SERVICE",
  "naicsCode": "541519",
  "pscCode": "7A21",
  "setAsideCode": "SBA",
  "setAside": "Small Business Set Aside - Total",
  "placeOfPerformance": { "streetAddress": null, "city": "Petersburg", "state": "AK", "zip": "99833", "country": "USA" },
  "primaryContact": { "title": null, "name": "Derick Yara", "email": "derick.yara@usda.gov", "phone": null, "fax": null },
  "officeAddress": { "city": "Albuquerque", "state": "NM", "zip": "87102", "country": "USA" },
  "award": null,
  "samUrl": "https://sam.gov/opp/ec525ac9d9a443cda29176eb2ed33093/view",
  "description": "This is a combined synopsis/solicitation for commercial items prepared in accordance with the format in FAR Part 12. ...",
  "descriptionTruncated": false,
  "dataSource": "SAM.gov daily public extract",
  "dataAsOf": "Wed, 23 Sep 2026 03:30:43 GMT"
}
```

Award notices fill `award` with `number`, `date`, `amount` (USD) and `awardee`. Other fields:
`baseType`, `archiveType`, `cgac`, `fpdsCode`, `aacCode`, `secondaryContact`,
`additionalInfoUrl`, `resourceLinks` (Live API only). The Console has an **Opportunities** table
and an **Awards** table.

### Daily extract vs Live API

| | Daily extract (default) | Live API |
|---|---|---|
| Key | none | your SAM.gov API key (free, from sam.gov Account Details) |
| Freshness | refreshed daily around 03:30 UTC | live |
| Description text | yes | no (the API only returns a link) |
| Limits | none | SAM.gov gives personal keys a small daily request quota; "Max API requests" protects it |

For daily alerts, schedule the actor after 04:00 UTC with "Posted within the last N days" = 1 or 2.

### Pricing

**$3 per 1,000 opportunities** ($0.003 each) plus a tiny actor start fee ($0.00005).

| Opportunities | Cost |
|---|---|
| 100 | $0.30 |
| 1,000 | $3.00 |
| 10,000 | $30.00 |

You pay only for opportunities returned after your filters. **Download failures, API errors and
searches with no matches are free** (they appear as rows with an `error` field). Set "Maximum cost
per run" and the actor stops cleanly when it is reached. A typical run takes 5-60 seconds.

### FAQ

**Is this scraping SAM.gov?** No. It reads the public Contract Opportunities data extract that
SAM.gov Data Services publishes for download, or the official Get Opportunities API with your key.

**Does it include archived notices?** The daily extract contains the notices that are currently
published on SAM.gov. Use the Live API for older posted-date ranges (up to one year per request).

**Why do some rows have no place of performance or deadline?** Contracting offices do not fill
every field; award and special notices usually have no response deadline.

**Can I get the attachments?** Open `samUrl` for the attachments; with the Live API source,
`resourceLinks` lists the attachment URLs.

# Actor input Schema

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

An opportunity matches when ANY keyword appears in its title or description (case-insensitive phrase match). Leave empty for everything that passes the other filters.

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

6-digit NAICS codes or prefixes: `541511` (custom programming), `5415` (all computer systems design), `236` (all building construction).

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

Keep only opportunities reserved for these business types. Empty = all, including unrestricted.

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

Empty = all types. Bidders usually want Solicitation, Combined Synopsis/Solicitation, Presolicitation and Sources Sought.

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

Match on the department, sub-tier agency or office name (case-insensitive, partial): `VETERANS AFFAIRS`, `ARMY`, `NASA`, `FOREST SERVICE`.

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

Two-letter state codes (`VA`, `TX`). Opportunities without a place of performance are excluded when this is set.

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

Ignored when 'Posted from' is set.

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

Optional exact start date (YYYY-MM-DD).

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

Optional end date, inclusive (YYYY-MM-DD). Default: today.

## `openOnly` (type: `boolean`):

Drop notices whose response deadline has already passed. Notices without a deadline (awards, most special notices) are dropped too.

## `latestVersionOnly` (type: `boolean`):

SAM.gov publishes every amendment as a new notice with the same solicitation number. On = keep only the newest notice per solicitation number and type.

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

Stop after this many matching opportunities (newest first).

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

The notice text (up to 32,000 characters) from the SAM.gov data extract. Turn off for smaller rows.

## `dataSource` (type: `string`):

Daily extract (default, no key) reads SAM.gov's official public Contract Opportunities file, refreshed every day around 03:30 UTC, and includes the description text. Live API calls the official Get Opportunities API with YOUR SAM.gov API key: fresh to the minute, but SAM.gov gives personal keys only a small daily request quota.

## `apiKey` (type: `string`):

Only needed for the Live API source. Free: sign in at sam.gov, open your profile's Account Details and request a Public API Key. Stored encrypted.

## `maxApiRequests` (type: `integer`):

Protects your daily SAM.gov quota. Each request returns up to 1,000 notices.

## Actor input object example

```json
{
  "keywords": [
    "software",
    "cybersecurity"
  ],
  "postedWithinDays": 7,
  "openOnly": false,
  "latestVersionOnly": true,
  "maxResults": 100,
  "includeDescription": true,
  "dataSource": "extract",
  "maxApiRequests": 3
}
```

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

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

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

```

## MCP server setup

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