# SAM.gov Scraper - Federal Contract Opportunities & Contacts (`scrapesage/sam-gov-scraper`) Actor

Scrape SAM.gov federal contract opportunities: RFPs, solicitations, sources sought, awards. Filter by keyword, NAICS, PSC, set-aside, notice type, dates. Returns contracting officer names, emails, phones, full descriptions, and attachment download links. No API key needed.

- **URL**: https://apify.com/scrapesage/sam-gov-scraper.md
- **Developed by:** [Scrape Sage](https://apify.com/scrapesage) (community)
- **Categories:** Lead generation, Agents, Integrations
- **Features:** Limited permissions
- **Stats:** 65 total users, 24 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.38 / 1,000 opportunities

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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 & Contacts

> **Disclaimer:** This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by the U.S. General Services Administration (GSA) or any government body. All trademarks mentioned are the property of their respective owners. "SAM.gov" is referenced only to describe the public data source this Actor collects from.

Extract **U.S. federal contract opportunities** from **SAM.gov** - RFPs, solicitations, sources sought, and award notices - into clean JSON with **full descriptions, contracting officer contacts (name, email, phone), NAICS and PSC codes with their titles, and direct attachment download links**. No login and no cookies - no SAM.gov account and no API key required.

### Why this SAM.gov scraper?

- No account, no API key - works out of the box
- One row per opportunity that combines the search result, the full notice record and its attachment list
- Full solicitation description text, set-aside, place of performance and the exact response deadline
- Contracting officer name, email and phone, as one-line columns ready for a CRM import
- NAICS and PSC codes with their official titles ("541511 Custom Computer Programming Services")
- Department, sub-tier agency, office and office address on every row, also when you scrape notices by ID
- Lists every attachment with a direct download URL - and can download the files for you
- Filter across all notice types, NAICS, PSC, set-asides, and date ranges; paste notice IDs or import them from a file

### Use cases

- **Government BD & capture teams** - find RFPs matching your NAICS codes before competitors do, with the contracting officer's email in the same row.
- **Proposal teams** - pull full solicitation text and attachment files (SOWs, specs, amendments) straight into your pipeline tools.
- **Market intelligence & consultants** - track award notices by agency and awardee (UEI) to see who's winning contracts in your market.
- **Subcontractors** - monitor award notices to find primes who just won work in your niche.
- **Daily opportunity feeds** - schedule a run with a relative `postedFrom` like `"1 day"` to capture freshly posted opportunities.

### How to use

1. [Sign up for Apify](https://console.apify.com/sign-up) - the free plan is enough to try this actor.
2. Open the **SAM.gov Scraper**, fill in the inputs you need, and click **Start**.
3. Watch results arrive in the dataset table; the run's status line says how many opportunities were delivered and why the run ended.
4. **Export** as JSON, CSV, Excel, XML, or RSS - or pull results programmatically via the [Apify API](https://docs.apify.com/api/v2).

### Input

The simplest input - the 100 most recently updated active software opportunities, with contacts and attachments:

```json
{
    "keywords": "software",
    "keywordMode": "ALL",
    "status": "active",
    "maxResults": 100,
    "fetchFullDetails": true,
    "includeAttachments": true
}
```

A daily-feed input for new small-business IT set-asides:

```json
{
    "naicsCodes": ["541511", "541512"],
    "setAsideCodes": ["SBA", "8A"],
    "noticeTypes": ["o", "k", "p"],
    "postedFrom": "1 day",
    "sortBy": "-modifiedDate",
    "maxResults": 500
}
```

Or scrape specific opportunities directly by URL or notice ID (search filters are ignored when this is set):

```json
{
    "noticeIds": ["https://sam.gov/opp/ecf37a7275fd4b0cb17b9e0cfd660654/view"]
}
```

Core fields:

- **`keywords`** - search text (e.g. `"janitorial services"`); leave empty to match all and rely on filters. **`keywordMode`** controls how words combine: `ALL`, `ANY`, or `EXACT`.
- **`noticeTypes`** - limit to notice types such as `o` (Solicitation), `p` (Presolicitation), `k` (Combined Synopsis/Solicitation), `r` (Sources Sought), `s` (Special Notice), `a` (Award Notice), `u` (J\&A), `g` (Surplus Sale), `i` (Intent to Bundle).
- **`naicsCodes`** / **`pscCodes`** - filter by NAICS industry codes (e.g. `541511`) and Product Service Codes (e.g. `DA01`, `R425`). A shorter prefix matches every code under it: `5415` covers 541511, 541512 and the rest of 5415; `7A` covers every 7A IT software code. The old `D3xx` IT codes were retired in October 2020, so active notices no longer carry them.
- **`setAsideCodes`** - limit to small-business set-aside categories such as `SBA`, `8A`, `HZC`, `SDVOSBC`, `WOSB`, `EDWOSB`, `VSA`, `BICiv`, and more.
- **`status`** - `active` (default), `inactive` (archived), or `all`.
- **`postedFrom`** / **`postedTo`**, **`modifiedFrom`** / **`modifiedTo`**, **`responseDueFrom`** / **`responseDueTo`** - date windows accepting ISO dates (`2026-06-01`) or relative values (`"7 days"`, `"2 weeks"`, `"3 months"`). SAM.gov applies them by whole day.
- **`maxResults`** - opportunities per run (up to 10,000). Left empty, a search delivers up to 100. A call with no search and no filter at all (for example `{}` from an API or AI-agent caller) returns a 25-row sample of the newest active opportunities, and its status line says so. **`sortBy`** - `-modifiedDate` (default) or `-relevance`.
- **`fetchFullDetails`** - read each notice's full record for the description, contracting officer contacts, NAICS / PSC with titles, set-aside, place of performance and exact deadline (default `true`); disable for a faster basic feed.
- **`includeAttachments`** - list attachments with download URLs (default `true`); **`downloadAttachments`** also saves the files to the key-value store (default `false`), with **`maxAttachmentSizeMb`** capping file size (default 25 MB).
- **`noticeIds`** - scrape specific notice IDs / `sam.gov` opportunity URLs directly. Repeated IDs are read once; an ID SAM.gov does not know is named in the run's status line and is never billed.
- **`urlsFromFile`** - paste many notice IDs or links at once (one per line, or a CSV with them in any column), or paste one link to a `.txt` / `.csv` file, a Google Sheet or a Drive file shared as "Anyone with the link".
- **`proxyConfiguration`** - proxy settings. With the default, the actor reads SAM.gov directly first (several times faster) and switches to the Apify proxy whenever SAM.gov refuses a direct request; pick a proxy group, a country or your own proxies to use them for every request.

### Output

One dataset record per opportunity:

```json
{
    "noticeId": "ecf37a7275fd4b0cb17b9e0cfd660654",
    "parentNoticeId": null,
    "title": "6515--NEW Seattle Patient Lift Replacement",
    "noticeType": "Combined Synopsis/Solicitation",
    "noticeTypeCode": "k",
    "solicitationNumber": "36C26026Q0576",
    "status": "Active",
    "isActive": true,
    "postedDate": "2026-06-09T23:08:15.561+00:00",
    "responseDeadline": "2026-07-16T10:00:00-07:00",
    "responseTimeZone": "America/Los_Angeles",
    "archiveDate": "2026-07-21",
    "department": "VETERANS AFFAIRS, DEPARTMENT OF",
    "subTier": "VETERANS AFFAIRS, DEPARTMENT OF",
    "office": "NETWORK CONTRACT OFFICE 20 (36C260)",
    "naicsCodes": ["339113"],
    "pscCode": "6515",
    "setAside": "Total Small Business Set-Aside",
    "setAsideCode": "SBA",
    "placeOfPerformance": {
        "streetAddress": "Department of Veterans Affairs Seattle VA Medical Center, 1660 S Columbian Way",
        "city": "Seattle",
        "state": "WA",
        "zip": "98499",
        "country": "UNITED STATES"
    },
    "descriptionText": "The Seattle VA Medical Center requires replacement of facility-wide patient lifts...",
    "pointsOfContact": [
        {
            "type": "primary",
            "fullName": "Denise Patches",
            "title": "Contracting Officer",
            "email": "Denise.Patches@va.gov",
            "phone": "253-888-4922"
        }
    ],
    "attachments": [
        {
            "name": "SOW - Facility Wide Patient Lift Replacement_V1.docx",
            "type": "file",
            "url": "https://sam.gov/api/prod/opps/v3/opportunities/resources/files/b74dff59617b459fbfc6462042b34523/download",
            "mimeType": ".docx",
            "sizeBytes": 44515,
            "accessLevel": "public",
            "resourceId": "b74dff59617b459fbfc6462042b34523",
            "exportControlled": false
        }
    ],
    "url": "https://sam.gov/opp/ecf37a7275fd4b0cb17b9e0cfd660654/view",
    "primaryNaicsCode": "339113",
    "primaryNaicsTitle": "Surgical Appliance and Supplies Manufacturing",
    "naicsCodesText": "339113",
    "pscTitle": "MEDICAL AND SURGICAL INSTRUMENTS, EQUIPMENT, AND SUPPLIES",
    "primaryContactName": "Denise Patches",
    "primaryContactTitle": "Contracting Officer",
    "primaryContactEmail": "Denise.Patches@va.gov",
    "primaryContactPhone": "253-888-4922",
    "pointsOfContactText": "Denise Patches (Contracting Officer), Denise.Patches@va.gov, 253-888-4922",
    "placeOfPerformanceText": "Department of Veterans Affairs Seattle VA Medical Center, 1660 S Columbian Way, Seattle, WA 98499, UNITED STATES",
    "attachmentsCount": 1,
    "detailFetched": true
}
```

The dataset has four table views: **Opportunities** (the overview, with contact and description columns), **Contacts** (one line per contracting officer), **Awards** (awardee, UEI, amount and award date; use it with Notice types = Award Notice) and **Attachments** (file names and download links).

#### What each field holds, and when it is empty

Every field below comes from SAM.gov itself; an empty value means SAM.gov has no value for that notice, not that the run missed it.

| Field | Holds | Empty when |
|---|---|---|
| `status`, `isActive`, `isCanceled` | Active / Inactive / Canceled, as in SAM.gov's own search | never |
| `responseDeadline`, `responseTimeZone` | the offer due date and its time zone | award notices and justifications (no response window); a deadline given as a date only has no time zone |
| `setAside`, `setAsideCode` | the set-aside SAM.gov records, `None` when the notice says no set-aside | the notice records no set-aside at all (about half of notices) |
| `naicsCodes`, `primaryNaicsCode`, `primaryNaicsTitle`, `pscCode`, `pscTitle` | industry and product codes with their official titles | the notice names none (some presolicitations and justifications carry a PSC code but no NAICS), or `fetchFullDetails` is off |
| `placeOfPerformance`, `placeOfPerformanceText` | where the work is done | the contracting officer left it blank (about half of notices) |
| `pointsOfContact` and the `primaryContact...` columns | name, email, phone and title of each contact | phone and title only when the notice gives them (titles are rare) |
| `award` | awardee name, UEI, CAGE code, amount, award date and number | notices that are not award notices or justifications |
| `attachments`, `attachmentsCount`, `attachmentsText` | every file and link with a download URL | the notice has no attachments (count 0), or `includeAttachments` is off (null) |
| `parentNoticeId`, `relatedNoticeId` | the original notice of an amendment, and a linked notice | original notices with no amendment or link |
| `descriptionText`, `descriptionHtml` | the full notice text | some award notices carry no description |
| `farCases` | FAR cases SAM.gov lists on the notice | SAM.gov sends this list empty on almost every notice |

Notes:

- Detail fields like `descriptionText`, `pointsOfContact`, `placeOfPerformance`, codes with titles and exact deadlines are filled when `fetchFullDetails` is enabled (`detailFetched: true`); `attachments` is filled when `includeAttachments` is enabled. Download URLs are always included in the dataset, and you only download the files when `downloadAttachments` is `true`.
- SAM.gov serves at most 10,000 results per search. To pull more, split the search with posted date windows (`postedFrom` / `postedTo`).
- This data is published by the U.S. federal government for public dissemination; the actor only accesses publicly available opportunity data.

### How much does it cost to scrape SAM.gov?

This Actor uses Apify's **pay-per-event** pricing: you are charged for the results it delivers, with no monthly rental. The events it can charge are:

- **Opportunity** (called "Opportunity Scraped" until 12 November 2026) - One federal contract opportunity record, including full description, contracting officer contacts, NAICS/PSC codes, deadlines, place of performance, and attachment links.
- **Attachment File Download** - One attachment file (SOW, specifications, amendments) downloaded into your run's key-value store. Only charged when "Download attachment files" is enabled - listing attachment URLs is always free.
- **Actor start** (from 12 November 2026) - Apify's standard run-start fee of $0.001 per GB of run memory, so $0.001 for a run at the default 1 GB. It covers the fixed cost of starting a run, including a search that finds nothing.

The current price of each event is shown on the **Pricing** tab of this page. Set a maximum total charge on the run if you want a hard cap on spend, and use the input limits to control how much the Actor fetches. When the cap is reached, the run stops and its status line says so; nothing beyond the cap is fetched or billed.

### Automate & schedule

Run this actor on autopilot and pull results into your own stack:

- **[Apify API](https://docs.apify.com/api/v2)** - start runs, fetch datasets, and manage schedules over REST.
- **[apify-client for JavaScript](https://docs.apify.com/api/client/js/)** and **[apify-client for Python](https://docs.apify.com/api/client/python/)** - official SDKs.
- **[Schedules](https://docs.apify.com/platform/schedules)** - run it on a cron to keep your data fresh.
- **[Webhooks](https://docs.apify.com/platform/integrations/webhooks)** - trigger downstream actions the moment a run finishes.

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

const client = new ApifyClient({ token: 'MY_APIFY_TOKEN' });

const run = await client.actor('scrapesage/sam-gov-scraper').call({
    naicsCodes: ['541511', '541512'],
    setAsideCodes: ['SBA', '8A'],
    noticeTypes: ['o', 'k', 'p'],
    postedFrom: '1 day',
    maxResults: 500,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(`Got ${items.length} records`);
```

### Integrate with any app

Connect the dataset to 5,000+ apps - no code required:

- **[Make](https://docs.apify.com/platform/integrations/make)** - multi-step automation scenarios.
- **[Zapier](https://docs.apify.com/platform/integrations/zapier)** - push new records straight into your CRM or sheet.
- **[Slack](https://docs.apify.com/platform/integrations/slack)** - get notified when a run finds something new.
- **[Google Drive / Sheets](https://docs.apify.com/platform/integrations/drive)** - auto-export every run to a spreadsheet.
- **[Airbyte](https://docs.apify.com/platform/integrations/airbyte)** - pipe results into your data warehouse.
- **[GitHub](https://docs.apify.com/platform/integrations/github)** - trigger runs from commits or releases.

### Use with AI assistants (MCP)

The output is clean, LLM-ready JSON. Call this actor from Claude, ChatGPT, or any agent framework through the **[Apify MCP server](https://docs.apify.com/platform/integrations/mcp)** - ask your assistant to "find active small-business IT solicitations posted in the last week and list each contracting officer's email" and let it run this scraper for you.

### Agent-ready: autonomous payments (x402 & Skyfire)

This actor is **agent-ready**: AI agents can discover it, run it, and **pay for it autonomously**, with no Apify account and no human in the loop. It uses [pay-per-event](https://docs.apify.com/platform/actors/publishing/monetize/pay-per-event) pricing and [limited permissions](https://docs.apify.com/platform/actors/development/permissions), so it qualifies for Apify's agentic-payment standards:

- **[x402](https://docs.apify.com/platform/integrations/x402)**: an open, HTTP-native payment protocol. Agents pay per run in USDC on the Base network directly through the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp), with no account and no API key.
- **[Skyfire](https://docs.apify.com/platform/integrations/skyfire)**: agent-to-service payments for fully autonomous AI-agent workflows.

Building an AI agent, MCP tool, or autonomous data pipeline? This scraper is ready to plug in and pay as it goes.

### More scrapers from scrapesage

Need data from somewhere else? Try these:

- **[Bark Listing Scraper](https://apify.com/scrapesage/bark-listing-scraper)** - Bark.com service-provider directory listings.
- **[Multi-ATS Job Scraper](https://apify.com/scrapesage/multi-ats-job-scraper)** - jobs from Greenhouse, Lever, Ashby, Workday & more.
- **[LinkedIn Jobs Scraper](https://apify.com/scrapesage/linkedin-jobs-scraper)** - filter-based LinkedIn job postings, no login.
- **[Google Ads Transparency Scraper](https://apify.com/scrapesage/google-ads-transparency-scraper)** - see who's advertising what on Google.
- **[Facebook Ad Library Scraper](https://apify.com/scrapesage/facebook-ad-library-scraper)** - Meta/Instagram competitor ad intelligence.
- **[Eventbrite Scraper](https://apify.com/scrapesage/eventbrite-scraper)** - events plus organizer leads with contacts.

### Tips

- **Build a daily opportunity feed** by setting `postedFrom` to `"1 day"`, sorting by `-modifiedDate`, and running the actor on an Apify [Schedule](https://docs.apify.com/platform/schedules) - then pipe new records to Slack, Make, or Google Sheets. SAM.gov's date filters work in whole days, so each daily run also re-reads the notices of the day before: keep `noticeId` as the key in your sheet or CRM to drop repeats.
- **Get past the 10,000-result limit** by splitting large pulls into `postedFrom` / `postedTo` date windows; SAM.gov serves at most 10,000 results per search.
- **Run faster** by disabling `fetchFullDetails` and `includeAttachments` when you only need basic listing fields - each adds one extra request per opportunity.
- **Use `responseDueFrom`** to exclude nearly-closed solicitations and focus on opportunities you can still respond to.
- **Have a list of notices already?** Paste the IDs or links into `urlsFromFile`, or paste one link to your Google Sheet.

### FAQ

**Do I need a SAM.gov account or API key?** No. This actor reads SAM.gov's public opportunity data without any login, account, or API key.

**Is this legal?** SAM.gov contract opportunity data is published by the U.S. federal government for public dissemination and is in the public domain. This actor only accesses publicly available data - no login, no bypassing of access controls.

**How fresh is the data?** It is read live from SAM.gov at run time.

**Can I download the attachment files, not just the links?** Yes. Download URLs are always included in each record; set `downloadAttachments` to `true` to also save the files into the run's key-value store, capped by `maxAttachmentSizeMb`.

**What if my filters match no opportunities?** The run finishes successfully with an empty dataset, nothing is billed, and the status line says which filters to loosen.

**Why is a field empty on some rows?** See the field table above: SAM.gov leaves those fields blank on those notices.

**Can I export the results?** Yes - export as JSON, CSV, Excel, XML, or RSS, or pull them via the Apify API and official SDKs.

### Data & lawful use

The source is an official public register, published so that anyone can consult it. Records can name individuals (points of contact named on notices and registrations), so the output may contain personal data even though it is public. If you are in the EU or UK you are the data controller for what you do with it: have a lawful basis, honour access and deletion requests, and respect the register's own reuse conditions, which can restrict marketing or commercial use.

Under [Apify's Standard Actor Contract](https://docs.apify.com/legal/standard-actor-contract), which governs your use of this Actor, you are the controller of any personal data in your input and output and scrapesage acts only as your processor: that data is processed solely to run your job, written only to your own Apify storage, never used for any other purpose and never shared onward. If you need help with a data-subject request that involves this Actor's output, open an issue on the Issues tab.

### Disclaimer

**This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by the U.S. General Services Administration (GSA) or any government body. All trademarks mentioned are the property of their respective owners.**

"SAM.gov" is referenced only in a descriptive, nominative sense - to identify the public data source this Actor collects from. This Actor is not an official product or service of the U.S. General Services Administration (GSA) and is not authorised or certified by it. It collects only publicly available records; you are responsible for ensuring your use of that data complies with applicable laws, regulations and the source's own terms of use or reuse conditions.

### Need help?

Open an issue on the actor's **Issues** tab, or visit the [Apify help center](https://help.apify.com/). Feature requests are welcome - this actor is actively maintained.

# Actor input Schema

## `keywords` (type: `string`):

Search keywords, e.g. 'janitorial services' or 'cybersecurity'. Leave empty to match all opportunities (combine with filters below).

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

How multiple keywords are combined: require all words, any word, or the exact phrase.

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

Limit to specific notice types. Leave empty for all types.

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

Filter by NAICS industry codes, e.g. 541511 (custom computer programming), 561720 (janitorial). One code per line. A shorter prefix matches every code under it: 5415 covers 541511, 541512 and the rest of 5415.

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

Filter by Product Service Codes (classification codes), e.g. DA01 (IT application development support), R425 (engineering and technical support), 7510 (office supplies). One code per line; a prefix such as 7A matches every 7A code. The old D3xx IT codes were retired in October 2020, so active notices no longer carry them.

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

Limit to small-business set-aside categories. Leave empty for all.

## `status` (type: `string`):

Active opportunities (open for response), inactive (archived), or everything.

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

Only opportunities first published on/after this date. ISO date (2026-06-01) or relative ('7 days', '2 weeks', '3 months'). TIP: schedule this actor daily with '2 days' for a monitoring feed of new opportunities.

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

Only opportunities first published on/before this date. ISO date or relative value.

## `modifiedFrom` (type: `string`):

Only opportunities updated on/after this date. ISO date or relative value like '1 day'.

## `modifiedTo` (type: `string`):

Only opportunities updated on/before this date. ISO date or relative value.

## `responseDueFrom` (type: `string`):

Only opportunities whose response/offer deadline is on/after this date. ISO date or relative value. Useful to exclude nearly-closed solicitations.

## `responseDueTo` (type: `string`):

Only opportunities whose response/offer deadline is on/before this date. ISO date or relative value.

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

Maximum number of opportunities to deliver in this run. Left empty, a search delivers up to 100, and a call with no search and no filter at all returns a 25-row sample. SAM.gov serves at most 10,000 results per search: split bigger pulls with posted date windows.

## `sortBy` (type: `string`):

Order of results. 'Recently modified' is best for monitoring; 'Relevance' is best with keywords.

## `fetchFullDetails` (type: `boolean`):

Fetch each opportunity's detail page: full description, contracting officer contacts (name, email, phone), NAICS/PSC codes, set-aside, place of performance, and exact response deadline. Adds one extra request per opportunity. Disable for a faster, cheaper feed of basic fields only.

## `includeAttachments` (type: `boolean`):

Fetch the list of attachments (SOWs, specs, amendments) for each opportunity, with direct download URLs. Adds one extra request per opportunity.

## `downloadAttachments` (type: `boolean`):

Download attachment files into the run's key-value store (download URLs are always included in the dataset regardless). Only public files up to the size limit below.

## `maxAttachmentSizeMb` (type: `integer`):

Skip downloading files larger than this. Only used when 'Download attachment files' is enabled.

## `noticeIds` (type: `array`):

Scrape specific opportunities directly: paste SAM.gov opportunity URLs (https://sam.gov/opp/<id>/view) or 32-character notice IDs, one per line. When set, the search filters above are ignored. Repeated IDs are read once, and an ID SAM.gov does not know is named on the run card and never billed.

## `urlsFromFile` (type: `string`):

Paste many notice IDs or sam.gov/opp/<id>/view links at once (one per line, or a CSV with them in any column), or paste ONE link to a .txt / .csv file, a Google Sheet or a Drive file shared as 'Anyone with the link'. Works like the field above and can be combined with it.

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

Proxy settings. With the default (Apify proxy, nothing else chosen) the actor reads SAM.gov directly first, which is several times faster, and switches to the Apify proxy whenever SAM.gov refuses a direct request. Choose a proxy group, a country or your own proxies to use them for every request.

## Actor input object example

```json
{
  "keywords": "software",
  "keywordMode": "ALL",
  "naicsCodes": [
    "541511",
    "541512"
  ],
  "pscCodes": [
    "DA01"
  ],
  "status": "active",
  "maxResults": 100,
  "sortBy": "-modifiedDate",
  "fetchFullDetails": true,
  "includeAttachments": true,
  "downloadAttachments": false,
  "maxAttachmentSizeMb": 25,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

One record per federal contract opportunity, including title, notice type, agency hierarchy, NAICS/PSC, set-aside, deadlines, description, contracting officer contacts, and attachment links.

## `attachmentFiles` (type: `string`):

Attachment files (SOWs, specifications, amendments) downloaded into the default key-value store when 'Download attachment files' is enabled.

# 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",
    "maxResults": 100,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapesage/sam-gov-scraper").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",
    "maxResults": 100,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("scrapesage/sam-gov-scraper").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",
  "maxResults": 100,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call scrapesage/sam-gov-scraper --silent --output-dataset

```

## MCP server setup

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

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/N5fPoWczVHllr71tN/builds/QUuLuPU51JxxpPBlW/openapi.json
