# SAM.gov Scraper & API — Contract Opportunities & Awards (`s-r/sam-gov-opportunities`) Actor

Export federal contract opportunities and award notices from SAM.gov: solicitations, presolicitations, sources sought and awards with deadlines, NAICS, set-asides, contacts, attachment links, award amounts and supplier UEI/CAGE. For government suppliers, bid consultants and GovCon sales teams.

- **URL**: https://apify.com/s-r/sam-gov-opportunities.md
- **Developed by:** [SR](https://apify.com/s-r) (community)
- **Categories:** Business, Lead generation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$2.50 / 1,000 opportunity records

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 API & Scraper: Contract Opportunities and Awards

This SAM.gov API alternative exports federal contract opportunities and award notices into a structured dataset, without a SAM.gov API key. Find solicitations by NAICS, PSC, set-aside or agency, track response deadlines, and connect awarded suppliers to other datasets through their UEI and CAGE identifiers.

Use the actor to monitor solicitations, presolicitations, combined synopsis/solicitations, sources sought, special notices, justifications, consolidated or bundled requirements, and sales of surplus property. Each notice becomes one row, including awards. A solicitation and its later award can be separate notices with their own IDs and parent or related notice references.

### What does this SAM.gov API return?

- **Opportunity data**: notice ID, public SAM.gov URL, title, notice type, solicitation number, publication date, response deadline (with source timezone and in UTC), archive date and active or cancelled status.
- **Agency hierarchy**: department, sub-tier agency, purchasing office and the full organization path with codes and SAM.gov organization IDs.
- **Classification**: NAICS codes, PSC code, set-aside code and set-aside name.
- **People and places**: primary and secondary contacts with name, email and phone, and the place of performance.
- **Documents**: the full plain-text and HTML description, and attachment metadata with stable download URLs.
- **Awards**: award amount in USD, award date, award number, awardee name, awardee UEI, CAGE code and supplier location.

### Use cases for SAM.gov contract opportunities

**Government suppliers** build a shortlist of open contract opportunities by industry classification and set-aside eligibility, for example every small-business set-aside under NAICS 541512 with a response deadline in the next two weeks.

**Bid and proposal consultants** monitor notices for a department or purchasing office, read the full description and attachments, and pass the contact details to their clients.

**GovCon sales and business development teams** inspect award notices to see which suppliers win which contracts and for how much, then use the awardee UEI to enrich the supplier with spending history and company records.

**Market researchers and analysts** schedule a daily run, append new notices to a warehouse, and measure demand per agency, NAICS code or set-aside program over time.

Keep `notice_id` as your notice identity and use `awardee_uei` when joining suppliers to USAspending or business records. Supplier names alone can vary between sources.

The buyer country is `US`, because the purchasing organization is a US federal entity. The place of performance is a separate object and can describe a location outside the United States. For example, the genuine award shown below concerns a truck at Aviano in Italy.

### Input

The default search returns up to 50 active notices ordered by latest modification, with full details and attachment metadata. All filters are optional. For a broader dataset, increase `max_items` within the 10,000-notice source window.

`keywords` accepts search terms or a solicitation number. Set `keyword_mode` to `all`, `any`, or `exact`; the default is `all`. Use `notice_types` to restrict the type of announcement, `naics_codes` to filter industries, and `psc_codes` for product or service classifications. Codes are strings. NAICS and PSC prefixes are supported. `set_aside_codes` accepts SAM.gov codes such as `SBA`, `SDVOSBC`, `WOSB`, `8A`, and `NONE`.

`agency` accepts a numeric SAM.gov organization ID or an agency name. A name resolves to the highest-scoring organization returned by SAM.gov; the selected name and ID appear in the output. You can supply a department, a sub-tier agency, or an office ID. Use `status` with `active`, `archived`, or `all` to select the notice lifecycle.

Publication, modification, and response deadlines each have independent date ranges: `posted_from` and `posted_to`, `modified_from` and `modified_to`, and `response_from` and `response_to`. Supply calendar dates as `YYYY-MM-DD`. Date ranges include their end day and use US Eastern time, including daylight saving time. Returned deadlines preserve the source offset and timezone.

If a search result provides a response date without a time, `deadline` is null and `deadline_utc` retains the source value. Midnight UTC in that value does not establish a local closing time. A detail record with a response time supplies the exact deadline when available.

For direct retrieval, provide `notice_ids` as a list of IDs or public SAM.gov opportunity URLs. This mode takes priority over search filters. The `max_items` limit also applies here and defaults to 50; increase it to collect a longer list. If the unique ID count exceeds that limit, the output includes a warning and delivery stops at the limit. Unknown IDs are skipped with a warning; an input containing only unknown IDs returns no dataset rows. Direct retrieval requires detail requests, even if `include_details` is false. Duplicate notice IDs are delivered once. Temporary lookup failures are retried before the remaining IDs are collected.

This real award can be retrieved with:

```json
{"notice_ids":["1ff88d655e55422dbbcd75dd64e21db2"],"include_attachments":false}
```

`include_details: false` collects search records with title, notice type, reference number, agency hierarchy, and available search timestamps. The full `description` remains null; an available search excerpt is stored separately in `description_snippet`. Attachment metadata requires details. Set `include_attachments: false` when you do not need file or link references.

### Output

Each dataset row includes `source`, `fetched_at`, `notice_id`, `url`, `position`, `title`, `notice_type`, `reference_number`, `buyer`, `country`, `published_at`, and `deadline`. Details add the full plain-text and HTML descriptions, NAICS codes, PSC code, set-aside code and name, contacts, archive information, and place of performance when SAM.gov provides them.

Award records can include `award_amount`, `currency`, `award_date`, `award_number`, `awardee_name`, `awardee_uei`, `awardee_cage`, and supplier location. Amounts are numbers. Missing source fields are null or empty lists; the actor does not infer an award value or supplier identifier.

The following selected fields come from the genuine SAM.gov award shown above:

```json
{
  "notice_id":"1ff88d655e55422dbbcd75dd64e21db2",
  "title":"31 LRS European 4x2 Tractor Truck",
  "notice_type":"Award Notice",
  "reference_number":"FA568226P0105",
  "sub_tier":"DEPT OF THE AIR FORCE",
  "naics_codes":["336212"],
  "psc_code":"2320",
  "award_amount":146991.35,
  "currency":"USD",
  "award_date":"2026-09-29",
  "awardee_name":"UNITED CAPITAL INVESTMENTS GROUP, INC.",
  "awardee_uei":"QDHNQJ9FHJW1",
  "awardee_cage":"62VC7"
}
```

And these selected fields come from a genuine open solicitation (`9a3bdbabfbe9425fb7ff750f4368004a`), with one of its five attachments:

```json
{
  "notice_id":"9a3bdbabfbe9425fb7ff750f4368004a",
  "title":"Ie Shima Barge Transportation",
  "notice_type":"Solicitation",
  "reference_number":"M2900027Q3000",
  "sub_tier":"DEPT OF THE NAVY",
  "deadline":"2026-10-07T10:00:00+09:00",
  "naics_codes":["483113"],
  "psc_code":"V115",
  "set_aside_code":"NONE",
  "set_aside":"No set-aside",
  "attachments":[{
    "type":"file",
    "name":"A01_PWS_KS27 ISTF Barge_Updated.pdf",
    "url":"https://sam.gov/api/prod/opps/v3/opportunities/resources/files/ae7bb576c91d4083a365933b04db93b4/download",
    "mime_type":".pdf",
    "size_bytes":231136,
    "access_level":"public",
    "export_controlled":false
  }]
}
```

Attachments include their type, name, URL, source file type, size in bytes, posting time, access level, and export-control indicator. File URLs point to a stable SAM.gov download route; external links keep their published destination. Files are not downloaded, and deleted attachments are excluded. Access restrictions still apply when you follow a link.

The run output reports counts, warnings, and whether collection was partial. A requested detail or attachment phase that fails is reported explicitly, while any available notice rows remain usable. Check `details_fetched` before treating absent classification or award fields as confirmation that the source has no such data. Search totals can exceed the source window; narrow your filters to collect other portions of a large result set.

### SAM.gov API vs this actor

| | Official SAM.gov Opportunities API | SAM.gov website search | This actor |
|---|---|---|---|
| API key | Required, tied to a SAM.gov account | Not needed | Not needed |
| Request limits | Daily limits per key | Manual paging | Bounded batches, cursor continuation handled for you |
| Award UEI and CAGE | Per award record | Visible per notice, by hand | In the award row |
| Attachments | Download links | Per notice, by hand | Name, size, type, access level and download URL in the row |
| Output | Nested JSON | Screen or CSV export | Flat dataset: JSON, CSV, Excel or API |

Compared with other SAM.gov scrapers in the Apify Store, this actor combines search filters, direct notice IDs, the full agency hierarchy, attachment metadata and award identifiers in one row, charges only for delivered notices, and continues large selections automatically.

### Pricing

The actor uses one `opportunity` event per delivered notice. Full details and attachment metadata belong to that notice; they do not create extra dataset rows or separate attachment charges. Duplicate records are charged once. Empty results and unknown IDs produce no row charge. The Store pricing panel shows the current price per opportunity, so 1,000 delivered notices cost 1,000 times that amount.

Users without a paid Apify plan receive at most ten notices per run. The actor stops collecting once that limit is reached. Paid users can request the full configured volume, subject to the source window and available notices. Your Apify usage budget can also stop a run; consult the run output for the rows actually delivered.

### FAQ

#### Do I need a SAM.gov API key?

No SAM.gov API key is required for this actor. Supply the search filters or notice IDs as actor input.

#### Can I collect archived awards?

Yes. Set `status` to `archived` or `all` and include notice type `a` or `Award Notice`. Award fields depend on the information published by the contracting office.

#### What is the difference between a notice ID and a solicitation number?

A notice ID identifies one SAM.gov publication. A solicitation number is the procurement reference and may appear on several related notices. Use `notice_ids` for specific publications and `keywords` to search a solicitation number.

#### How do I find small-business set-aside opportunities?

Set `set_aside_codes` to the programs you qualify for, such as `SBA`, `8A`, `WOSB` or `SDVOSBC`, and combine them with `naics_codes` and a `response_from` date so that only open opportunities with a future deadline remain.

#### Are full descriptions and attachments always available?

Their availability depends on the notice and its access rules. Full descriptions require details; files are returned as links and metadata. Failures appear in warnings. A null place of performance means SAM.gov supplied no usable location, rather than an inferred office address.

#### How are large runs collected?

The actor collects notices in bounded batches and follows continuation cursors automatically. Returned positions continue through the run, and repeated notice IDs are removed. Live search results can change while collection is underway, so narrow date and agency filters when you need a reproducible selection.

#### Can I schedule daily alerts for new contract opportunities?

Yes. Create an Apify schedule with your filters; results are ordered by latest modification, so each run starts with the newest notices. Deduplicate on `notice_id` against earlier runs, and connect the dataset to email, Slack, Google Sheets or a webhook through Apify integrations.

# Actor input Schema

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

Search terms or a solicitation number.

## `keyword_mode` (type: `string`):

Match all terms, any term or an exact phrase.

## `notice_ids` (type: `array`):

Notice IDs or SAM.gov opportunity URLs. A string may separate IDs with newlines or commas. Overrides search filters.

## `notice_types` (type: `array`):

Notice codes s, r, p, i, o, k, a, u, g, or their full SAM.gov names.

## `naics_codes` (type: `array`):

NAICS codes or prefixes, supplied as strings.

## `psc_codes` (type: `array`):

Product/service classification codes or prefixes.

## `set_aside_codes` (type: `array`):

SAM.gov set-aside codes, including SBA, SDVOSBC and NONE.

## `agency` (type: `string`):

Numeric SAM.gov organization ID or agency name. Names resolve to the highest-scoring organization.

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

Active notices, archived notices, or both.

## `sort` (type: `string`):

Modification time descending/ascending, or relevance when keywords are supplied.

## `max_items` (type: `integer`):

Maximum unique notices across all cursor pages. Each API response covers a bounded portion.

## `include_details` (type: `boolean`):

Fetch full descriptions, classifications, contacts and award data. Direct notice IDs always require details.

## `include_attachments` (type: `boolean`):

Include file metadata and stable download URLs plus external links. Requires details. Files are not downloaded.

## `cursor` (type: `string`):

Opaque continuation token. Keep all original input options unchanged.

## `posted_from` (type: `string`):

Publication date from, YYYY-MM-DD; inclusive, interpreted in US Eastern time.

## `posted_to` (type: `string`):

Publication date to, YYYY-MM-DD; inclusive, interpreted in US Eastern time.

## `modified_from` (type: `string`):

Modification date from, YYYY-MM-DD; inclusive, interpreted in US Eastern time.

## `modified_to` (type: `string`):

Modification date to, YYYY-MM-DD; inclusive, interpreted in US Eastern time.

## `response_from` (type: `string`):

Response deadline date from, YYYY-MM-DD; inclusive, interpreted in US Eastern time.

## `response_to` (type: `string`):

Response deadline date to, YYYY-MM-DD; inclusive, interpreted in US Eastern time.

## Actor input object example

```json
{
  "keyword_mode": "all",
  "notice_ids": [
    "1ff88d655e55422dbbcd75dd64e21db2"
  ],
  "status": "active",
  "sort": "modified_desc",
  "max_items": 50,
  "include_details": true,
  "include_attachments": true
}
```

# Actor output Schema

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

One row per SAM.gov notice.

## `output` (type: `string`):

Counts, warnings and delivery status.

# 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 = {
    "notice_ids": [
        "1ff88d655e55422dbbcd75dd64e21db2"
    ],
    "include_attachments": true
};

// Run the Actor and wait for it to finish
const run = await client.actor("s-r/sam-gov-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 = {
    "notice_ids": ["1ff88d655e55422dbbcd75dd64e21db2"],
    "include_attachments": True,
}

# Run the Actor and wait for it to finish
run = client.actor("s-r/sam-gov-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 '{
  "notice_ids": [
    "1ff88d655e55422dbbcd75dd64e21db2"
  ],
  "include_attachments": true
}' |
apify call s-r/sam-gov-opportunities --silent --output-dataset

```

## MCP server setup

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