# Government Contracts & RFP Monitor (US + UK Tenders) (`ishekofficial/goverment-contract-monitor`) Actor

Track live government contracts and RFPs from the U.S. and U.K. Automatically filter by keywords and budget, and get structured results with buyer details, values, and deadlines. Ideal for sales teams, consultants, and anyone selling to the public sector.

- **URL**: https://apify.com/ishekofficial/goverment-contract-monitor.md
- **Developed by:** [Abhishek Khanra](https://apify.com/ishekofficial) (community)
- **Categories:** Lead generation, Automation, Jobs
- **Stats:** 22 total users, 4 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-usage

## 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

## Global Government Tender Monitor & Notion Pipeline

**Unlock the multi-trillion-dollar public procurement market, ranked by the work your business actually wins.** This Actor monitors government tenders, RFPs, and contract notices across the USA and UK, scores every one of them against your own capability profile, and delivers the qualified opportunities straight into your Notion pipeline. No keywords to re-type. No duplicate rows. No API keys to manage.

Most tender tools hand you a firehose and let you sort it out. This one already knows what you do, what codes you hold, and which agencies you've won with.

### Features

- **Your Business Profile Drives the Search**: Keep your keywords, NAICS/CPV codes, and target agencies in a Notion database your team already maintains. The Actor reads it before every run. Change your strategy in Notion, not in a form.
- **Past-Performance Scoring**: A contract from an agency you've previously won work with ranks above an identical contract from a stranger. Nothing else on the Store can do this, because nothing else reads your win history.
- **Delivered to Your Pipeline, Not a Dataset**: Qualified contracts arrive as rows in your Notion pipeline, with buyer, deadline, contact, direct link, and a plain-English reason for the score. Ready to work, not ready to export.
- **Never Sends You the Same Contract Twice**: The Actor reads your pipeline before it writes to it. Schedule it daily and it only ever tells you what's new.
- **No Credentials to Manage**: One-click Notion authorization through Apify. No integration secrets, no tokens pasted into input fields. The Actor never sees your Notion credentials at all.
- **Rich Procurement Metadata**: 35+ data points per tender including direct **Buyer Contacts**, **NAICS/CPV Codes**, **Set-Asides**, and **Award Details**.
- **Currency Normalization**: All contract values converted to **USD** for unified filtering and analysis.

### Usage

#### 1. Create two Notion databases

**Capability Profile**: tells the Actor what you do:

| Name | Type | Weight | Active |
| :--- | :--- | :--- | :--- |
| cloud migration | Keyword | 3 | ✅ |
| cyber security | Keyword | 2 | ✅ |
| 541512 | NAICS | 2 | ✅ |
| 72000000 | CPV | 2 | ✅ |
| Veterans Affairs | WonAgency | | ✅ |
| Department of the Navy | WonAgency | | ✅ |
| Home Office | ExcludeBuyer | | ✅ |

Columns: `Name` (Title), `Type` (Select), `Weight` (Number), `Active` (Checkbox).

**Contract Pipeline**: where qualified opportunities land:

`Name` (Title) · `Source ID` (Text) · `Buyer` (Text) · `Score` (Number) · `Budget (USD)` (Number) · `Country` (Text) · `Deadline` (Date) · `Link` (URL) · `Contact` (Email) · `Why it scored` (Text)

> Use **Text** for `Country`, not Select. Notion select columns only accept options that already exist, and they do not learn new ones from an API write. A fresh Select column has no options at all, so every row would be rejected. Text accepts anything. If you prefer Select for the colour coding, create the options `USA` and `UK` by hand first.

#### 2. Connect Notion

In Apify Console → **Settings → MCP connectors → Add connector** → enter `https://mcp.notion.com/mcp` → authorize and grant access to both databases. That's the only setup step.

#### 3. Configure and run

- **Notion connectors**: Select your connector in both fields.
- **Database IDs**: The 32-character ID from each Notion URL.
- **Minimum score to write back**: Only contracts at or above this reach your pipeline. Default `65`.
- **Dry run**: Score everything and log what *would* be written, without touching Notion. Recommended for your first run.
- **Deadline Within (Days)**: Government frameworks often run years ahead, so `365` or more is usually right.
- **Target Countries**: `USA`, `UK`, or leave empty for both.
- **SAM.gov API Key**: (Optional) Free from [sam.gov](https://sam.gov) to unlock US federal data. Leave empty to run UK only.

### What it looks like

![Capability profile in Notion](https://raw.githubusercontent.com/IshekKhal/government-tender-monitor/main/assets/notion-database-capability-profile-configuration.png)
*Your capability profile in Notion. This is the only place you configure what to search for.*

![Contract pipeline in Notion](https://raw.githubusercontent.com/IshekKhal/government-tender-monitor/main/assets/notion-database-qualified-contracts-opportunity-pipeline.png)
*Qualified contracts delivered to your pipeline, scored and explained.*

![Apify Console input](https://raw.githubusercontent.com/IshekKhal/government-tender-monitor/main/assets/apify-console-two-notion-mcp-connectors-input-configuration.png)
*One-click Notion authorization. No API keys.*

### Output

Every contract is written to your Notion pipeline **and** returned in a standardized dataset:

- `title` / `description`: The opportunity itself.
- `buyer` + `buyerDepartment` / `buyerAgency` / `buyerOffice`: Granular buyer hierarchy.
- `buyerContactName` / `buyerContactEmail` / `buyerContactPhone`: Direct route to the procurement officer.
- `country` / `region` / `postcode` / `placeOfPerformance`: Where the work happens.
- `noticeType` / `status`: e.g. "Solicitation", "active".
- `naicsCode` / `cpvCode` / `classificationCode`: Industry classification.
- `setAside` / `isSMEEligible`: Small business eligibility.
- `valueLow` / `valueHigh` / `awardValue` / `budgetUsd` / `currency`: Financials, normalized to USD.
- `deadline` / `publishedDate` / `contractStartDate` / `contractEndDate` / `awardDate`: Full timeline.
- `documentUrls` / `sourceRecordUrl`: Direct links to specs and the official notice.
- `supplierName` / `supplierUei`: Awarded supplier, where applicable.
- `confidenceScore`: 0–100, scored against your profile.
- `scoreReason`: Plain-English explanation of the score.
- `profileContribution`: Points this contract earned *specifically* because of your capability profile.
- `matchedVia`: Which of your profile signals surfaced this contract.
- `keywordsMatched`: Which of your keywords hit.

#### Example output

```json
{
  "rawSourceId": "a1b2c3d4e5f6",
  "sourceName": "SAM.gov",
  "title": "J065--Federal EHR Oracle Migration Support in support of the VISN VAHCS",
  "description": "The Department of Veterans Affairs requires migration support for Electronic Health Record infrastructure...",
  "buyer": "VETERANS AFFAIRS, DEPARTMENT OF.VETERANS AFFAIRS, DEPARTMENT OF.246-NETWORK CONTRACT OFFICE 23",
  "buyerDepartment": "VETERANS AFFAIRS, DEPARTMENT OF",
  "buyerAgency": "VETERANS AFFAIRS, DEPARTMENT OF",
  "buyerOffice": "246-NETWORK CONTRACT OFFICE 23",
  "buyerContactEmail": "contracting.officer@va.gov",
  "country": "USA",
  "noticeType": "Sources Sought",
  "status": "Active",
  "naicsCode": "541512",
  "classificationCode": "J065",
  "setAside": "Total Small Business Set-Aside (FAR 19.5)",
  "budgetUsd": null,
  "currency": "USD",
  "deadline": "2026-08-14T17:00:00.000Z",
  "publishedDate": "2026-07-30T10:00:00.000Z",
  "documentUrls": ["https://sam.gov/api/prod/opps/v3/opportunities/resources/files/123456"],
  "sourceRecordUrl": "https://sam.gov/opp/a1b2c3d4e5f6/view",
  "confidenceScore": 70,
  "confidenceScoreWithoutProfile": 55,
  "profileContribution": 15,
  "scoreReason": "base 40; previously won with \"veterans affairs\" (+15); contact or documents available (+5); published 1d ago (+10)",
  "matchedVia": "naics=541512",
  "keywordsMatched": []
}
```

Note `confidenceScore: 70` against `confidenceScoreWithoutProfile: 55`. That 15-point gap is the past-performance bonus. This contract ranks higher because the Actor read your win history.

### Supported Regions

| Region | Source | Status | Features |
| :--- | :--- | :--- | :--- |
| **USA** | SAM.gov (Official API) | ✅ Active | Rich Data, NAICS, Set-Asides, Buyer Hierarchy |
| **UK** | Contracts Finder (OCDS) | ✅ Active | Rich Data, CPV, Document Links |
| **EU** | TED (Tenders Electronic Daily) | 🔧 In development | See note below |

**On EU coverage:** v1 listed TED as "coming in v2.0". It isn't in this release, and it's fair to say why. TED migrated to a new API with a different schema, and mapping it into the unified output properly is a bigger job than the original estimate. EU procurement uses different notice types, award structures, and lot handling that don't map cleanly onto the existing US/UK schema. A half-working EU source would be worse than none, because you'd trust it. It remains the most-requested addition and it's the next thing being built.

### Integrations

Beyond Notion, results can be pushed anywhere Apify integrates (Google Sheets, Slack, Airtable, Zapier, Make) or pulled via the [Apify API](https://docs.apify.com/api/v2). Schedule the Actor daily and it maintains your pipeline on its own.

***

Built by [Abhishek Khanra](https://apify.com/ishekofficial). Pay-per-use, no subscription required.

# Actor input Schema

## `capabilityConnector` (type: `string`):

Connector used ONLY to read your capability profile database. This determines what the Actor searches for. See the README for the database template.

## `pipelineConnector` (type: `string`):

Connector used to read existing pipeline rows for deduplication, then write new qualifying contracts back.

## `runMode` (type: `string`):

Leave as 'analyse'. Set to 'discover' only when connecting a new MCP server for the first time: it prints every tool the connector exposes with its annotations and input schema, then exits without scraping anything.

## `capabilityDatabaseId` (type: `string`):

The 32-character ID from your Notion capability profile database URL.

## `pipelineDatabaseId` (type: `string`):

The 32-character ID from your Notion contract pipeline database URL. Qualifying contracts are written here.

## `capabilityViewUrl` (type: `string`):

Open the capability profile database in Notion and copy the FULL browser URL — it must contain ?v=... The view ID cannot be derived from the database ID, so without this the database-view read path is unavailable. Only used when notion-query-data-sources is over your workspace quota.

## `pipelineViewUrl` (type: `string`):

Same thing for the contract pipeline database. Full URL including ?v=...

## `minimumScore` (type: `integer`):

Only contracts scoring at or above this are written to Notion. Everything scraped still lands in the dataset regardless.

## `dryRun` (type: `boolean`):

Runs the full read + scrape + score pipeline and logs exactly what would be written, without touching your Notion pipeline. Use this on your first run.

## `maxWritesPerRun` (type: `integer`):

Safety cap. Notion rate-limits at roughly 3 requests/second, and an unbounded first run against a fresh pipeline can write hundreds of rows.

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

⚠️ Anything you type here REMOVES results. This is not where you put what you are looking for. Your search terms live in the Notion capability profile as rows with Type = Keyword. Leave this empty unless you have something specific to filter out (e.g. 'janitorial', 'catering'). Exclusions can also be kept in Notion as rows with Type = ExcludeKeyword.

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

List of countries to monitor. Leave empty for all available (currently USA and UK).

## `minimumBudget` (type: `integer`):

Minimum estimated value converted to USD.

## `deadlineWithinDays` (type: `integer`):

Only include tenders expiring within this many days.

## `maxResultsPerSource` (type: `integer`):

Limit the number of results scraped per source.

## `includeNoDeadline` (type: `boolean`):

RFIs and Sources Sought notices often have no response date. They are early-stage signals — you hear about a requirement before the solicitation exists — so they are kept by default. Turn off to only see opportunities with a firm deadline.

## `includeExpired` (type: `boolean`):

Whether to include tenders that have already passed their deadline.

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

Optional — required only to include U.S. federal tenders from the official SAM.gov API. Free from sam.gov. Leave empty to run UK only.

## `samMaxRequestsPerRun` (type: `integer`):

SAM.gov allows non-federal API keys only 10 requests PER DAY. Each profile signal costs one request, so this caps how many are spent per run. Classification codes are prioritised over keywords because they return far more results per request.

## `samCacheHours` (type: `integer`):

Reuse SAM.gov responses this recent instead of spending a request. Set higher while developing so debugging runs don't burn the daily allowance; the tender feed changes slowly enough that 6 hours is safe in production.

## `notifyWebhook` (type: `string`):

Optional URL to POST a run summary to on completion.

## Actor input object example

```json
{
  "runMode": "analyse",
  "capabilityDatabaseId": "1f2a3b4c5d6e7f8090a1b2c3d4e5f607",
  "pipelineDatabaseId": "607f5e4d3c2b1a0908f7e6d5c4b3a2f1",
  "capabilityViewUrl": "https://www.notion.so/workspace/3ade23d3fab38049980cfe9aa75b5ff3?v=abc123def456",
  "pipelineViewUrl": "https://www.notion.so/workspace/607f5e4d3c2b1a0908f7e6d5c4b3a2f1?v=789abc012def",
  "minimumScore": 65,
  "dryRun": true,
  "maxWritesPerRun": 50,
  "excludeKeywords": [],
  "countries": [],
  "minimumBudget": 0,
  "deadlineWithinDays": 60,
  "maxResultsPerSource": 200,
  "includeNoDeadline": true,
  "includeExpired": false,
  "samMaxRequestsPerRun": 4,
  "samCacheHours": 6
}
```

# Actor output Schema

## `tenders` (type: `string`):

Dataset containing all scraped, normalized, and scored government contract opportunities.

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

Summary statistics of tenders fetched, scored, deduplicated, and written to Notion.

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("ishekofficial/goverment-contract-monitor").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("ishekofficial/goverment-contract-monitor").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 '{}' |
apify call ishekofficial/goverment-contract-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ishekofficial/goverment-contract-monitor"
        }
    }
}
```

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/OEhjda3NeVRI2fiJs/builds/HNBS0ek3A0Tco7fZO/openapi.json
