# SAM.gov Federal Contract Opportunities (Unofficial) (`syntrovia/federal-opportunities-sam-gov-extract`) Actor

Unofficial tool. Get U.S. federal contract opportunities from the public daily extract file published on SAM.gov. Filter by NAICS, PSC, set-aside, state, agency and keywords, and schedule only-new runs for a daily bid feed. No API key, no contact-person data.

- **URL**: https://apify.com/syntrovia/federal-opportunities-sam-gov-extract.md
- **Developed by:** [Syntrovia Data](https://apify.com/syntrovia) (community)
- **Categories:** Business, Lead generation
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 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 Federal Contract Opportunities (Unofficial)

> **Unofficial tool.** This Actor is not affiliated with, endorsed by or sponsored by the U.S. General Services Administration (GSA), SAM.gov or any U.S. government agency. "SAM.gov" is used only to identify the source of the public data file.

**Get U.S. federal contract opportunities from SAM.gov as a spreadsheet or JSON feed.** Pick a date window, filter by NAICS or PSC code, set-aside, state, agency, notice type and keywords, and download JSON, CSV or Excel. Each record has the posted date, the response deadline when one is published, the buying office, NAICS and PSC codes, the set-aside and a link to the full notice on SAM.gov. The data comes from the public daily extract file that GSA publishes, so you need no SAM.gov account and no API key.

**Try it now:** click **Try for free**, then **Start**. The prefilled input `{"postedWithinDays": 2, "maxItems": 20}` returns 20 notices posted in the last 2 days and costs at most $0.045.

**Looking for a SAM.gov scraper?** This Actor gives you the notice records without scraping SAM.gov pages. It reads the extract file from the newest notice backwards and stops at the end of your date window; in our test on 14 Nov 2026, a 90-day window took about a minute.

### Who uses it

- **Small businesses and BD teams:** a daily list of new solicitations in your NAICS codes and set-asides (8(a), HUBZone, SDVOSB, WOSB), ready to triage before you open SAM.gov.
- **Capture and proposal managers:** deadline, agency, office and codes in one row per notice, sortable in Excel.
- **GovCon consultants and market researchers:** what each agency buys, by NAICS, PSC and state, over up to 90 days.
- **Award trackers:** award notices with number, date, amount and, for legal entities, the awardee name and state.

### Sample SAM.gov results

| Title | Notice type | Department | NAICS | PSC | Posted |
|---|---|---|---|---|---|
| FCC Yazoo City FY 2027 Q2 Food Service Subsistence Requirements | Combined Synopsis/Solicitation | JUSTICE, DEPARTMENT OF | 311999 | 8945 | 2026-11-13 |
| Y--EMERGENCY FLOOD PROTECTIONS | Award Notice | INTERIOR, DEPARTMENT OF THE | 237990 | Y1PZ | 2026-11-13 |

Two rows from the extract file of 14 Nov 2026, shortened to six of about 30 fields. Contact names, e-mail addresses and phone numbers are not in the results; open `samUrl` to see them on SAM.gov.

### What can this Actor do?

- Reads the public **Contract Opportunities** extract file (`ContractOpportunitiesFullCSV.csv`, about 220 MB) that GSA publishes on [sam.gov/data-services](https://sam.gov/data-services).
- Reads the file **from the newest notice backwards and stops as soon as it passes your date window**. A 2-day window reads about 15 MB; a 90-day window about 125 MB of the 222 MB file (measured on 14 Nov 2026).
- Filters by notice type, NAICS prefix, PSC prefix, set-aside code, place-of-performance state, agency and keywords.
- **Only new notices mode** for daily or hourly schedules: each run skips notices that an earlier run already returned to you.
- Removes personal data: contact names, e-mail addresses, phone and fax numbers, street addresses and free-text descriptions are never returned.
- Checks the file before it saves or charges anything: the run fails at no cost to you when the file is empty or its header or first 200 rows do not have the expected layout.

### What data can you extract?

One record per notice:

| Field | Example | Description |
|---|---|---|
| `noticeId` | `4c6bc11d…305e8e` | Notice ID used by SAM.gov |
| `samUrl` | `https://sam.gov/…/view` | Link to the notice, as given in the file |
| `title` | `FCC Yazoo City FY 2027 Q2 Food Service…` | Notice title |
| `solicitationNumber` | `111326` | Solicitation number |
| `noticeType`, `baseType` | `Combined Synopsis/Solicitation` | Current and original notice type |
| `postedAt` | `2026-11-13T11:46:20` | Posted date and time as published (the file does not state a time zone) |
| `responseDeadline` | `2026-12-04T12:00:00-06:00` | Response deadline as published |
| `archiveType`, `archiveDate` | `auto15`, `2026-12-19` | Archive rule and date |
| `department`, `subTier`, `office` | `JUSTICE, DEPARTMENT OF` | Buying organisation |
| `cgac`, `fpdsCode`, `aacCode` | `015`, `1540`, `15B315` | Agency codes |
| `naicsCode`, `pscCode` | `311999`, `8945` | Industry and product/service codes |
| `setAsideCode`, `setAside` | `SBA`, `Small Business Set Aside - Total` | Set-aside |
| `placeOfPerformance` | `{ city, state, zip, country }` | Where the work is done (no street address) |
| `officeLocation` | `{ city, state, zip, country }` | Contracting office location |
| `award` | `{ number, date, amountUsd, awardeeName, awardeeState, awardeeRedacted }` | For award notices; see "Awardee names" below |
| `source` | `{ name, fileLastModified }` | Which extract file the record came from |
| `collectedAt` | `2026-11-14T10:56:51.013Z` | When the run started |

Each run also stores a `RUN_SUMMARY` record (bytes read, rows scanned, notices saved, stop reason, file date) and an `ATTRIBUTION` record in its key-value store.

#### Awardee names

Award notices name the winning bidder. To avoid publishing data about private individuals, `award.awardeeName` is shown only when the name ends with a legal-entity suffix (INC, INCORPORATED, LLC, CORP, CORPORATION, LTD, LIMITED, LP, LLP, PLLC, PC), the text after it is an address, **and** the award is dated 4 April 2022 or later. Any doubtful case is hidden: names ending in "Co." or "Company" (also used by sole proprietors), suffix-like words that may be part of a place or street name ("University Park", "Corporation Way"), "doing business as" names, and names that contain a house number or a street word. Awardee addresses are never shown; for a shown awardee, only the U.S. state is kept. When a name is hidden, `award.awardeeRedacted` is `true`. On the extract file of 14 Nov 2026 (measured the same day), 91.6% of awardees on awards from 4 April 2022 onwards were shown.

### How to use it

1. Click **Try for free**, set **Posted within the last N days** and any filters you need. Every field is optional.
2. Click **Start**. A typical run finishes in under a minute.
3. Download the results as JSON, CSV, Excel or HTML, or read them through the Apify API.

**Daily alerts:** create a Task with your filters, turn on **Only notices not returned before**, give it a **State name** (for example `it-services-va`), and add a Schedule (for example every day at 07:00 in your time zone). Each run then returns only notices you have not seen yet. Send the results onward with Apify integrations, for example Slack, e-mail, Zapier or Make.

### How much does it cost?

This Actor uses pay-per-event pricing with exactly two events; nothing else is charged. Platform usage is included.

| Event | Price |
|---|---|
| Run start, charged once per run after the source file passed the layout check | $0.005 |
| Notice saved to your dataset | $0.002 ($2.00 per 1,000 notices) |

Examples:

- 1,000 notices in one run: $0.005 + $2.00 = **$2.005**.
- A daily schedule that returns about 20 new notices: $0.045 per run, about **$1.35 per month**.
- A run whose filters match nothing: **$0.005**.

You can set a maximum cost per run; the Actor stops when it reaches it, and only notices that were actually saved count as returned. **You pay nothing** when the input is invalid, or when the source file is empty or its header or first 200 rows do not have the expected layout: the run fails before saving or charging anything. If the layout breaks later in the file, the run stops and you keep (and pay for) the notices saved before that point.

### Input example

```json
{
    "postedWithinDays": 7,
    "noticeTypes": ["Solicitation", "Combined Synopsis/Solicitation"],
    "naicsPrefixes": ["5415"],
    "setAsideCodes": ["SBA", "SDVOSBC"],
    "placeOfPerformanceStates": ["VA", "MD", "DC"],
    "keywords": ["cloud", "cybersecurity"],
    "keywordMode": "any",
    "onlyNewSinceLastRun": true,
    "stateName": "it-services-dmv",
    "maxItems": 500
}
```

Keywords are matched in the title and the description, but the description itself is not returned.

### Output example

```json
[
    {
        "noticeId": "4c6bc11dd46d475698e7c41798305e8e",
        "samUrl": "https://sam.gov/workspace/contract/opp/4c6bc11dd46d475698e7c41798305e8e/view",
        "title": "FCC Yazoo City FY 2027 Q2 Food Service Subsistence Requirements",
        "solicitationNumber": "111326",
        "noticeType": "Combined Synopsis/Solicitation",
        "baseType": "Combined Synopsis/Solicitation",
        "postedAt": "2026-11-13T11:46:20",
        "responseDeadline": "2026-12-04T12:00:00-06:00",
        "archiveType": "auto15",
        "archiveDate": "2026-12-19",
        "active": true,
        "department": "JUSTICE, DEPARTMENT OF",
        "subTier": "FEDERAL PRISON SYSTEM / BUREAU OF PRISONS",
        "office": "FCC YAZOO CITY",
        "cgac": "015",
        "fpdsCode": "1540",
        "aacCode": "15B315",
        "naicsCode": "311999",
        "pscCode": "8945",
        "setAsideCode": "SBA",
        "setAside": "Small Business Set Aside - Total",
        "placeOfPerformance": { "city": "Yazoo City", "state": "MS", "zip": "39194", "country": "USA" },
        "officeLocation": { "city": "YAZOO CITY", "state": "MS", "zip": "39194", "country": "USA" },
        "organizationType": "OFFICE",
        "award": null,
        "source": { "name": "SAM.gov Contract Opportunities public data extract (GSA)", "fileLastModified": "2026-11-14T04:30:20.000Z" },
        "collectedAt": "2026-11-14T10:56:51.013Z"
    },
    {
        "noticeId": "da72f57de09a4361af12db8503eafb4f",
        "title": "Y--EMERGENCY FLOOD PROTECTIONS",
        "noticeType": "Award Notice",
        "postedAt": "2026-11-13T19:11:20",
        "department": "INTERIOR, DEPARTMENT OF THE",
        "naicsCode": "237990",
        "pscCode": "Y1PZ",
        "award": {
            "number": "140GG027P0052",
            "date": "2026-11-13",
            "amountUsd": 390711,
            "awardeeName": "EXAMPLE CONSTRUCTION INC",
            "awardeeState": "WA",
            "awardeeRedacted": false
        },
        "...": "other fields as above"
    }
]
```

The awardee name in the second record is replaced by a placeholder in this README.

### Limits and responsible use

- **Source:** only the public extract file. The Actor does not scrape SAM.gov pages, does not log in and does not use any SAM.gov API key. Each run requests one fresh download link and reads only the part of the file it needs.
- **Freshness:** GSA updates the file once a day (the 14 Nov 2026 file was last modified at 04:30 UTC). Notices posted on SAM.gov today usually appear in the next day's file. If you need notices within minutes of posting, this Actor is not the right tool.
- **No attachments or descriptions:** the file does not include attachments, and descriptions are left out because they often contain the names and phone numbers of contracting staff. Use `samUrl` to read the full notice.
- **Active notices:** on 14 Nov 2026 every row in the file was an active notice (72,204 rows, from 2008 to the previous day). Archived notices are not in this file.
- **Polite access:** the Actor identifies itself with its own User-Agent, uses no proxies and stops on HTTP 401, 403, 407 or 429 instead of retrying. Network errors and server errors are retried up to 3 times with a fresh link (after 10, 30 and 60 seconds).
- **Window:** up to 90 days and 50,000 notices per run. Memory is fixed at 1 GB.
- **Interrupted runs:** if Apify moves the run to another server or you abort it, the Actor finishes the batch it is saving, records it, and stops. A moved run is designed to continue where it left off without saving or charging any notice twice.

### Data source

Source: SAM.gov Contract Opportunities public data extract (https://sam.gov/data-services), U.S. General Services Administration (GSA). This Actor only processes the public extract file. It does not scrape SAM.gov, does not log in and does not use any SAM.gov API key. Contact-person fields are removed. Awardee names are shown only for legal entities and only for awards dated on or after 4 April 2022; awardee addresses are never shown. Descriptions are not included in the results. Unofficial tool, not affiliated with or endorsed by GSA, SAM.gov or any U.S. government agency.

### Data, licensing & privacy

- **What this Actor returns:** factual records from the public source listed in "Data source". Fields are limited to an allow-list; new source fields are not added automatically.
- **No personal data:** this Actor does not return names, e-mail addresses, phone numbers, social profiles or other details of individual people. Records that describe a natural person are reduced to non-identifying fields.
- **Source terms:** the Actor uses only the access channel the source permits (the public bulk file) and stops when it meets a CAPTCHA, a login wall or a rate-limit response.
- **Removal requests:** if you believe a record concerns you personally, open an issue on this Actor's Issues tab with the notice ID. We aim to review requests within 72 hours and exclude confirmed records from future runs.
- Data is provided as is, without warranty. It is not legal, financial or investment advice.
- This Actor is an independent tool and is not affiliated with or endorsed by the data source owners.

### FAQ

**Is it legal to use this data?**
The Actor reads a bulk file that GSA publishes for public download and does not scrape SAM.gov pages. Most federal government works are not protected by copyright in the U.S. You are responsible for how you use the results; this is not legal advice.

**Why did my run stop before reaching Max notices?**
Usually because it reached the end of your date window. Check `stopReason` in the `RUN_SUMMARY` record: `date-cutoff` (window finished), `max-items`, `charge-limit` (your maximum cost per run), or `end-of-file`.

**Why did my run fail with "Source extract is empty or its format changed"?**
On some days the published file is empty or incomplete, or its columns change. The Actor checks the header and the first 200 rows before it saves or charges anything, so such a run costs you nothing. Try again a few hours later.

**Why is there no contracting officer contact?**
Contact names, e-mails and phone numbers belong to individual people, so they are removed. Open the notice through `samUrl` to see them on SAM.gov.

**Do two schedules with "Only notices not returned before" interfere?**
Not if they use different **State name** values. Two runs with the same state name cannot run at the same time; the second one stops with a clear message.

### More data tools from Syntrovia Data

- [Greenhouse & Lever Jobs API (Unofficial)](https://apify.com/syntrovia/ats-jobs-greenhouse-lever): open jobs from the Greenhouse and Lever boards you list, with only-new mode.
- [SEO Audit & Sitemap Checker](https://apify.com/syntrovia/sitemap-seo-check-http): status codes, redirects, titles, meta descriptions and 35+ issue codes for a site you may audit.
- [UK Companies House Data (Unofficial)](https://apify.com/syntrovia/uk-company-register-companies-house): UK company lists by SIC code, postcode or incorporation date.

### Support

Open an issue on the **Issues** tab with your run ID. We aim to review issues and data-removal requests within 72 hours.

# Changelog

This Actor's version history is a separate document: https://apify.com/syntrovia/federal-opportunities-sam-gov-extract/changelog.md

# Actor input Schema

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

Return notices posted in the last N days (UTC calendar days, 1-90). Smaller windows finish faster because the Actor stops reading the file once it passes this date.

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

Keep only these notice types. Leave empty for all types.

## `naicsPrefixes` (type: `array`):

Keep notices whose NAICS code starts with one of these prefixes (2 to 6 digits), for example 5415 for computer systems design.

## `pscPrefixes` (type: `array`):

Keep notices whose product/service code starts with one of these prefixes (1 to 4 letters or digits), for example D3 or R4.

## `setAsideCodes` (type: `array`):

Keep notices with one of these set-aside codes. Leave empty to ignore set-asides.

## `placeOfPerformanceStates` (type: `array`):

Two-letter U.S. state codes, for example VA, TX, CA. Notices without a place of performance are excluded when this is set.

## `agencyKeywords` (type: `array`):

Keep notices whose department, sub-tier or office contains one of these phrases (case-insensitive), for example "army corps of engineers" or "veterans affairs".

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

Phrases matched in the title and description (case-insensitive). The description is used only for matching and is not included in the results.

## `keywordMode` (type: `string`):

"any": a notice needs one of the keywords. "all": it needs every keyword.

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

Keep notices whose response deadline is on or after this date (YYYY-MM-DD). Notices without a deadline are excluded when this is set.

## `onlyNewSinceLastRun` (type: `boolean`):

Skip notices that an earlier run with the same state name already returned. Useful for daily schedules. The list of returned notice IDs is kept in a named key-value store in your own Apify account.

## `stateName` (type: `string`):

Separate memory for each schedule, for example "it-services-va". Lower-case letters, digits and hyphens, up to 40 characters.

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

The run stops after saving this many notices. You pay per saved notice.

## Actor input object example

```json
{
  "postedWithinDays": 2,
  "noticeTypes": [],
  "naicsPrefixes": [],
  "pscPrefixes": [],
  "setAsideCodes": [],
  "placeOfPerformanceStates": [],
  "agencyKeywords": [],
  "keywords": [],
  "keywordMode": "any",
  "onlyNewSinceLastRun": false,
  "stateName": "default",
  "maxItems": 20
}
```

# Actor output Schema

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

No description

## `runSummary` (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 = {
    "postedWithinDays": 2,
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("syntrovia/federal-opportunities-sam-gov-extract").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 = {
    "postedWithinDays": 2,
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("syntrovia/federal-opportunities-sam-gov-extract").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 '{
  "postedWithinDays": 2,
  "maxItems": 20
}' |
apify call syntrovia/federal-opportunities-sam-gov-extract --silent --output-dataset

```

## MCP server setup

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

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/zHoC4jniCsFrwoiWn/builds/L002zLD9xKgZ9a8MO/openapi.json
