# Government Tenders Scraper — RFPs & Contract Awards (`inovaflow/government-tenders-scraper`) Actor

Open government tenders, RFPs and contract awards from the US, UK, EU and Canada in one clean feed: buyer, value, deadline, awardee and notice link, deduplicated across portals, with what is new since your last run. Raw typed data, MCP-ready.

- **URL**: https://apify.com/inovaflow/government-tenders-scraper.md
- **Developed by:** [inovaflow](https://apify.com/inovaflow) (community)
- **Categories:** Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $10.00 / 1,000 tenders

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

## Government Tenders Scraper — RFPs & Contract Awards

If you sell to government — or to the companies that win government contracts — the best leads you will ever get are
published for free every day: a named buyer, a budget, a deadline, and later the vendor who won. The catch is that
they are scattered across a dozen national procurement systems, each with its own format, codes, currencies and
quirks.

This Actor reads them for you and hands back **one clean, typed row per notice**, in one schema, whatever the country:
open tenders and RFPs (an active buying window), contract awards (budget just landed, and who got it) and, if you
want them, planned procurements (a purchase coming soon). Schedule it and it returns **only what is new or changed
since your last run**.

**Who it's for**

- **B2B and govtech sales teams** — see every public-sector buyer asking for what you sell, with days left to bid.
- **Agencies, consultancies and integrators** — follow the awards in your niche and learn who is winning, for how much.
- **Partners and subcontractors** — an award names the prime contractor: that is your next outbound list.
- **AI and GTM agents** — call it over MCP or the API, get raw structured facts, reason on your own side.

### What you get

Coverage: **United States** (federal contract awards; federal open opportunities too with your own free SAM.gov key),
**United Kingdom** (central and local government, above and below threshold), **every EU/EEA country** (plus
Switzerland), and **Canada** (federal).

Every row, whatever the source:

| Field | What it is |
| --- | --- |
| `noticeType` | `tender` (open call for bids / RFP / RFQ), `award` (contract awarded) or `planning` |
| `status` | `open`, `closed`, `awarded`, `planned`, `cancelled` |
| `title`, `description` | as published (description up to 1,000 characters), with `language` |
| `buyer`, `buyerUnit`, `buyerUrl`, `country` | who is buying |
| `valueAmount`, `valueCurrency`, `valueType` | the amount in the notice's own currency, and what it means: `estimated`, `awarded` or `obligated` |
| `valueUsd`, `fxRate`, `fxRateDate` | an **indicative** USD conversion at the official euro reference rate — clearly separate from the real amount |
| `publishedAt`, `deadlineAt`, `daysUntilDeadline`, `awardedAt`, `contractStart`, `contractEnd` | the dates, in the source's own precision |
| `awardee`, `awardeeDomain`, `awardees[]` | the winning vendor(s), with an id and website where available — each website says where it came from |
| `cpvCodes`, `naicsCodes`, `classifications[]` | category codes (CPV, NAICS, PSC, UNSPSC, GSIN) |
| `noticeUrl`, `sources[]` | the official notice page — and every portal that carried it |
| `canonicalId`, `isNewSinceLastRun`, `changedFields`, `firstSeenAt` | stable id and the since-last-run delta |

Example row (trimmed):

```json
{
  "canonicalId": "uk-find-a-tender:tender:ocds-h6vhtk-077ad8",
  "noticeType": "tender",
  "status": "open",
  "title": "Supply of Networking Hardware and Software",
  "buyer": "South Wales Fire and Rescue Service",
  "country": "GB",
  "valueAmount": 583000,
  "valueCurrency": "GBP",
  "valueType": "estimated",
  "valueUsd": 772613,
  "deadlineAt": "2026-10-26T12:00:00Z",
  "daysUntilDeadline": 30,
  "cpvCodes": ["32420000"],
  "noticeUrl": "https://www.find-tender.service.gov.uk/Notice/091153-2026",
  "isNewSinceLastRun": true,
  "changedFields": []
}
```

The dataset has four ready views: **All notices**, **Open tenders** (deadline and days left), **Contract awards**
(winner, website, value) and **New and changed**.

### How to use it

Everything is optional. An empty run returns the last 7 days of tenders and awards from every country.

- **Keywords** — what you sell: `software`, `cybersecurity`, `cloud hosting`, `facilities management`.
- **Countries** — `US`, `GB`, `CA`, `EU`, or single EU/EEA countries.
- **Notice types** — tenders, awards, planned procurements.
- **CPV / NAICS codes** — prefixes work: `72` = IT services, `5415` = computer systems design.
- **Buyers** — an agency, council, ministry or trust, e.g. `Department of Veterans Affairs`, `NHS`.
- **Value range** (USD), **deadline window**, **only tenders still open**.

#### Daily monitoring

Turn on **Only new or changed since the last run** and schedule the Actor daily. The first run is your baseline; every
run after that returns just the new notices, plus the ones whose deadline, value, status or awardee changed
(`changedFields` says which). Give the schedule a **watch name** to keep separate monitors apart.

#### Call it from an agent (MCP / API)

```json
{
  "keywords": ["cybersecurity"],
  "countries": ["US", "GB", "DE"],
  "noticeTypes": ["tender", "award"],
  "publishedWithinDays": 3,
  "onlyNewSinceLastRun": true,
  "watchId": "cyber-daily",
  "maxResults": 200
}
```

The run summary (`OUTPUT` in the key-value store) reports counts by type, status, country and source, what each
source returned, the exchange-rate date and any input it could not use.

### Accuracy, not guesses

- Every field comes from the official notice or is `null`. No AI rewriting, no scoring prose, no invented values.
- A value printed as 0 or 1 (buyers withholding the price) is reported as `null`, not as a price.
- Amounts are never converted in place; `valueUsd` is a separate, dated, indicative field.
- The same notice published on two portals is **one row** with both in `sources[]`; a re-published notice is not a new one.
- A vendor website is only filled when the notice prints it (`domainSource: "notice"`) or the company's own homepage
  names it (`domainSource: "homepage-match"`).

### Pricing

Pay per event: **$0.01 per notice delivered**, plus the standard Actor start fee. Duplicates, filtered-out notices
and empty runs are never charged. A daily monitor delivering 50 new notices costs about $0.50 a day — a fraction of
a procurement-intelligence subscription.

### FAQ

**Why do US results show awards but not open tenders?** US open opportunities require a personal API key. Get a free
public key from SAM.gov and paste it in **SAM.gov API key**; it is stored as a secret and only used for your runs.

**Why is `valueUsd` different from the amount?** It is an indicative conversion at the official reference rate of
`fxRateDate`. Use `valueAmount` + `valueCurrency` for the real figure.

**Why is a US award's `publishedAt` empty?** Federal award records carry a signature date (`awardedAt`), not a notice
publication date. `eventDate` always has the date used for ordering.

**A brand-new US award's link says "No Award found".** The federal award page catches up with the award search one
to three days after signature; the id in `noticeUrl` is the permanent one.

**Some rows have no value.** Many tenders do not publish one — the field is `null` rather than a guess. Set a minimum
value to keep only notices that state one.

# Actor input Schema

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

Words or phrases to look for in the notice (any of them matches). Empty = every notice. Examples: software, cybersecurity, cloud hosting, facilities management.

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

Buyer countries. Empty = all. US = federal awards (plus open opportunities with your own SAM.gov key), GB = UK central and local government, CA = Canadian federal government, EU = every EU/EEA buyer; or pick single EU/EEA countries.

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

Tender = an open call for bids (tender, RFP, RFQ, contract notice) — an active buying window. Award = a contract awarded to a named vendor — budget just landed. Planning = a prior-information or pre-market notice — a purchase coming soon.

## `publishedWithinDays` (type: `integer`):

How far back to look. 1–7 for a daily or weekly monitor; up to 365 for a one-off backfill.

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

Stop after this many notices (newest first). You are only charged for notices delivered.

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

Common Procurement Vocabulary codes or prefixes — 72 = IT services, 48 = software packages, 79 = business services. A code filter skips portals that do not classify by it.

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

NAICS codes or prefixes for US notices — 5415 = computer systems design, 541512 = systems integration.

## `buyers` (type: `array`):

Only notices from these buyers (agency, council, ministry, hospital trust…). A name or part of one, e.g. Department of Veterans Affairs, NHS, Bundesamt.

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

Only notices worth at least this much (converted to USD at the official reference rate). Notices that do not publish a value are left out when this is set.

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

Only notices worth at most this much. Notices without a published value are kept.

## `onlyOpenTenders` (type: `boolean`):

Drop tenders whose submission deadline has passed. Awards and planning notices are not affected.

## `deadlineAfter` (type: `string`):

Only tenders whose submission deadline is on or after this day (YYYY-MM-DD).

## `deadlineBefore` (type: `string`):

Only tenders whose submission deadline is on or before this day (YYYY-MM-DD).

## `onlyNewSinceLastRun` (type: `boolean`):

Deliver only notices this watch has not seen before, or whose status, deadline, value or awardee changed. The first run of a watch returns everything and becomes the baseline.

## `watchId` (type: `string`):

Names the memory used for 'new since last run'. Runs with the same watch name share it. Empty = derived from your filters, so the same search always continues the same watch.

## `resolveAwardeeDomains` (type: `boolean`):

For award notices that do not print the winner's website, check the obvious homepage and keep it only when the page names the company. Every domain says where it came from.

## `maxDomainLookups` (type: `integer`):

Upper bound on winner-website checks per run.

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

Your own free SAM.gov public API key. Adds US federal OPEN opportunities (solicitations, sources sought, pre-solicitations). Without it, US coverage is federal contract awards.

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

Not needed — the sources are official open-data services. Use it only if your network is blocked.

## Actor input object example

```json
{
  "keywords": [
    "cybersecurity",
    "cloud"
  ],
  "countries": [
    "US",
    "GB"
  ],
  "noticeTypes": [
    "tender",
    "award"
  ],
  "publishedWithinDays": 7,
  "maxResults": 20,
  "cpvCodes": [],
  "naicsCodes": [],
  "buyers": [],
  "onlyOpenTenders": false,
  "onlyNewSinceLastRun": false,
  "resolveAwardeeDomains": true,
  "maxDomainLookups": 30,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

Tenders, awards and planning notices, one normalized row each, newest first.

## `openTenders` (type: `string`):

Buyer, value, deadline and days left to bid.

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

Buyer, winning vendor, vendor website and awarded value.

## `changes` (type: `string`):

What is new or changed since the previous run of this watch.

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

Counts by type, status, portal and country, per-source report, exchange-rate date and the watch id.

# 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"
    ],
    "countries": [
        "US",
        "GB"
    ],
    "maxResults": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("inovaflow/government-tenders-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"],
    "countries": [
        "US",
        "GB",
    ],
    "maxResults": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("inovaflow/government-tenders-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"
  ],
  "countries": [
    "US",
    "GB"
  ],
  "maxResults": 20
}' |
apify call inovaflow/government-tenders-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,inovaflow/government-tenders-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/MdWoFXmc4xjxIqPbt/builds/kiv38UZP7wLcKu2cr/openapi.json
