# Government Tenders API - EU TED, SAM.gov, UK - New Alerts (`aw09/government-tender-feed`) Actor

Multi-source government tender & public procurement feed. Official open APIs only (EU TED, UK Contracts Finder, SAM.gov). Unified schema, new-tender-only monitor mode, filters by keyword, CPV, country and value.

- **URL**: https://apify.com/aw09/government-tender-feed.md
- **Developed by:** [Agung Wicaksono](https://apify.com/aw09) (community)
- **Categories:** Developer tools, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.50 / 1,000 tender extracteds

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 API — EU TED, SAM.gov, UK Contracts Finder

Multi-source government tender & public procurement feed as clean JSON, from official government
APIs only. No scraping, no proxies, no browser, no customer login. Point it at a schedule and it
becomes a new-tender alert feed for your niche.

**Sources (all official open APIs, commercial reuse permitted):**

| Source | Coverage | Auth |
|---|---|---|
| TED | EU (all 27 member states) | none |
| Contracts Finder | UK | none |
| SAM.gov | US federal | your own free API key |

AusTender is deliberately not supported: it has no official API, so it is not scraped.

### What you get

One row per tender, one schema for every source:

```json
{
  "source": "ted",
  "raw_id": "674226-2026",
  "title": "France – Repair and maintenance services of firefighting equipment",
  "organization": "Banque de France",
  "country": "FRA",
  "published_date": "2026-10-01",
  "value": 300000,
  "cpv_codes": ["50413200"],
  "url": "https://ted.europa.eu/en/notice/-/detail/674226-2026"
}
```

- `source` — `ted`, `uk_cf` or `sam_gov`
- `raw_id` — the source's own notice id, unique within the source
- `title`, `organization` — notice title and buying organization, as published
- `country` — buyer country, in the code the source uses (TED: ISO3 like `DEU`; UK: `GB`; US: `US`)
- `published_date` — `YYYY-MM-DD`
- `value` — estimated contract value, in the source's own currency (EUR / GBP / USD). `null` when the
  buyer published no figure
- `cpv_codes` — category codes (CPV for TED/UK, NAICS for SAM.gov), de-duplicated
- `url` — the notice page

### Who this is for

- **Contractors and vendors selling to the public sector** — get the notice while it is still open,
  not from a £1,359/year (Tenders Direct pricing) subscription feed.
- **Bid / tender consultancies** — one schema across three jurisdictions to feed your own CRM.
- **Market analysts** — track what governments buy, by category and by buyer.
- **Developers** — a JSON feed you can filter and forward anywhere: Slack, email, Sheets, a database.

### Monitor mode (new tenders only)

Set **Only new tenders** to `true` and schedule the Actor. It records every tender it has already
delivered, so each run outputs only notices that no earlier run has seen — an alert feed, not a
re-export. Tenders already seen are never billed twice, and monitor runs are billed at the cheaper
`new-tender-alert` price instead of `tender-extracted`.

### Filters

All optional. Combine them to narrow a source feed to your niche before anything is billed:

- **Keywords** — case-insensitive match on title + buyer name (`cloud`, `cybersecurity`, `road`)
- **CPV codes** — prefix match, so `72` catches `72000000`, `72200000`, … (non-EU sources match
  their own category code in the same field)
- **Countries** — buyer country codes
- **Minimum contract value** — drops below-threshold and unpublished-value tenders
- **Published since** — earliest publication date
- **Max tenders per source** — caps each run so the bill stays predictable

### Pricing

Pay per event, no subscription:

- `tender-extracted` — **$2.50 per 1,000 tenders** (primary event)
- `new-tender-alert` — **$0.50 per 1,000 new tenders** (monitor mode)

Only one of the two is charged per tender. A daily monitor run pulling 200 new tenders a day costs
about $0.10/day — roughly 10x cheaper than the incumbent subscription alert services, and you pay
nothing when there is nothing new.

### Usage

Run it from Apify Console, the API, or any scheduler:

```bash
curl -X POST "https://api.apify.com/v2/acts/<username>~government-tender-feed/runs?token=$APIFY_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"sources":["ted","uk_cf"],"keywords":["cloud"],"minValue":100000,"onlyNew":true,"maxItems":500}'
```

Or with the Apify CLI: `apify call <username>/government-tender-feed`.

SAM.gov needs your own free key: log in at sam.gov → Account Details → API Key. Paste it into the
**SAM.gov API key** input field; it is stored encrypted and never leaves your run.

### Notes

- Every adapter is a plain HTTP JSON call to the official API — runs in seconds, 256 MB.
- A source that fails is logged and skipped; the rest of the run still delivers.
- SAM.gov fails loudly when the key is missing rather than returning fabricated rows.
- Output is the default dataset, also viewable as the **Tenders** table view.
- Cheaper tender feeds exist in Apify Store; this Actor competes on official government APIs
  (no scraping, no proxies), a monitor mode that bills new tenders separately, and pay-per-use
  pricing — not on being the cheapest per 1,000 items.

### Local development

```
python test_contract.py     # schema + filter + monitor-mode contract, no network
python test_real_fetch.py   # 5 live tenders per source -> probe_out/real_tenders.json
python test_only_new.py     # monitor mode against a mock KV store
```

`ADAPTER_NOTES.md` documents each source's endpoint, auth and field mapping, with the raw probe
responses in `probe_out/`.

# Actor input Schema

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

Which tender sources to query. ted = EU TED (no key). uk_cf = UK Contracts Finder (no key). sam_gov = US SAM.gov (requires your own free API key, see below). AusTender has no official API and is not supported.

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

Only needed when sam_gov is in Sources. Free: log in at sam.gov, then Account Details > API Key. Stored encrypted.

## `onlyNew` (type: `boolean`):

When on, this run outputs only tenders that no earlier run of this Actor has delivered, and bills the cheaper new-tender-alert event. Turn off to re-export everything the filters match.

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

Optional. Case-insensitive substring match against the tender title and the buyer name. Any keyword matching keeps the tender.

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

Optional. EU category codes; prefix match, so 72 matches 72000000, 72200000, etc. Non-EU sources are matched against their own category code in the same field.

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

Optional. Buyer country filter. EU TED reports ISO3 codes (DEU, FRA), UK and US report GB and US, so enter the code the source uses.

## `minValue` (type: `integer`):

Optional. Drop tenders below this estimated value. Tenders with no published value are dropped too, since they cannot be shown to meet the threshold. Currency follows the source (EUR, GBP, USD).

## `publishedSince` (type: `string`):

Optional. Earliest publication date to include (YYYY-MM-DD). Leave empty to use each source's own default window (TED from 2026-01-01, UK last 30 days, SAM.gov last 30 days).

## `maxItems` (type: `integer`):

Upper bound on tenders requested from each source per run. Keep the run cheap and the bill predictable.

## Actor input object example

```json
{
  "sources": [
    "ted",
    "uk_cf"
  ],
  "onlyNew": false,
  "keywords": [
    "cloud",
    "cybersecurity"
  ],
  "cpvCodes": [
    "72000000",
    "48000000"
  ],
  "countries": [
    "DEU",
    "FRA"
  ],
  "minValue": 100000,
  "publishedSince": "2026-10-01",
  "maxItems": 1000
}
```

# Actor output Schema

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

One item per tender notice, with source, title, buyer, country, publication date, value, CPV codes and the canonical notice URL.

# 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": [
        "ted",
        "uk_cf",
        "sam_gov"
    ],
    "keywords": [
        "cloud",
        "cybersecurity"
    ],
    "cpvCodes": [
        "72000000"
    ],
    "countries": [
        "DEU",
        "FRA",
        "GB",
        "US"
    ],
    "minValue": 100000
};

// Run the Actor and wait for it to finish
const run = await client.actor("aw09/government-tender-feed").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": [
        "ted",
        "uk_cf",
        "sam_gov",
    ],
    "keywords": [
        "cloud",
        "cybersecurity",
    ],
    "cpvCodes": ["72000000"],
    "countries": [
        "DEU",
        "FRA",
        "GB",
        "US",
    ],
    "minValue": 100000,
}

# Run the Actor and wait for it to finish
run = client.actor("aw09/government-tender-feed").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": [
    "ted",
    "uk_cf",
    "sam_gov"
  ],
  "keywords": [
    "cloud",
    "cybersecurity"
  ],
  "cpvCodes": [
    "72000000"
  ],
  "countries": [
    "DEU",
    "FRA",
    "GB",
    "US"
  ],
  "minValue": 100000
}' |
apify call aw09/government-tender-feed --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,aw09/government-tender-feed"
        }
    }
}
```

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/ZhVxSVfA09vMqzeLn/builds/59y1ZgZq6IVyIwmDs/openapi.json
