# Gov Contract Opportunities: SAM.gov + EU TED + USAspending (`chaptersoft/gov-contract-opportunities`) Actor

US federal (SAM.gov), EU (TED) tenders and USAspending awards in one feed. Keyword, NAICS, CPV, set-aside, agency, value and deadline filters; only-new alerts with webhook. No API key.

- **URL**: https://apify.com/chaptersoft/gov-contract-opportunities.md
- **Developed by:** [Jeremy Lam](https://apify.com/chaptersoft) (community)
- **Categories:** Lead generation, Automation, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.35 / 1,000 contract notices

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

## Gov Contract Opportunities: SAM.gov + EU TED + USAspending

Get **new government contract opportunities and awards from the U.S. and Europe in one clean, deduplicated feed**. It covers U.S. federal bids, RFQs, RFIs and sources-sought notices from **SAM.gov**, public tenders from all EU/EEA countries on **TED (Tenders Electronic Daily)**, and newly signed U.S. federal contracts from **USAspending.gov**. Filter by keyword, NAICS, PSC, CPV, set-aside, agency, country/state, value and deadline. Put it on a schedule and it delivers **only what's new since the last run**, with an optional Slack/Discord/Teams/Zapier alert.

- 💸 **$0.50 per 1,000 new notices** ($0.45 Bronze, $0.40 Silver, $0.35 Gold and above). **No start fee, no monthly rental.** You pay only for new notices saved. Notices you already received, duplicates, amendment updates, "nothing new" rows and errors are **free**.
- 🔓 **No API key, no login, no proxy.** SAM.gov's public search, the official TED Search API v3 and the official USAspending API, all politely rate-limited.
- 🔔 **Built for alerts:** since-last-run memory per search (or per `stateKey`), a free **baseline** first run, catch-up after missed schedules, and a webhook digest that is sent only when something new or changed turns up.
- ✏️ **Change tracking:** when a notice you already have is amended (new deadline, cancelled, award posted, TED corrigendum), you get a **free `update` row** that spells out what changed.
- 🎯 **Low noise:** whole-word keyword matching with plurals and `prefix*`, any/all logic, exclude words, title-only scope, and stripping of standard FAR/DFARS clause lists and CMMC boilerplate, so "cybersecurity" doesn't match every DLA hardware buy.
- 📇 **Everything to act on:** contacts (name, email, phone), deadline with days left, set-aside, NAICS/PSC/CPV with descriptions, place of performance, estimated/award value **with USD conversion**, awardee, attachment list with public download links, and optional attachment download.

### Who it's for

- **Small businesses and GovCon BD teams:** a daily list of SAM.gov bids in your NAICS and set-asides, straight into Slack or your CRM.
- **Companies selling into Europe:** TED tenders by CPV and country in English where available, in the same format as U.S. notices.
- **Capture managers and competitive intel:** who just won what (USAspending new awards and SAM.gov award notices), with amounts and agencies.
- **Consultants, bid writers and lead-gen agencies:** one saved monitor per client (`stateKey`).
- **AI agents and automations:** stable JSON schema with a one-line `digest` per notice.

### Input examples

**Daily IT bids for a small business (typical schedule):**

```json
{
  "sources": ["sam"],
  "naicsCodes": ["541512", "541519"],
  "setAsides": ["SBA", "SDVOSBC"],
  "noticeTypes": ["solicitation", "sources-sought", "presolicitation"],
  "postedWithinDays": 2,
  "notifyWebhookUrl": "https://hooks.slack.com/services/…"
}
```

**Cybersecurity work in the U.S. and the EU, title-only matching:**

```json
{ "sources": ["sam", "ted"], "keywords": ["cybersecurity", "penetration testing", "SOC"], "keywordScope": "title" }
```

**EU software tenders in Germany, France and the Netherlands worth at least $250k:**

```json
{ "sources": ["ted"], "cpvCodes": ["72000000", "48000000"], "countries": ["DE", "FR", "NL"], "minValueUsd": 250000, "includeWithoutValue": false }
```

**Who won cloud contracts this month (competitive intel):**

```json
{ "sources": ["usaspending"], "keywords": ["cloud"], "awardsLookbackDays": 30, "minValueUsd": 100000 }
```

**Start a new monitor without paying for the backlog:**

```json
{ "sources": ["sam", "ted"], "keywords": ["drone", "UAS"], "firstRunMode": "baseline", "stateKey": "client-acme-drones" }
```

**Look up specific notices:**

```json
{ "noticeIds": ["N0010426QAB90", "747022-2026"] }
```

### Main inputs

| Field | What it does | Default |
|---|---|---|
| `sources` | `sam` (U.S. opportunities), `ted` (EU tenders), `usaspending` (U.S. awards). | sam, ted |
| `keywords` / `keywordMode` / `keywordScope` / `excludeKeywords` | Words or phrases (`cyber*` = prefix), any or all, title-only or title+description, words to exclude. | – / any / title+description |
| `noticeTypes` | presolicitation, solicitation, sources-sought, special-notice, award, justification, modification, … | all |
| `naicsCodes` / `pscCodes` / `setAsides` / `states` | U.S. filters (prefixes allowed: `5415`). | – |
| `cpvCodes` / `countries` / `language` | EU filters (CPV prefixes, ISO countries) and preferred text language. | – / – / eng |
| `agencies` | Buyer/agency name contains these words (`Veterans Affairs`, `Air Force`). | – |
| `minValueUsd` / `maxValueUsd` / `includeWithoutValue` | Value range in USD (EUR and other currencies converted at the daily ECB rate). Most SAM.gov bids publish no value, so they are kept unless you turn this off. | – / – / on |
| `postedWithinDays` / `postedFrom` / `postedTo` | Posting window. | 7 days |
| `awardsLookbackDays` | Longer window for USAspending awards, because agencies report them days to weeks late. | 30 |
| `openOnly` / `deadlineFrom` / `deadlineTo` | Skip expired or cancelled opportunities; deadline range. | on |
| `sinceLastRun` / `stateKey` / `firstRunMode` / `includeUpdates` | Alert memory (pruned after 180 days), monitor name, baseline first run, free update rows. | on / auto / emitAll / on |
| `notifyWebhookUrl` | HTTPS webhook for a digest of new notices (Slack/Discord format plus JSON). | – |
| `maxResults` | Max new (charged) notices per run, newest first, shared fairly across sources. | 200 |
| `fetchDetails` / `includeAttachments` / `downloadAttachments` | SAM.gov full detail, attachment list, attachment download ($0.001 per file). | on / on / off |
| `samApiKey` | Optional. Only used if SAM.gov's public search is unavailable. | – |

Set **Maximum cost per run** in the run options to cap spending. The Actor stops cleanly at the limit, and the next since-last-run picks up the rest.

### Output

One row per notice (`type: "notice"`). Main fields:

`source` (SAM.gov / TED / USAspending) · `kind` (opportunity / award) · `noticeType` + `noticeTypeLabel` · `title` (+ `titleEnglish`) · `digest` (one-line summary) · `noticeId`, `referenceNumber` (solicitation # / procedure ID / PIID) · `buyer`, `buyerPath`, `buyerEmail`/`buyerPhone`/`buyerWebsite`, `country`, `placeOfPerformance` · `postedDate`, `modifiedDate`, `responseDeadline`, `daysToDeadline`, `status`, `procedureType`, `contractNature`, `contractDuration` · `setAside` · `naics`, `psc`, `cpv` (+ descriptions) · `estimatedValue`, `awardValue`, `currency`, `valueUsd` · `awardee`, `awardeeId` (UEI), `awardDate`, `periodStart`/`periodEnd` · `contacts[]` · `attachments[]` (name, size, public/controlled, URL, stored copy) · `description` · `url`, `documentsUrl`, `submissionUrl` · `matchedKeywords` · `retrievedAt`.

Free rows: `update` (with `changes[]` and `previouslyDeliveredAt`), `no-match` (why nothing matched), `error` (a source failed; nothing charged), and `summary` (baseline). The run's `OUTPUT` record holds totals, per-source stats, notes, FX rates and the state key.

Example `digest`:
`[SAM.gov] solicitation · 53--HOIST STRAP · DEPT OF THE NAVY · due 2026-11-15 (18d left) · Total Small Business Set-Aside (FAR 19.5)`

### Pricing

| Event | FREE | BRONZE | SILVER | GOLD+ |
|---|---|---|---|---|
| New notice saved | $0.0005 | $0.00045 | $0.0004 | $0.00035 |
| Attachment downloaded (opt-in) | $0.001 | $0.001 | $0.001 | $0.001 |

There is no start fee. A daily alert with 20 new notices costs about **$0.01**.

### Notes and limits

- **SAM.gov:** uses the same public search the sam.gov website uses (active notices, newest first, up to 10,000 per search). Controlled/export-restricted attachments are listed but never downloaded.
- **TED:** keyword search uses TED's full-text index, which mostly works in the notice's original languages. For broad EU coverage, combine keywords with **CPV codes**, or use CPV alone.
- **USAspending:** shows awards once agencies report them (DoD up to ~90 days later). Each award is delivered once; later modifications are not re-sent.
- Values in other currencies are converted with the European Central Bank's daily reference rates.
- Data comes from official public sources and is provided as-is. Always confirm details on the official notice before bidding.

# Actor input Schema

## `sources` (type: `array`):

Where to search. SAM.gov = U.S. federal opportunities (bids, RFQs, sources sought, awards). TED = EU/EEA public tenders (all 27 EU countries + more). USAspending = newly signed U.S. federal contract awards (competitive intel).

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

Words or phrases to find (any of them by default). Matched as whole words/phrases against title and description; plural forms match; end with \* for a prefix ("cyber\*"). Standard FAR/DFARS clause text and CMMC boilerplate are ignored so 'cybersecurity' doesn't match every DLA part buy. Leave empty to get everything matching the other filters.

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

Match notices containing any or all of the keywords.

## `keywordScope` (type: `string`):

Title only gives fewer, highly relevant results.

## `excludeKeywords` (type: `array`):

Drop notices whose title or description contains any of these.

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

Leave empty for all types. Tip: \["solicitation","sources-sought","presolicitation"] = only things you can still bid on.

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

SAM.gov/USAspending NAICS codes or prefixes ("5415" = all computer systems design).

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

Product/service codes or prefixes, e.g. "D3" (IT services) or "R425".

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

Small-business set-aside codes or names: SBA (Total Small Business), SBP (Partial), 8A, 8AN (8(a) sole source), HZC (HUBZone), HZS, SDVOSBC (Service-Disabled Veteran-Owned), SDVOSBS, WOSB, WOSBSS, EDWOSB, EDWOSBSS, VSA, VSS, ISBEE, IEE.

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

2-letter state codes, e.g. TX, VA, DC.

## `cpvCodes` (type: `array`):

TED CPV codes or prefixes, e.g. "72000000" (IT services) or "722" (software programming/consultancy). Trailing zeros are treated as a prefix.

## `countries` (type: `array`):

ISO country codes for TED buyers, e.g. DE, FR, IE, NL (or DEU, FRA).

## `language` (type: `string`):

3-letter code (eng, fra, deu, spa…). Falls back to English, then the original language.

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

Only notices from these buyers (all significant words must appear, any order): "Veterans Affairs", "Air Force", "Bundeswehr".

## `minValueUsd` (type: `integer`):

Estimated or awarded value, converted to USD with the daily ECB rate.

## `maxValueUsd` (type: `integer`):

Upper value limit in USD.

## `includeWithoutValue` (type: `boolean`):

Most SAM.gov solicitations publish no value. Turn off to only get notices with a value inside your range.

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

Look back this many days. With since-last-run on, a missed schedule is caught up automatically (up to 90 days).

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

Exact start date (overrides 'Posted within').

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

Exact end date (default today).

## `awardsLookbackDays` (type: `integer`):

Federal award data is reported with a lag (DoD up to 90 days), so awards use a longer window. Since-last-run makes sure you never pay twice.

## `openOnly` (type: `boolean`):

Skip opportunities whose response deadline has passed or that were cancelled (awards are always kept).

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

Only opportunities due on or after this date.

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

Only opportunities due on or before this date.

## `sinceLastRun` (type: `boolean`):

Remembers what you already received (per search) so scheduled runs only deliver — and charge for — new notices. Changed notices (new deadline, amendment, award) come as free 'update' rows.

## `includeUpdates` (type: `boolean`):

When a notice you already received changes (deadline moved, amended, cancelled), add a free row explaining what changed.

## `firstRunMode` (type: `string`):

Baseline marks everything existing as seen for free, so a new schedule starts with only fresh notices.

## `stateKey` (type: `string`):

Optional name for this monitor's memory (letters, digits, -\_.). Default: derived from your filters. Use different names to run independent monitors.

## `notifyWebhookUrl` (type: `string`):

Optional https URL (Slack/Discord incoming webhook, Teams, Zapier, Make or your API). Receives a message only when there are new notices or updates.

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

Newest first. You only pay for rows saved; also respects your max cost per run.

## `fetchDetails` (type: `boolean`):

Full description, NAICS, set-aside, contacts, place of performance, award info. Recommended (and needed for exact keyword matching).

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

Attachment names, sizes and public download links (free).

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

Save public SAM.gov files to the run's key-value store (charged per file). Controlled/export-restricted files are listed but never downloaded.

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

Larger files are listed but not downloaded.

## `descriptionMaxChars` (type: `integer`):

Truncate descriptions to this many characters (0 = omit).

## `includeNoMatchRows` (type: `boolean`):

Add a free row per source when nothing new matched, with the main filter reasons.

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

Instead of searching, fetch these: SAM.gov notice IDs or solicitation numbers, TED publication numbers (e.g. 747022-2026).

## `samApiKey` (type: `string`):

Not needed. Only used as a fallback if SAM.gov's public search is unavailable. Free key from sam.gov → Account Details.

## Actor input object example

```json
{
  "sources": [
    "sam",
    "ted"
  ],
  "keywords": [
    "cybersecurity",
    "penetration testing",
    "cloud migration"
  ],
  "keywordMode": "any",
  "keywordScope": "titleAndDescription",
  "excludeKeywords": [
    "janitorial",
    "brand name"
  ],
  "naicsCodes": [
    "541512",
    "5415"
  ],
  "pscCodes": [
    "D3",
    "R425"
  ],
  "setAsides": [
    "SBA",
    "SDVOSBC",
    "8A"
  ],
  "states": [
    "TX",
    "VA"
  ],
  "cpvCodes": [
    "72000000",
    "48000000"
  ],
  "countries": [
    "DE",
    "FR",
    "NL"
  ],
  "language": "eng",
  "agencies": [
    "Veterans Affairs",
    "Department of the Air Force"
  ],
  "includeWithoutValue": true,
  "postedWithinDays": 7,
  "awardsLookbackDays": 30,
  "openOnly": true,
  "sinceLastRun": true,
  "includeUpdates": true,
  "firstRunMode": "emitAll",
  "maxResults": 200,
  "fetchDetails": true,
  "includeAttachments": true,
  "downloadAttachments": false,
  "maxAttachmentSizeMb": 25,
  "descriptionMaxChars": 5000,
  "includeNoMatchRows": true,
  "noticeIds": [
    "N0010426QAB90",
    "747022-2026"
  ]
}
```

# Actor output Schema

## `notices` (type: `string`):

Overview table of new notices: source, posted, type, title, buyer, deadline, value, codes, link.

## `awards` (type: `string`):

Awarded contracts: awardee, value, date.

## `fullJson` (type: `string`):

Every field incl. description, contacts and attachments.

## `summary` (type: `string`):

Window, per-source counts, filtered-out reasons, charged rows, notes.

# 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 = {
    "sources": [
        "sam",
        "ted"
    ],
    "keywords": [
        "cybersecurity"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("chaptersoft/gov-contract-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 = {
    "sources": [
        "sam",
        "ted",
    ],
    "keywords": ["cybersecurity"],
}

# Run the Actor and wait for it to finish
run = client.actor("chaptersoft/gov-contract-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 '{
  "sources": [
    "sam",
    "ted"
  ],
  "keywords": [
    "cybersecurity"
  ]
}' |
apify call chaptersoft/gov-contract-opportunities --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,chaptersoft/gov-contract-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/LYINoriRa2P3bkhNu/builds/NcN3NIrc3dV6rV768/openapi.json
