# SAM.gov Scraper - Federal Contracts & Grants, No API Key (`loomwise/federal-opportunities`) Actor

Scrape SAM.gov federal contract opportunities (RFPs, solicitations, sources sought, awards) plus Grants.gov grants. Filter by NAICS, set-aside, agency, state, keyword. No API key, no rate cap. Daily bid alerts. $2/1k.

- **URL**: https://apify.com/loomwise/federal-opportunities.md
- **Developed by:** [Loomwise](https://apify.com/loomwise) (community)
- **Categories:** Lead generation, Business, AI
- **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 Scraper: federal contract opportunities, RFPs and grants (no API key)

A SAM.gov scraper alternative and **government contracts API** for GovCon BD teams, bid-alert services and AI agents. Get a clean, filtered feed of **US federal contract opportunities from SAM.gov**, with optional **federal grant opportunities from Grants.gov**. Filter by keyword, NAICS code, set-aside, agency, place-of-performance state, notice type and posted date. Export to JSON, CSV or Excel, or schedule a daily alert.

- **No SAM.gov API key and no 10-requests-per-day cap.** The Actor reads SAM.gov's official public daily extract of all active opportunities.
- **Fast:** a "last 7 days" search usually finishes in a few seconds. The source file is newest-first, so the Actor stops reading as soon as it passes your date window.
- **Privacy-safe:** contact names, e-mails and phone numbers are never included. E-mails and phone numbers are also removed from description snippets.
- **One schema for both sources**, so contracts and grants land in the same spreadsheet.
- **Simple pricing:** $2 per 1,000 results. You pay only for opportunities that are delivered.

### What data does it return?

One row per opportunity:

| Field | Example |
|---|---|
| `id` | `045e7a7863ff4ef2845155e13504c4c6` |
| `source` | `sam.gov` or `grants.gov` |
| `title` | Boiler Inspection Services |
| `solicitationNumber` | `36C26026Q0977` |
| `agency` / `subAgency` / `office` | VETERANS AFFAIRS, DEPARTMENT OF / … |
| `noticeType` | Solicitation, Combined Synopsis/Solicitation, Sources Sought, Award Notice, Grant (posted)… |
| `naicsCode` | `238220` |
| `classificationCode` (PSC) | `H345` |
| `setAsideCode` / `setAside` | `SDVOSBC` / Service-Disabled Veteran-Owned Small Business Set-Aside |
| `postedDate` | `2026-10-16` |
| `responseDeadline` | `2026-10-23T12:00:00-04:00` |
| `archiveDate` | `2026-11-07` |
| `popCity` / `popState` / `popZip` / `popCountry` | place of performance |
| `link` | link to the notice on SAM.gov or Grants.gov |
| `descriptionSnippet` | first ~300 characters of the description as plain text |
| `fundingInstrument`, `assistanceListings`, `awardCeiling`, `awardFloor` | Grants.gov only (`null` for contracts) |

### Who uses it

- **Small and mid-size government contractors:** get every new solicitation in your NAICS codes and set-aside programs (8(a), HUBZone, SDVOSB, WOSB) each morning.
- **Bid and proposal consultants and BD teams:** track several clients' NAICS/agency profiles with one scheduled task per client.
- **Bid-alert and lead-gen services:** feed fresh opportunities into your CRM, newsletter or Slack through the Apify API, webhooks or integrations.
- **Grant writers and nonprofits:** turn on Grants.gov to see posted and forecasted grants next to contract work.
- **Market researchers and AI agents:** structured, deduplicated federal demand signals by agency, NAICS and region.

### How to use it

1. Enter keywords and/or NAICS codes. Leave everything empty to get all recent notices.
2. Optionally narrow by set-aside, agency, state and notice type.
3. Choose a date window. The default is the last 7 days.
4. Run it, then download the results as JSON, CSV, Excel or HTML, or read them through the API.
5. For daily alerts, **schedule** the Actor with `postedWithinDays: 1` and connect a webhook, e-mail or Slack integration.

### Input example

```json
{
  "keywords": ["HVAC", "boiler"],
  "naicsCodes": ["238220"],
  "setAsideTypes": ["SBA", "SDVOSBC"],
  "agencies": ["VETERANS AFFAIRS"],
  "placeOfPerformanceStates": ["TX", "OK"],
  "noticeTypes": ["Solicitation", "Combined Synopsis/Solicitation"],
  "postedWithinDays": 14,
  "excludeExpired": true,
  "maxResults": 500,
  "includeGrants": false
}
```

| Input | What it does |
|---|---|
| `keywords` | Matches any keyword in the title, solicitation number or full description (case-insensitive). |
| `naicsCodes` | Exact codes or prefixes (`5415` matches every 5415xx code). |
| `setAsideTypes` | SBA, 8A, HZC, SDVOSBC, WOSB, EDWOSB, VSA, … or `NONE` for unrestricted notices. |
| `agencies` | Text match on the department, sub-tier or office (e.g. `ARMY`, `FOREST SERVICE`). |
| `placeOfPerformanceStates` | Two-letter state codes. |
| `noticeTypes` | Solicitation, Combined Synopsis/Solicitation, Presolicitation, Sources Sought, Special Notice, Award Notice, … |
| `postedWithinDays` / `postedFrom` / `postedTo` | Date window (`0` = no limit). |
| `excludeExpired` | Drops notices whose response deadline has passed (default `true`). |
| `dedupeBySolicitation` | Keeps only the newest notice per solicitation number (amendments are separate notices on SAM.gov). |
| `maxResults` | Total cap across sources. |
| `includeSam` / `includeGrants` | Choose the sources. Grants.gov is off by default. |
| `grantStatuses` | `posted`, `forecasted`, `closed`, `archived`. |
| `descriptionSnippetLength` | Snippet length in characters (`0` turns snippets off). |

### Output example

```json
{
  "id": "6196197ae63848ce93a86870cb18e0cd",
  "source": "sam.gov",
  "title": "Helena - Lewis and Clark National Forest Dry Pole Pit Rock Crushing Service",
  "solicitationNumber": "1240BE27Q0001",
  "agency": "AGRICULTURE, DEPARTMENT OF",
  "subAgency": "FOREST SERVICE",
  "office": "WALLOWA WHITMAN NATIONAL FOREST",
  "noticeType": "Combined Synopsis/Solicitation",
  "naicsCode": "237310",
  "classificationCode": "Z1LB",
  "setAsideCode": "SBA",
  "setAside": "Small Business Set Aside - Total",
  "postedDate": "2026-10-17",
  "responseDeadline": "2026-10-22T13:00:00-06:00",
  "archiveDate": "2026-11-06",
  "popCity": "Stanford",
  "popState": "MT",
  "popZip": null,
  "popCountry": "USA",
  "link": "https://sam.gov/workspace/contract/opp/6196197ae63848ce93a86870cb18e0cd/view",
  "descriptionSnippet": "Amendment 0001 - This amendment provides missing solicitation attachments, issues Government responses to offeror questions…",
  "fundingInstrument": null,
  "assistanceListings": null,
  "awardCeiling": null,
  "awardFloor": null
}
```

### Pricing

**$2.00 per 1,000 results** ($0.002 per opportunity), plus Apify's standard small Actor-start fee. There's no subscription. You're charged only for opportunities saved to your dataset, and you can cap any run's cost with the run's maximum-charge setting. Examples: a daily alert returning 40 new notices costs about $0.08 per day. A full export of every active notice (~70,000) costs about $140.

### FAQ

**Do I need a SAM.gov account or API key?**
No. The Actor uses the public daily data extract that SAM.gov publishes for everyone. It doesn't use the rate-limited SAM.gov API.

**How fresh is the data?**
SAM.gov regenerates the extract once a day, overnight US time. Each run reads the latest file, so notices posted today usually appear the next morning. Every run's `RUN_SUMMARY` record shows the file's timestamp.

**Does it include contracting officer names, e-mails or phone numbers?**
No. Personal contact fields are dropped, and e-mail addresses and phone numbers are removed from description snippets. Use the `link` field to open the official notice when you're ready to respond.

**Does it include award notices?**
Yes. Award Notices are in the extract. Select the "Award Notice" notice type to track awards; awardee details are not included.

**Do the NAICS, set-aside and state filters apply to grants?**
No. Grants.gov doesn't publish those fields, so for grants only keywords, agency, date window and status apply.

**Why do I see the same solicitation twice?**
SAM.gov publishes amendments and follow-up notices (for example, Presolicitation, then Solicitation) as separate records. Turn on `dedupeBySolicitation` to keep only the newest one.

**How do I get only new opportunities every day?**
Schedule the Actor daily with `postedWithinDays: 1` or `2`, then de-duplicate on `id` in your destination.

**Is this legal to use?**
The data comes from official US government open-data sources (SAM.gov public extract and the public Grants.gov API) and is public information. You're responsible for how you use it.

**Something broke or a field is missing?**
Open an issue on the Actor's Issues tab and we'll take a look.

# Actor input Schema

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

Match any keyword (case-insensitive) in the title, solicitation number or full description. Example: janitorial, cybersecurity, HVAC. Also sent to Grants.gov search when Grants.gov is enabled.

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

6-digit NAICS codes or prefixes (e.g. 541512, or 5415 for all computer-systems design). SAM.gov only.

## `setAsideTypes` (type: `array`):

Keep only these set-asides. Choose 'No set-aside / not specified' to include unrestricted notices. SAM.gov only.

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

Match department, sub-tier or office name containing any of these (case-insensitive), e.g. 'VETERANS AFFAIRS', 'ARMY', 'FOREST SERVICE'. For Grants.gov, matches agency name or code (e.g. 'DOE', 'NSF').

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

Two-letter state codes for the place of performance. Notices without a listed place of performance are excluded when this is set. SAM.gov only.

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

SAM.gov notice types to include. Leave empty for all.

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

Only notices posted in the last N days (including today, UTC). 0 = no limit. Ignored if 'Posted from' is set. Smaller windows run much faster because the source file is newest-first.

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

Optional absolute start date. Overrides 'Posted within last N days'.

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

Optional absolute end date (inclusive).

## `excludeExpired` (type: `boolean`):

Drop notices whose response deadline (or grant close date) is before today. Notices without a deadline are kept.

## `dedupeBySolicitation` (type: `boolean`):

SAM.gov posts amendments and follow-up notices as separate records with the same solicitation number. Turn on to keep only the newest notice for each solicitation number.

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

Stop after this many results in total (all sources). You pay per result.

## `includeSam` (type: `boolean`):

Streams the official SAM.gov daily public extract.

## `includeGrants` (type: `boolean`):

Adds federal grants (posted and forecasted) from the public Grants.gov API, merged newest-first. NAICS, set-aside, state and notice-type filters apply to SAM.gov only.

## `grantStatuses` (type: `array`):

Which Grants.gov opportunity statuses to include.

## `descriptionSnippetLength` (type: `integer`):

Characters of plain-text description to include (e-mails and phone numbers are removed). 0 = no snippet (faster for Grants.gov).

## Actor input object example

```json
{
  "keywords": [
    "cybersecurity"
  ],
  "naicsCodes": [],
  "postedWithinDays": 7,
  "excludeExpired": true,
  "dedupeBySolicitation": false,
  "maxResults": 1000,
  "includeSam": true,
  "includeGrants": false,
  "grantStatuses": [
    "posted",
    "forecasted"
  ],
  "descriptionSnippetLength": 300
}
```

# Actor output Schema

## `opportunities` (type: `string`):

One item per opportunity (overview view). Use the 'detailed' view or the full dataset for all fields.

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

Rows scanned, result counts per source, source file timestamp, duration and peak memory.

# 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": [
        "cybersecurity"
    ],
    "naicsCodes": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("loomwise/federal-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": ["cybersecurity"],
    "naicsCodes": [],
}

# Run the Actor and wait for it to finish
run = client.actor("loomwise/federal-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": [
    "cybersecurity"
  ],
  "naicsCodes": []
}' |
apify call loomwise/federal-opportunities --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,loomwise/federal-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/ZE5RyemnGuJrait9y/builds/auxhon3vfQKppF2ee/openapi.json
