# SAM.gov Contract Opportunities & Awards - No API Key (`jpopendata/us-sam-opportunities`) Actor

U.S. federal contract opportunities and awards from SAM.gov's official public data extract: agency, NAICS, PSC, set-aside, deadline, place of performance, award amount, awardee company. Filters: keyword, agency, NAICS, type, state, set-aside, date. No API key. Unofficial; not affiliated with GSA.

- **URL**: https://apify.com/jpopendata/us-sam-opportunities.md
- **Developed by:** [JP Open Data](https://apify.com/jpopendata) (community)
- **Stats:** 2 total users, 1 monthly users, 100.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 Opportunities & Awards — official public extract, no API key

Get U.S. federal contract opportunities and award notices from **SAM.gov's official public Contract Opportunities data extract** (GSA Data Services). There is no SAM.gov account and no API key. Every row comes in one clean English schema: agency, NAICS, PSC, set-aside, posting date, response deadline, place of performance (city and state), award number, award amount and the **awarding company**, plus a direct SAM.gov link.

- **Official channel, not website scraping.** SAM.gov's Terms of Use name its APIs and its **Data Services extracts** (`sam.gov/data-services`) as the way it makes data available. This Actor downloads only the file marked *Public* there. It never scrapes the website or its internal search API.
- **Fast and light.** The extract (about 70,000 active notices, refreshed daily) is sorted newest first. The Actor streams it and stops as soon as your date window and row limit are satisfied, so a recent-window search downloads only a fraction of the file (the Quick start reads about 2 MB) and finishes in seconds, in 2 requests.
- **Privacy-safe by design.** No contracting officers' names, e-mails or phone numbers, no notice descriptions, no street addresses. Awardee names are shown only for registered companies (LLC, Inc., Corp., Ltd., …).

### Quick start — verified input

```json
{
  "daysBack": 7,
  "maxItems": 20
}
```

This returns the newest 20 notices posted in the last 7 days. An empty input `{}` does exactly the same.

A typical bid-monitoring input:

```json
{
  "naicsCodes": ["541512", "541519"],
  "noticeTypes": ["solicitation", "combined_synopsis_solicitation", "sources_sought"],
  "setAsides": ["small business"],
  "onlyOpen": true,
  "daysBack": 14,
  "maxItems": 500
}
```

### What you get

One row per notice, newest first:

| Field | Description |
|---|---|
| `noticeId`, `samUrl` | SAM.gov notice ID and the public notice page |
| `title`, `solicitationNumber` | Notice title and solicitation number |
| `noticeType`, `noticeTypeLabel`, `baseNoticeType` | `solicitation`, `combined_synopsis_solicitation`, `presolicitation`, `sources_sought`, `special_notice`, `award_notice`, `justification`, `sale_of_surplus_property`, `intent_to_bundle`; the SAM.gov label; the notice's original type |
| `department`, `subTier`, `office` (+ `departmentCode`, `subTierCode`, `officeCode`) | Buying organization and its CGAC / FPDS / AAC codes |
| `officeCity`, `officeState`, `officeCountry` | Location of the contracting office |
| `postedDate`, `postedDateTime` | When the notice was posted (as published by SAM.gov) |
| `responseDeadline`, `responseDeadlineUtc`, `isOpenForResponses` | Response deadline as published, in UTC when SAM.gov gives a time zone, and whether it is still in the future |
| `naicsCode`, `pscCode` | Industry (NAICS) and product/service (PSC) codes |
| `setAsideCode`, `setAside` | e.g. `SBA` / "Small Business Set Aside - Total", `SDVOSBC`, `8A`, `WOSB`, `HZC` |
| `placeOfPerformanceCity`, `placeOfPerformanceState`, `placeOfPerformanceStateName`, `placeOfPerformanceCountry` | Where the work is performed (city and state only) |
| `awardNumber`, `awardDate`, `awardAmount` | Award details on award notices |
| `awardeeName`, `awardeeWithheld`, `awardeeWithheldReason` | The awarding company (legal name only, address removed), or why it is withheld |
| `archiveType`, `archiveDate` | When SAM.gov archives the notice |
| `matchedKeywords` | Which of your keywords matched |
| `source`, `sourceUrl`, `license`, `retrievedAt` | Attribution on every row |

#### Example output

```json
{
  "noticeId": "fc6eefee8325431dbd05077d90c72f78",
  "title": "R499--FY26 Lifeguard and Pool Maintenance Services (B+ OPT)",
  "solicitationNumber": "36C24226Q0994",
  "noticeType": "solicitation",
  "noticeTypeLabel": "Solicitation",
  "department": "VETERANS AFFAIRS, DEPARTMENT OF",
  "subTier": "VETERANS AFFAIRS, DEPARTMENT OF",
  "office": "242-NETWORK CONTRACT OFFICE 02 (36C242)",
  "officeCode": "36C242",
  "officeCity": "ALBANY",
  "officeState": "NY",
  "postedDate": "2026-10-11",
  "postedDateTime": "2026-10-11T16:24:24",
  "responseDeadline": "2026-10-20T10:00:00-04:00",
  "responseDeadlineUtc": "2026-10-20T14:00:00.000Z",
  "isOpenForResponses": true,
  "naicsCode": "561210",
  "pscCode": "R499",
  "setAsideCode": null,
  "awardeeName": null,
  "samUrl": "https://sam.gov/opp/fc6eefee8325431dbd05077d90c72f78/view",
  "source": "SAM.gov Contract Opportunities public data extract (U.S. General Services Administration)",
  "license": "U.S. Government work, public domain in the U.S. (17 U.S.C. 105); source: SAM.gov (GSA), public Contract Opportunities data extract. Points of contact and notice descriptions are omitted. Unofficial tool, not affiliated with or endorsed by GSA or SAM.gov.",
  "retrievedAt": "2026-10-12T18:47:25.126Z"
}
```

An award notice (abridged):

```json
{
  "title": "47--TUBE ASSEMBLY,METAL,BRANCHED",
  "noticeType": "award_notice",
  "department": "DEPT OF DEFENSE",
  "subTier": "DEFENSE LOGISTICS AGENCY",
  "office": "DLA WEAPONS SUPPORT",
  "naicsCode": "326122",
  "awardNumber": "SPE7L327D60BH",
  "awardDate": "2026-10-09",
  "awardAmount": 350000,
  "awardeeName": "OSHKOSH DEFENSE LLC",
  "awardeeWithheld": false,
  "samUrl": "https://sam.gov/opp/a0635b91fb0e40d2ad788133706d889e/view"
}
```

### Input

All fields are optional.

| Field | What to enter |
|---|---|
| `keywords` | Words or phrases (whole words, any case), e.g. `"cybersecurity"`, `"janitorial"`. A notice matches if it contains ANY of them in the title, solicitation number or description. |
| `searchDescriptions` | `true` (default) also searches the description. The description itself is never output. |
| `noticeTypes` | Type codes above, SAM.gov labels, or words: `award`, `RFI` (sources sought), `RFP`/`RFQ` (solicitation + combined), `opportunities`. |
| `agencies` | Part of the department / sub-tier / office name (`"Navy"`, `"Forest Service"`), an abbreviation (`DoD`, `VA`, `GSA`, `DHS`, `DLA`, `NASA`, `USACE`, `NIH`, `FAA` …) or an agency code (`097`, `97AS`, `SPE4A5`). |
| `naicsCodes` | NAICS codes or prefixes (2–6 digits): `"541512"`, `"5415"`, `"236"`. |
| `pscCodes` | PSC codes or prefixes (1–4 characters): `"R499"`, `"D3"`, `"59"`. |
| `setAsides` | Codes (`SBA`, `8A`, `HZC`, `SDVOSBC`, `WOSB`, `EDWOSB`, `VSA`, `ISBEE`, `NONE` …) or words: `small business`, `8(a)`, `HUBZone`, `SDVOSB`, `WOSB`, `veteran`, `Indian`, `none`, `any`. |
| `states` | Place-of-performance states: `"TX"`, `"Virginia"`, `"DC"`, `"PR"`. |
| `useOfficeStateWhenNoPlace` | Match `states` against the contracting office's state when a notice publishes no place of performance. |
| `daysBack` | Notices posted in the last N days (default 7). `0` = every active notice in the extract. |
| `postedFrom`, `postedTo` | Posting-day window, `YYYY-MM-DD` or `MM/DD/YYYY` (UTC days). |
| `deadlineFrom`, `deadlineTo` | Response-deadline window, `YYYY-MM-DD`. |
| `onlyOpen` | Only notices whose response deadline is still ahead. |
| `maxItems` | Maximum rows, newest first (default 20, up to 100,000). |
| `proxyConfiguration` | Not needed; SAM.gov answers Apify datacenter IPs. |

### Common input mistakes

| Instead of | Use |
|---|---|
| `"states": ["Austin"]` | `"states": ["TX"]` (cities are not states) |
| `"naicsCodes": ["software"]` | `"naicsCodes": ["5415"]` and put words in `keywords` |
| `"setAsides": ["small biz"]` | `"setAsides": ["small business"]` or `["SBA"]` |
| `"noticeTypes": ["contract"]` | `"noticeTypes": ["award"]` or `["solicitation"]` |
| `"postedFrom": "last week"` | `"daysBack": 7` or `"postedFrom": "2026-10-01"` |
| `onlyOpen` with `noticeTypes: ["award"]` | Award notices have no response deadline, so drop `onlyOpen` |

Invalid values stop the run at once, before anything is downloaded, with a message listing the valid values.

### Empty results?

A run with no match succeeds with 0 rows (nothing is charged per row). Typical causes:

- **A short window with narrow filters.** Widen `daysBack`, or use `0` to search every active notice.
- **About 3 in 4 notices publish no place-of-performance state** (many supply notices). Turn on `useOfficeStateWhenNoPlace` or drop `states`.
- **`onlyOpen` or a deadline window** drops notices without a deadline (most award and special notices).
- **A 6-digit NAICS code** that no agency used in the window. Try its 4-digit prefix.

### How it works

1. One request to `https://sam.gov/api/prod/fileextractservices/v1/api/download/Contract Opportunities/datagov/ContractOpportunitiesFullCSV.csv?privacy=Public`. SAM.gov answers with a temporary download link to its file storage.
2. The CSV (about 200 MB, refreshed once a day) is streamed newest first and decoded. The file mixes Windows-1252 and UTF-8 text; both are handled.
3. Rows are normalized, filtered, sorted by posting time and pushed. The connection is closed once your window and `maxItems` are satisfied.

Requests are sequential, at least 1.2 s apart, use an honest User-Agent, and honor `Retry-After`. Only the public extract and its download link are ever requested; `robots.txt` is checked before each request.

### What is deliberately not included

- **Points of contact** (contracting officers' names, e-mails, phones): personal data. Use `samUrl` to reach the notice on SAM.gov.
- **Notice descriptions and attachments**: descriptions often contain personal contact details. Keywords still search them.
- **Street addresses and ZIP codes**: places stop at city and state.
- **Awardees that are not identifiable as companies** (individuals, sole proprietors' trade names, "dba"/"c/o" names): withheld, with `awardeeWithheld: true` and a reason.
- **Awardees of awards dated before 2022-04-04**: SAM.gov's Restricted Data Use terms say these may be Dun & Bradstreet data, which may not be redistributed in bulk.

### Legal and disclaimer

- **Unofficial / not affiliated.** This Actor is an independent tool. It is not affiliated with, endorsed by or sponsored by the U.S. General Services Administration (GSA) or SAM.gov.
- **Public data only.** It reads only the SAM.gov Data Services file marked *Public*, which GSA also lists on data.gov as a public dataset. No login, no API key, no restricted or sensitive data.
- **Your responsibility.** You are responsible for using the data in line with the SAM.gov Terms of Use and applicable laws.
- **GDPR / privacy.** No personal contact data is output. Awardee names are limited to registered companies.
- **Attribution.** Works of the U.S. Government are in the public domain in the U.S. (17 U.S.C. 105). SAM.gov asks for citation and a link back; every row carries `source`, `sourceUrl` and `license`.

### FAQ

**How fresh is the data?** SAM.gov refreshes the extract once a day; the run summary (`RUN_SUMMARY` in the key-value store) shows the file's refresh time.

**Does it return only new notices on a schedule?** It returns the notices posted in your window. For daily monitoring, schedule it with `daysBack: 1` or `2` and de-duplicate on `noticeId`.

**Why do some awardees show `null`?** See "What is deliberately not included". The award number, amount and date are still there.

# Actor input Schema

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

Optional. Words or phrases to find in the notice title, solicitation number or description (whole words, any case), e.g. "cybersecurity", "janitorial", "body armor". A notice matches if it contains ANY of them. Leave empty for all notices.

## `searchDescriptions` (type: `boolean`):

Also look for the keywords in the notice description. The description itself is never output (it often contains contracting officers' names, e-mails and phone numbers). Turn off to match titles and solicitation numbers only.

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

Optional. solicitation, combined_synopsis_solicitation, presolicitation, sources_sought, special_notice, award_notice, justification, sale_of_surplus_property, intent_to_bundle. SAM.gov labels ("Combined Synopsis/Solicitation", "Sources Sought") and words like award, RFI (= sources sought), RFP / RFQ (= solicitation + combined) or opportunities (solicitation, combined, presolicitation, sources sought) also work. Empty = all.

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

Optional. Part of the department, sub-tier or office name, e.g. "Veterans Affairs", "Navy", "Defense Logistics Agency", "Forest Service". Common abbreviations work (DoD, VA, GSA, DHS, DLA, NASA, USACE, NIH, FAA ...), and so do agency codes (CGAC "097", FPDS sub-tier "97AS", office AAC "SPE4A5"). Any match counts.

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

Optional. NAICS codes or prefixes (2 to 6 digits), e.g. "541512" (computer systems design), "5415" (every code starting 5415), "236" (building construction).

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

Optional. Product and Service Codes or prefixes (1 to 4 characters), e.g. "R499", "D3" (IT services), "J065", "59" (electrical components).

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

Optional. Set-aside codes (SBA, SBP, 8A, 8AN, HZC, HZS, SDVOSBC, SDVOSBS, WOSB, WOSBSS, EDWOSB, EDWOSBSS, VSA, VSS, ISBEE, IEE, BICiv, LAS, ESB, NONE) or words: small business, 8(a), HUBZone, SDVOSB, WOSB, veteran, Indian, none (no set-aside), any (any set-aside at all).

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

Optional. U.S. states where the work is performed: two-letter codes or names, e.g. "TX", "Virginia", "DC", "PR". About 3 in 4 notices publish no place-of-performance state (many supply notices); they are dropped unless the next option is on.

## `useOfficeStateWhenNoPlace` (type: `boolean`):

When a notice publishes no place-of-performance state, match the States filter against the contracting office's state instead.

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

Read notices posted in the last N days (UTC days, 0..3650). 0 = every active notice in the extract (about 70,000, some posted years ago). Ignored when Posted from is set. The extract is sorted newest first, so a short window downloads only the start of the file.

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

Optional. First posting day, YYYY-MM-DD (UTC), e.g. "2026-10-01". MM/DD/YYYY, "today" and "yesterday" also work.

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

Optional. Last posting day, YYYY-MM-DD (UTC). Empty = up to the newest notice.

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

Optional. Keep only notices whose response deadline is on or after this day, YYYY-MM-DD. Notices without a deadline are dropped when this is set.

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

Optional. Keep only notices whose response deadline is on or before this day, YYYY-MM-DD.

## `onlyOpen` (type: `boolean`):

Keep only notices whose response deadline is still in the future. Notices without a deadline (most award and special notices) are dropped.

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

Maximum notices (1..100000), newest first. You are charged per notice.

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

Optional and normally not needed: SAM.gov and its download storage answer Apify datacenter IPs. If set, one sticky session is used for the whole run (never rotation).

## Actor input object example

```json
{
  "keywords": [],
  "searchDescriptions": true,
  "noticeTypes": [],
  "agencies": [],
  "naicsCodes": [],
  "pscCodes": [],
  "setAsides": [],
  "states": [],
  "useOfficeStateWhenNoPlace": false,
  "daysBack": 7,
  "postedFrom": "",
  "postedTo": "",
  "deadlineFrom": "",
  "deadlineTo": "",
  "onlyOpen": false,
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `records` (type: `string`):

One row per SAM.gov notice, newest first, with the attribution (source, sourceUrl, license, retrievedAt) on every item.

# 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": [],
    "searchDescriptions": true,
    "noticeTypes": [],
    "agencies": [],
    "naicsCodes": [],
    "pscCodes": [],
    "setAsides": [],
    "states": [],
    "useOfficeStateWhenNoPlace": false,
    "daysBack": 7,
    "postedFrom": "",
    "postedTo": "",
    "deadlineFrom": "",
    "deadlineTo": "",
    "onlyOpen": false,
    "maxItems": 20,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("jpopendata/us-sam-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": [],
    "searchDescriptions": True,
    "noticeTypes": [],
    "agencies": [],
    "naicsCodes": [],
    "pscCodes": [],
    "setAsides": [],
    "states": [],
    "useOfficeStateWhenNoPlace": False,
    "daysBack": 7,
    "postedFrom": "",
    "postedTo": "",
    "deadlineFrom": "",
    "deadlineTo": "",
    "onlyOpen": False,
    "maxItems": 20,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("jpopendata/us-sam-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": [],
  "searchDescriptions": true,
  "noticeTypes": [],
  "agencies": [],
  "naicsCodes": [],
  "pscCodes": [],
  "setAsides": [],
  "states": [],
  "useOfficeStateWhenNoPlace": false,
  "daysBack": 7,
  "postedFrom": "",
  "postedTo": "",
  "deadlineFrom": "",
  "deadlineTo": "",
  "onlyOpen": false,
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call jpopendata/us-sam-opportunities --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,jpopendata/us-sam-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/dR7hr8wCeOp6NufdH/builds/vfgR9aHnnRIx7S2e2/openapi.json
