# Government Tenders Scraper: Global Notices & Awards (`zaiq/government-tenders-scraper`) Actor

Search official public procurement notices across countries. Get buyers, deadlines, values, classification codes, lots, document links and awards in one schema, with deduplication and new-notice alerts.

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

## Pricing

from $2.40 / 1,000 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

## Government Tenders Scraper: official notices and awards in one schema

![Government Tenders Scraper: Global Notices & Awards](https://api.apify.com/v2/key-value-stores/4VJNANhwKgqPpXtAi/records/hero-government-tenders-scraper.jpg)

Get government procurement notices with a plain verdict, buyer, deadline, classification codes, available values, lots, document links and award information. Search official public feeds across Europe, the UK, US federal procurement, Australia, Canada, France and New Zealand.

**$0.003 per notice** on every source and every connection route, the same price on every Apify plan. Failures and status notes are free. The smallest input is `{}`: it returns up to 10 recent TED tenders with a future deadline. No source account or API key is needed.

Coverage is specific to each source. TED supplies notices published on the European portal. Find a Tender and Contracts Finder supply UK OCDS releases. SAM.gov supplies federal search records and notice links. AusTender supplies awarded contracts. CanadaBuys supplies the federal open-tender file and award files. BOAMP supplies French notices. GETS supplies New Zealand’s current-tenders RSS feed.

### What you get

| Field | What it holds |
|---|---|
| verdict | A one-line status, such as a tender deadline, an award amount, or an explanation of a free note row. |
| source, noticeId, procurementId | The originating feed and identifiers. A procurement process can have several distinct tender, award and amendment notices. |
| title, description, buyer, buyerId | Source text and the named procuring organisation where published. Text remains in its original language. |
| country, countries, region | Buyer country on TED and the national procurement jurisdiction on national feeds, plus published region codes or names. |
| cpvCodes, unspscCodes, naicsCodes | Separate classification systems, kept as strings so leading zeros survive. |
| estimatedValue, currency, valueMin, valueMax | Published estimates and ranges. A missing value stays null. |
| published, updated, deadline, deadlines, deadlinePrecision | Published dates and the source’s closing dates. Date-only deadlines and times without a timezone are labelled. |
| procedure, lots, lotTitles | The procedure and available lot information. TED’s independent lot-ID and title lists are kept separate. |
| documents | Public document links supplied by a feed, plus the official notice XML link on TED. Documents are not downloaded. |
| awardWinner, awardValue, awardCurrency, awards | Published winners and values. Multiple award values are combined only when all values are available in the same currency. |
| sourceUrl, dataUrl, crossPortalIds | A public notice or official data link, its source feed and exact identities used for deduplication. |
| note, notes, kind, resultId | Missing-data explanations, free source notes and a stable delivery ID. Filter kind=notice to keep only procurement records. |
| SUMMARY | Per-source rows, scans, requests, traffic, duplicates, skipped malformed records, limits, route changes and alert state. |

### What people use it for

- **Supplier bid discovery:** Search the places where buyers publish tenders, then filter by a relevant sector code, buyer jurisdiction, deadline and disclosed budget.
- **Bid consultancy:** Collect several public feeds into the same columns for review, qualification and bid tracking.
- **Award research:** See named suppliers and disclosed contract values, without confusing an estimated opportunity value with a completed award.
- **Notice alerts:** Schedule new-notice mode with a consistent named state store to deliver previously unseen notices within a rolling publication window.
- **Procurement data pipelines:** Export JSON, CSV or spreadsheet data with source IDs and links, and retain free status rows so an unavailable source is visible.

### How to use it

1. Run with the default input for up to 10 recent TED tenders.
2. Select your sources and notice types. For Australia, select award. Add optional keywords, codes, buyer countries, values or closing dates.
3. Set Maximum notices per source and Maximum cost per run. These are separate limits.
4. Open Notices or Award details in the dataset. Read SUMMARY for coverage and any skipped sources.
5. For repeated alerts, choose New notices since previous runs, keep the same state store and filters, and schedule runs without overlap.

### Input

| Field | Example | Notes |
|---|---|---|
| sources | \["ted", "uk_find_tender"] | Eight official feeds; see the source descriptions above. |
| keywords | \["software", "maintenance"] | Any literal phrase may match title, description or buyer. Keywords are not translated. Empty means all. |
| noticeTypes | \["tender", "award"] | Also prior_information and other; coverage varies by source. |
| maxResults | 10 | Per source, after filtering, deduplication and alert suppression. Maximum 10,000 per source. |
| countries | \["IE", "GB"] | ISO country codes. TED matches buyer country; national feeds use their procurement jurisdiction. |
| cpvCodes / unspscCodes | \["72"] / \["43"] | Codes or numeric prefixes. A match in either selected code system is enough. Sources without either scheme are skipped. |
| currency, minValue, maxValue | EUR, 100000, 5000000 | Currency is required for a value range. Estimates for tenders; award values for awards. No exchange-rate conversion. |
| publishedWithinDays | 30 | Rolling window. Use publishedFrom and publishedTo for an inclusive YYYY-MM-DD range, up to 365 days. |
| deadlineFrom / deadlineTo | YYYY-MM-DD | Inclusive closing-date window; records without a deadline are excluded. |
| openOnly | true | Only tenders with a known, non-expired deadline. Does not exclude awards or prior-information notices. |
| deduplicate | true | Exact notice identities across selected sources, not similar titles. Different publication versions stay distinct. |
| mode / stateStore | new / procurement-alerts | Named persistent state; first run delivers the current matches, later runs suppress identities already delivered. |
| maxScannedPerSource | 5000 | Before filters. Increase for a sparse search; maximum 50,000. |
| maxRequestsPerSource | 120 | Includes retries. Maximum 150; 429 and 503 stop that source. |

### Output

Each result is one row in the run's dataset (download it as JSON, CSV, Excel, XML or HTML, or read it through the API). An example row (values shortened):

```json
{
  "kind": "notice",
  "verdict": "Award notice — GBP 120,000.00",
  "source": "uk_find_tender",
  "noticeId": "100001-2026",
  "title": "Building roof replacement",
  "buyer": "Example Public Buyer",
  "country": "GB",
  "noticeType": "award",
  "cpvCodes": [
    "45261900",
    "45260000",
    "45261210",
    "45261910",
    "45261920"
  ],
  "estimatedValue": null,
  "currency": null,
  "published": "2026-10-23T19:46:24+01:00",
  "deadline": null,
  "procedure": "Restricted procedure",
  "awardWinner": "Example Services Ltd",
  "awardValue": 120000.0,
  "awardCurrency": "GBP",
  "sourceUrl": "https://procurement.example/notices/100001-2026"
}
```

This example comes from the real UK award test on 25 October 2026. Organisation and supplier names, the notice identifier and site address have been replaced; the title has been paraphrased. Dates, classifications and amounts are from that delivered row. SUMMARY records source coverage, any free failures and the charged events.

### Pricing

- **$0.003 per delivered notice** ($3 per 1,000), whatever the source or connection route.
- These are the same prices on every Apify plan. There is no AI step or separate AI bill.
- Failures, no-match notes, skipped duplicate notices and previously delivered alert notices have no notice charge.
- Apify’s **$0.00005 start charge** counts towards the buyer’s **Maximum cost per run**.

What typical jobs cost at the list price:

| Job | Cost |
|---|---|
| 10 notices | $0.03005 including the start charge |
| 100 notices | $0.30005 including the start charge |
| 2,000 notices | $6.00005 including the start charge |
| No delivered notices | $0.00005 start charge; no notice charges |

Set Maximum cost per run to control the total. At least $0.00305 covers one notice and Apify’s $0.00005 start charge. Free notes still appear after the limit.

### Tips

- Prefer CPV or UNSPSC codes when terminology varies between countries. Do not use one classification system as a substitute for the other.
- Use award mode when researching suppliers and contract values. An award can retain an old tender closing date; that does not make it an open opportunity.
- For alerts, allow a publication window long enough to overlap feed updates. Only delivered identities are remembered, so an incomplete run does not mark unseen notices as processed.
- Increase the scan limit when a local filter is very selective. SUMMARY distinguishes a complete no-match search from an incomplete portion of a feed.
- Use the source link to check the current notice and submission instructions. The Actor does not submit bids or download restricted documents.

### Use it through the API

**Python**

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("zaiq/government-tenders-scraper").call(run_input={"sources": ["ted"], "keywords": ["software"], "maxResults": 10})
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(row)
```

**JavaScript**

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('zaiq/government-tenders-scraper').call({"sources": ["ted"], "keywords": ["software"], "maxResults": 10});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

**HTTP (one call, results back)**

```bash
curl -X POST 'https://api.apify.com/v2/acts/zaiq~government-tenders-scraper/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{"sources": ["ted"], "keywords": ["software"], "maxResults": 10}'
```

### Integrations and schedules

- **Schedules:** run it every hour, day or week from the Apify Console (Schedules) and keep a history of results.
- **Make, Zapier, n8n, Google Sheets, Slack, Airtable:** connect it through Apify's integrations, or send each finished run to a **webhook**.
- **Datasets:** results stay in the run's dataset; export them or read them by API whenever you need them.

### Use it with AI agents (MCP)

Add Apify's MCP server (`https://mcp.apify.com`) to Claude, ChatGPT, Cursor, VS Code or any MCP client. The agent can find this Actor and run it for you: ask it for "recent software tenders with deadlines and disclosed values from the selected official sources". AI agents can also pay for runs directly through Apify's agentic payments.

### Limits

- Coverage is limited to notices the named feeds publish. This is not a complete worldwide database of every government contract.
- Australia’s open API supplies awarded contract notices, not live approaches to market. Canada’s tender coverage is the current open federal file, not its full historical archive. GETS is the current-tender RSS feed and does not provide structured awards or contract values.
- US federal rows are public search records and notice links. Use the separate SAM.gov Actor when you need full notice details and attachment lists.
- Some sources do not support keyword, code or value search server-side. Those filters are applied to the records read within the scan, request and time limits. A limited scan is reported as incomplete.
- A source stops after 150 requests, ten minutes of source time, or a response above 64 MiB. Limits and malformed records are listed in SUMMARY. A rate-limit response stops that source without rotating addresses to evade its cooldown.
- Canada uses direct then datacenter routes only. Its bulk files are too large for an economical residential fallback at these notice prices. If both routes are refused, it returns a free note.
- Other feeds try direct, datacenter, then fresh residential sessions when an address is refused or expected data is missing. A failed final route remains a visible source issue. No CAPTCHA is solved and no login is attempted.
- Exact shared notice IDs support cross-portal deduplication. Notices lacking shared identifiers can remain separate even if their titles look similar. Tender and award stages are not merged merely because they concern the same procurement.
- A value filter excludes undisclosed amounts. Canada’s zero placeholders remain in the raw amount fields and are not advertised as free contracts. Currencies are never combined across currencies.
- TED’s search API returns lot fields as independent lists. The headline deadline is the earliest available lot deadline; use the linked official XML for complete lot-level relationships.
- New-notice mode remembers up to 100,000 identities per filter profile. It detects unseen notices within the configured window, not arbitrary historical changes outside it. Store retention, concurrent runs or an evicted identity can cause a notice to appear again. Use sequential schedules.
- The default input was verified with 10 notices in about five seconds locally. A 2,200-notice pull was also checked. Source response times and availability vary.

### FAQ

**Do I need accounts on the procurement websites?**

No. The Actor reads public signed-out feeds. A linked procurement portal may require registration to obtain bidding documents or submit a bid; the Actor does not do that.

**Does it cover all of Europe?**

It covers notices published on TED, including buyers in EU and EEA countries and other jurisdictions represented there. National contracts below publication thresholds may appear only in their own portals. France additionally has a separate BOAMP adapter.

**Can I search several countries together?**

Yes. Select the sources and countries, then apply the same notice, code, value and deadline filters. The result limit is per source.

**Why is a field empty?**

A source may not publish that field, or it may be absent in an individual notice. The Actor preserves nulls rather than estimating a budget, winner, currency or closing time.

**How do updates differ from new notices?**

The state tracks published notice identities. A new release or publication version can be new; an in-place edit retaining the same identity is suppressed. This is a new-notice alert feed, not a full change-history service.

**Is a completed run always exhaustive?**

No. The run can finish successfully after delivering the requested number of rows. SUMMARY.complete and each source’s stopReason distinguish exhausted source windows, reached limits and source failures.

**What happens after a restart?**

Stable delivery IDs are read from the existing dataset. Already delivered rows are neither written nor charged again. Pending alert identities are recovered from those delivered rows.

**Are there extra charges for documents or AI?**

No documents are downloaded and no AI model is used. Only the notice events and Apify’s start charge apply.

### Related Actors from Zaiq

- [sam-gov-scraper](https://apify.com/zaiq/sam-gov-scraper): US federal notices with full details and attachment links

### Support

Questions, a site that changed, or a field you need? Open an issue on this Actor's **Issues** tab: we answer there, usually within a day.

***

Also found as: government tenders scraper, public procurement API, tender notices, contract awards, TED tenders, UK procurement notices, CPV search, UNSPSC search, new tender alerts.

# Actor input Schema

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

Select the feeds to search. The result limit applies to each source. Australia supplies awarded contracts; Canada supplies federal open tenders and fiscal-year awards; New Zealand supplies the current-tenders RSS feed.

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

Optional literal phrases matched case-insensitively in the title, description or buyer. A notice may match any phrase. Use the source language; the Actor does not translate. Empty means all notices.

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

Tender opportunities, awarded contracts, prior information, or other notices. Availability differs by source. The open-only filter applies only to tenders.

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

Maximum unique matching notices delivered from each source, after filters, deduplication and alert suppression. A reached cap is shown as partial coverage in SUMMARY.

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

Exclude tenders with missing or expired deadlines and cancelled tenders. A date-only deadline remains eligible on that date. Awards and prior-information notices are unaffected.

## `mode` (type: `string`):

Search returns matching notices. New notices remembers delivered notice identities in a named store across runs. The first run emits the current matches. Keep schedules sequential.

## `stateStore` (type: `string`):

Named key-value store for new-notice mode. Use the same name and filters for repeated runs. Changes to filters start a separate profile. Up to 100,000 identities are retained; evictions appear in SUMMARY.

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

Optional ISO alpha-2 country codes. Matches the buyer country, not necessarily the location of the work. TED covers notices published there; a selected national source is skipped when its country is excluded.

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

Optional CPV codes, such as 72000000, or numeric prefixes, such as 72. A notice may match any requested CPV or UNSPSC prefix. Sources that publish neither requested scheme are skipped with a free note.

## `unspscCodes` (type: `array`):

Optional UNSPSC codes or prefixes. Available mainly in Australia, Canada and New Zealand. A notice may match any requested prefix in either code system; the Actor does not translate between systems.

## `currency` (type: `string`):

Three-letter currency, such as EUR, GBP, USD, AUD or CAD. Required when using a value range. The Actor never converts currencies. Awards use awardCurrency; other notices use currency.

## `minValue` (type: `number`):

Minimum estimated value for tenders or disclosed award value for awards, in the selected currency. Missing values are excluded.

## `maxValue` (type: `number`):

Maximum estimated value for tenders or disclosed award value for awards, in the selected currency. Missing values are excluded.

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

Rolling publication window when publishedFrom is empty. Relative to UTC today; does not imply that a feed contains every notice in this window.

## `publishedFrom` (type: `string`):

Optional earliest publication date, YYYY-MM-DD, inclusive. Overrides publishedWithinDays. The maximum window is 365 days.

## `publishedTo` (type: `string`):

Optional latest publication date, YYYY-MM-DD, inclusive. Defaults to UTC today.

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

Optional earliest deadline, YYYY-MM-DD, inclusive. Notices without a deadline are excluded.

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

Optional latest deadline, YYYY-MM-DD, inclusive. Notices without a deadline are excluded.

## `deduplicate` (type: `boolean`):

Suppress duplicates with the same published notice identity: eForms UUID and version, OCDS release, source ID or exact notice URL. Similar titles alone are never merged.

## `maxScannedPerSource` (type: `integer`):

Safety limit before filters. Sparse searches may need a higher limit. If reached, SUMMARY says coverage is partial; zero matches then does not mean the source has none.

## `maxRequestsPerSource` (type: `integer`):

Polite request limit including retries. The Actor spaces requests and stops that source on HTTP 429 or 503. At most 150 requests per source per run.

## Actor input object example

```json
{
  "sources": [
    "ted"
  ],
  "keywords": [],
  "noticeTypes": [
    "tender"
  ],
  "maxResults": 10,
  "openOnly": true,
  "mode": "search",
  "stateStore": "government-tender-alerts",
  "countries": [],
  "cpvCodes": [],
  "unspscCodes": [],
  "publishedWithinDays": 30,
  "deduplicate": true,
  "maxScannedPerSource": 5000,
  "maxRequestsPerSource": 120
}
```

# Actor output Schema

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

Dataset: the results.

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

What each input returned, and 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": [
        "ted"
    ],
    "maxResults": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("zaiq/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 = {
    "sources": ["ted"],
    "maxResults": 10,
}

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

```

## MCP server setup

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