# Government Tenders Scraper | Data API: SAM.gov, TED, $2/1K (`aurelix/government-tenders-scraper`) Actor

Scrape government tenders data from SAM.gov (USA), CanadaBuys and TED Europa (EU) in one run at $2.00 per 1,000, cheaper than the leading tools. Official open data, no login or key: buyer, country, NAICS/UNSPSC/CPV, value, dates, status, link.

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

## Pricing

from $1.40 / 1,000 tender results

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

### What is Government Tenders Scraper?

**Get new government tenders from SAM.gov, CanadaBuys and TED (EU) in one run, with buyer, codes, value and deadline, for $2.00 per 1,000 tenders, no login.**

For contractors, suppliers and bid teams. Filter by NAICS, UNSPSC and CPV codes, keywords and countries, and get only new notices with a Slack or webhook digest after each run. Your first run with the example input costs about $0.066 (30 tenders in our test run).

[![Government Tenders Scraper: example output from a real run](https://api.apify.com/v2/key-value-stores/twkCCtTWzsi8fVbx5/records/government-tenders-scraper-card-v2.png)](https://console.apify.com/actors/H9sUbeigs6iQmydsl?addFromActorId=H9sUbeigs6iQmydsl)

| | |
|---|---|
| **Sources** | SAM.gov public extract, CanadaBuys open data, TED Search API |
| **Filters** | Days back (up to 7), open only, keywords, countries, NAICS, UNSPSC and CPV code prefixes, new tenders only |
| **Output** | 28 fields per tender; JSON, CSV, Excel, API |
| **Automate** | Schedules, webhooks, Zapier, Make, n8n, Google Sheets, MCP for AI agents |
| **Price** | $2.00 per 1,000 tenders ($1.40 per 1,000 tenders on paid Apify plans) |
| **Login needed** | No |

### Daily monitor: only what's new, every morning

Set it once, get only the new tenders every morning. With **Only new tenders since last run** on, the first run returns everything that matches; each later run skips tenders that earlier runs already returned, so you pay only for new ones.

```json
{
  "sources": [
    "sam.gov",
    "canadabuys",
    "ted"
  ],
  "daysBack": 2,
  "keywords": [
    "software",
    "cloud"
  ],
  "incremental": true,
  "stateKey": "software-cloud-tenders"
}
```

1. Paste this input into the **Input** tab (JSON view) and click **Save as a new task**; it appears under **Saved tasks**.
2. Open the task from **Saved tasks** and click **Schedule**.
3. Choose **Daily**, pick the hour, and save.

**Cost example:** 2 keywords on 3 sources, about 30 new tenders a day ≈ $1.98/month on the free plan ($1.44 on paid plans): one run a day for 30 days, start fee included. The first run returns everything that matches, so it costs more.

Add a Slack incoming-webhook URL in `slackWebhookUrl` (or any URL in `webhookUrl`) to get a short digest of each run's new tenders; nothing is sent when a run finds nothing.

### Why Government Tenders Scraper users pick this one

- **Three sources, one schema.** SAM.gov, CanadaBuys and TED in the same 28 fields.
- **Cheaper per tender.** $2.00 per 1,000 tenders, cheaper than the leading tools.
- **The buyer's own codes.** Filter by NAICS, UNSPSC and CPV prefixes.
- **New tenders only.** Notices you have not seen, plus a Slack or webhook digest.
- **No key needed.** Official open data: no login, no API key, no proxies.

### Get started in 3 steps

1. Pick the sources (SAM.gov, CanadaBuys, TED) and how many days back to look; the defaults return open tenders from the last 3 days, newest first, up to 500 per source. TED alone publishes about 3,500 notices a working day, so a default run returns the newest 500 TED notices, not all three days: the run status names every source that hit the cap, and 'Max results per source' (0 = no limit) raises it.
2. Optionally narrow it: keywords, ISO country codes, NAICS/UNSPSC/CPV code prefixes; turn on 'Only new tenders since last run' for a daily feed.
3. Click Start, then download JSON, CSV or Excel, or schedule the run and send results to Google Sheets, Slack, Zapier, Make or n8n.

**[▶ Try it with the example input](https://console.apify.com/actors/H9sUbeigs6iQmydsl?addFromActorId=H9sUbeigs6iQmydsl)**

The form opens with an example input already filled in: that run costs about $0.066 on the free plan.

### How much does it cost to scrape government tenders?

Pay per event: you pay only for what the run returns, plus a small start fee. Bronze, Silver, Gold and higher Apify plans pay less per result.

| Tenders | Free plan | Paid plans (Bronze, Silver, Gold) |
|---|---|---|
| 100 | $0.21 | $0.15 |
| 1,000 | $2.01 | $1.41 |
| 10,000 | $20.01 | $14.01 |

Totals include the $0.006 start fee per run, rounded to the cent. Apify's free plan includes $5 of credit a month, enough for about 2,500 tenders.

No charge for sources that return nothing. Each run's start fee covers downloading the three sources when your filters match nothing.

#### Billing events

| Event | Free plan | Paid plans (Bronze, Silver, Gold) |
|---|---|---|
| `tender-result` | $2.00 per 1,000 tenders | $1.40 per 1,000 tenders |
| `apify-actor-start` | $0.006 per run | $0.006 per run |

### Benchmarks: how we compare

| Test | Input | Result | Run time |
|---|---|---|---|
| Empty input (all defaults) | 3 sources, last 3 days, open only, 500 per source | 1,032 tenders (SAM.gov 500, CanadaBuys 32, TED 500); the status named SAM.gov and TED as capped | 8.4 s |
| A full week with no cap | CanadaBuys and TED, 7 days, open only, no descriptions | 4,921 tenders (CanadaBuys 110, TED 4,811), peak memory 246 MB | 71.7 s |
| New-only mode, first run | CanadaBuys and TED, 2 days, no cap | 5,374 tenders (CanadaBuys 31, TED 5,343) | 70.5 s |
| New-only mode, same input again | As above | 0 tenders: no repeats | 58.3 s |
| Keyword that matches nothing | 3 sources, 7 days, closed notices included, cap 100,000 | 0 tenders, so no tender charges; platform cost $0.0030, covered by the $0.006 start fee | 202.5 s |
| Field accuracy | 10 records: 4 SAM.gov, 3 CanadaBuys, 3 TED | 10 of 10 matched the source record field by field, descriptions included | not timed |
| SAM.gov long descriptions | 500 SAM.gov notices from a default run | 3 of 500 descriptions reached SAM.gov's 32,000-character cut | not timed |

Each timed row is one Apify cloud run at the default 256 MB memory. Accuracy was checked by comparing records with the SAM.gov opportunity API, the CanadaBuys CSV and the TED API. Counts are what the sources published at the time, so yours will differ.

### What data you get

**Government Tenders Scraper** turns public procurement notices from SAM.gov (US federal contract opportunities), CanadaBuys (Government of Canada) and TED (EU Tenders Electronic Daily) into one table: title, buyer, country, notice type, category, status, NAICS, UNSPSC and CPV codes, value where published, publish and closing dates, solicitation number, description, notice link and the point of contact (name, title, email, phone) as the notice publishes it. Filter by keywords, countries and code prefixes, and look back up to 7 days. Switch on new-only mode and schedule it daily for bid alerts.

- Title, buyer (department or contracting authority), sub-agency/office
- Country (ISO code) and state, province or buyer city
- Notice type, category (CanadaBuys: goods, services, construction; TED: supplies, services, works), status (open, closed, awarded)
- NAICS, UNSPSC and CPV codes where the source publishes them
- Estimated or awarded value and currency where published
- Publication date and bid closing time in ISO 8601 UTC (for TED restricted and negotiated procedures, the request-to-participate deadline; the latest lot deadline on multi-lot notices)
- Solicitation number, the notice description (SAM.gov, CanadaBuys, TED) and the official notice link
- Point of contact as published: contact_name, contact_title, contact_email, contact_phone, plus every contact (SAM.gov primary and secondary) in a contacts list
- Stable tender_id for joins and dedupe

| source | title | buyer | country | status | naics | value | currency | published_date | closes_at | contact_email |
|---|---|---|---|---|---|---|---|---|---|---|
| sam.gov | Post Quantum Cryptography (PQC) Readiness and Validation ... | GENERAL SERVICES ADMINISTRATION | US | open | \["541519"] |  |  | 2026-11-06 | 2026-12-08T04:59:00Z | innovationiwm@gsa.gov |
| sam.gov | CGC DILIGENCE TUG SERVICES | HOMELAND SECURITY, DEPARTMENT OF | US | open | \["488330"] |  |  | 2026-11-06 | 2026-11-07T17:00:00Z | Patricia.M.Fremming@uscg.mil |
| canadabuys | Motor Grader | Government of the Northwest Territories (GNWT) | CA | open | \[] |  |  | 2026-11-06 | 2026-11-27T21:00:00Z | psstendershayriver@gov.nt.ca |
| canadabuys | Light on Snow Vehicle (LOSV) Training | Department of National Defence (DND) | CA | open | \[] |  |  | 2026-11-06 | 2026-11-11T04:59:00Z | melanie.crocker@forces.gc.ca |
| ted | Austria – Transport equipment and auxiliary products to t... | Salzburger Verkehrsverbund GmbH | AT | open | \[] |  |  | 2026-11-06 | 2026-12-09T11:00:00Z | leistungsbeschaffung@salzburg-verkehr.at |
| ted | Germany – Printers and plotters – Druck-Multifunktionssys... | Stadt Dülmen | DE | open | \[] |  |  | 2026-11-06 | 2026-12-08T09:00:00Z | zvs@duelmen.de |

One full tender record, exactly as a real run returned it (long text and lists shortened here). From a real run:

```json
{
  "tender_id": "sam.gov:45d94c40c8144f0e97b0eb5d724ff5b4",
  "source": "sam.gov",
  "notice_id": "45d94c40c8144f0e97b0eb5d724ff5b4",
  "title": "Canned Tomato Products for use in Domestic Food Assistance Program",
  "buyer": "AGRICULTURE, DEPARTMENT OF",
  "buyer_unit": "AGRICULTURAL MARKETING SERVICE / USDA  AMS  3J14",
  "country": "US",
  "region": "DC",
  "notice_type": "Combined Synopsis/Solicitation",
  "category": null,
  "status": "open",
  "naics": [
    "311421"
  ],
  "unspsc": [],
  "cpv": [],
  "value": null,
  "currency": null,
  "published_date": "2026-11-06",
  "closes_at": "2026-11-18T19:00:00Z",
  "solicitation_number": "123J1427B0069",
  "url": "https://sam.gov/opp/45d94c40c8144f0e97b0eb5d724ff5b4/view",
  "description": "Amendment 1 - 11/6/2026 - This amendment adds a 10% SDVOSB set-aside to the following materials: 100333 (Tomato Sauce Ca... [3851 more characters]",
  "contact_name": "Latoya Gainey",
  "contact_title": null,
  "contact_email": "latoya.gainey@usda.gov",
  "contact_phone": "910-824-3151",
  "contacts": [
    {
      "type": "primary",
      "name": "Latoya Gainey",
      "title": null,
      "email": "latoya.gainey@usda.gov",
      "phone": "910-824-3151"
    },
    {
      "type": "secondary",
      "name": "Leeanna Balsley",
      "title": null,
      "email": "leeanna.balsley@usda.gov",
      "phone": "9133403152"
    }
  ],
  "source_url": "https://sam.gov/opp/45d94c40c8144f0e97b0eb5d724ff5b4/view",
  "scraped_at": "2026-11-07T16:37:37Z"
}
```

### Use cases

- Contractors and suppliers getting a daily list of new tenders in their NAICS, UNSPSC or CPV codes
- Bid consultants watching US, Canadian and EU tenders for several clients
- Sales teams finding public-sector buyers for what they sell
- Analysts tracking public procurement by buyer, category and value

### Use-case recipes

#### US IT contractor: a daily SAM.gov feed in your NAICS codes

A small IT services firm schedules this daily for SAM.gov only, with its NAICS prefixes and new-only mode on. Each morning, sort the new rows by `closes_at`, read `notice_type` and `description`, and copy `solicitation_number` and `url` into the bid tracker. Two days back covers SAM.gov's one-to-two-day delay.

```json
{
  "sources": [
    "sam.gov"
  ],
  "daysBack": 2,
  "naicsCodes": [
    "5415"
  ],
  "incremental": true,
  "stateKey": "it-services-feed",
  "maxResultsPerSource": 50
}
```

#### EU construction supplier: TED notices in your countries

A construction firm watches TED for works notices from buyers in Germany and Austria. Use `value` and `currency` to size each job, `buyer` and `region` (the buyer's city) to see who is buying, and `closes_at` for the bid deadline. The title is TED's English rendering; the original title follows it in the buyer's language.

```json
{
  "sources": [
    "ted"
  ],
  "daysBack": 1,
  "countries": [
    "DE",
    "AT"
  ],
  "cpvCodes": [
    "45"
  ],
  "maxResultsPerSource": 50
}
```

#### Selling to the Government of Canada

A sales team that sells IT hardware to federal departments pulls CanadaBuys notices in UNSPSC segment 43 once a week. Group the rows by `buyer` and `buyer_unit` to see which departments are buying, and pass `url` and `closes_at` to the account owner. CanadaBuys lists open notices only.

```json
{
  "sources": [
    "canadabuys"
  ],
  "daysBack": 7,
  "unspscCodes": [
    "43"
  ],
  "maxResultsPerSource": 25
}
```

#### Bid consultant: one keyword feed per client, posted to Slack

A consultant runs one saved task per client, each with its own keywords and `stateKey` so the feeds never share memory. With new-only mode on, each client's Slack channel gets the count and the top 10 new tenders after every run. `source` and `country` show at a glance which market each tender is in.

```json
{
  "sources": [
    "sam.gov",
    "canadabuys",
    "ted"
  ],
  "daysBack": 2,
  "keywords": [
    "cybersecurity"
  ],
  "incremental": true,
  "stateKey": "client-acme-cyber",
  "maxResultsPerSource": 25,
  "slackWebhookUrl": "https://hooks.slack.com/services/T000/B000/XXXX"
}
```

### Input

| Field | Type | What it does | Default |
|---|---|---|---|
| `sources` (Sources) | array | Which official sources to read: 'sam.gov' (US federal contract opportunities, public extract), 'canadabuys' (Government of Canada tender notices, open data)... | \["sam.gov", "canadabuys", "ted"] |
| `maxResultsPerSource` (Max results per source) | integer | Upper limit of results per source after filters, newest first; the run status says when it was hit. | 500 |
| `daysBack` (Published in the last N days) | integer | Keep notices published on or after today minus this many days (UTC). | 3 |
| `openOnly` (Open tenders only) | boolean | Keep only notices still open for bids (closing date not passed; award notices and SAM.gov justifications and special notices excluded). | true |
| `keywords` (Keywords) | array | Keep only notices whose title or description contains at least one of these words (case-insensitive), e.g. \['software', 'cybersecurity']. |  |
| `countries` (Countries (ISO codes)) | array | Keep only notices from buyers in these countries, as two-letter ISO codes, e.g. \['US', 'CA', 'DE', 'IE']. |  |

All 14 fields, with examples: see the **Input** tab.

### Use with AI agents (MCP)

MCP (Model Context Protocol) is the open standard that lets AI assistants such as Claude, ChatGPT and Cursor call outside tools. Apify's hosted MCP server at `https://mcp.apify.com/?tools=aurelix/government-tenders-scraper` gives your assistant this Actor only: it fills in the input from your request, runs it and reads the tenders back, at the same per-result price as a run started by hand.

#### Example prompts

- "Find open US federal tenders on SAM.gov posted in the last 3 days under NAICS 5415 and list the title, agency, closing date and link."
- "Show me EU tenders on TED for construction work (CPV 45) from buyers in Germany published in the last 7 days, with buyer, estimated value and deadline."
- "Get open Government of Canada tenders for IT equipment (UNSPSC 43) from CanadaBuys and sort them by closing date."

#### Claude Desktop and claude.ai

**Settings > Connectors > Add custom connector**, name it Apify, paste `https://mcp.apify.com/?tools=aurelix/government-tenders-scraper`, keep the detected OAuth settings, select **Add** and sign in to Apify.

#### Claude Code

```bash
claude mcp add --transport http apify "https://mcp.apify.com/?tools=aurelix/government-tenders-scraper"
```

#### Cursor and VS Code

Add this to `~/.cursor/mcp.json` (Cursor); in VS Code's `.vscode/mcp.json` put the same entry under `"servers"` with `"type": "http"`. Sign in to Apify when asked.

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com/?tools=aurelix/government-tenders-scraper"
    }
  }
}
```

#### ChatGPT

Turn on **Developer mode**, open **Settings > Apps & Connectors > Create**, paste the URL above as the MCP server URL, choose **OAuth** and authorize Apify.

Clients without sign-in send `Authorization: Bearer <YOUR_APIFY_TOKEN>` instead. No Apify account? This Actor supports Apify's agentic payments: an agent can pay per run with a prepaid, spend-capped token, bought with x402 stablecoin payments.

#### n8n AI agent

Give an **AI Agent** node an **MCP Client Tool** with the endpoint `https://mcp.apify.com/?tools=aurelix/government-tenders-scraper` and a Bearer credential holding your Apify token.

### Use it from AI agents (MCP), the API or no-code

#### Copy this to your AI assistant

```text
Use the Apify Actor aurelix/government-tenders-scraper (Government Tenders Scraper) through Apify's MCP server or API. Main input: sources (Sources); maxResultsPerSource (Max results per source). Example input: {"sources": ["sam.gov", "canadabuys", "ted"], "daysBack": 1, "keywords": ["software", "cloud"], "naicsCodes": ["5415"], "unspscCodes": ["4321", "8111"], "cpvCodes": ["72", "48"], "incremental": true}. Each result is one tender with fields such as tender_id, source, notice_id, title, buyer, buyer_unit, country, region. It costs $2.00 per 1,000 tenders on Apify's free plan plus a $0.006 start fee per run, and needs no login.
```

MCP server URL for this Actor: `https://mcp.apify.com/?tools=aurelix/government-tenders-scraper` (setup for each client in the section above).

#### API

Start a run and read the dataset with Apify's REST API or the Python and JavaScript clients:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("aurelix/government-tenders-scraper").call(run_input={'sources': ['sam.gov', 'canadabuys', 'ted'], 'daysBack': 1, 'keywords': ['software', 'cloud'], 'naicsCodes': ['5415'], 'unspscCodes': ['4321', '8111'], 'cpvCodes': ['72', '48'], 'incremental': True})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

#### No-code: schedule it in 3 clicks

Send the results to Google Sheets, Zapier, Make, n8n, Slack or any webhook URL.

1. Fill in the input, then click **Save as a new task**.
2. In the task, click **Schedule** and pick daily or weekly (Apify Schedules).
3. Turn on **Only new tenders since last run** so each run returns only what is new, and paste a Slack or webhook URL into **Slack webhook URL** / **Webhook URL** to get a digest of the new items (count plus the top 10) after every run.

Prefer n8n or Make? Ask in the **Issues** tab and we will share a ready-made workflow for it.

### FAQ

#### Can I scrape government tenders without login?

Yes. It never logs in, so you need no SAM.gov, CanadaBuys or TED account, password or cookies; only a free Apify account to run it.

#### Is there a government tenders API?

You can use this Actor as one. Start it with Apify's REST API or the Python and JavaScript clients and read the results as JSON (see the code above), or call it from an AI agent through MCP.

#### How much does it cost to scrape government tenders?

About $2.01 for 1,000 tenders on Apify's free plan and $1.41 on paid plans, start fee included. The free $5 monthly credit covers about 2,500 tenders.

#### Can I export government tenders data to Excel or Google Sheets?

Yes. Download the results as Excel, CSV, JSON, XML or HTML from the run's **Storage** tab, or send them to Google Sheets with Apify's Google Sheets integration or the API.

#### Is it legal to scrape government tenders?

It reads only public data any logged-out visitor can see: the official open data of SAM.gov, CanadaBuys and TED. It goes at a polite pace, never logs in and never solves CAPTCHAs. It returns tender fields (buyer, codes, value, dates, status, link) and the point of contact the notice publishes for bidders (contracting officer or buyer contact: name, title, email, phone). Data is returned as shown publicly on the source; people can ask for removal by opening an issue on this Actor's Issues tab; if a publisher formally asks us to stop, this Actor will stop. You are responsible for using the data lawfully, incl. anti-spam and privacy laws; this is not legal advice.

#### Do I need a SAM.gov or TED API key?

No. The Actor reads SAM.gov's public Contract Opportunities data extract, the CanadaBuys open dataset and the TED Search API, none of which needs a key.

#### Does it return the contracting officer's name, email and phone?

Yes, as each notice publishes them: SAM.gov's primary and secondary points of contact (name, title, email, phone), the CanadaBuys contact (often a role such as Contract Administrator, with email and phone) and the TED buyer contact point, email and phone. The first contact is in contact_name, contact_title, contact_email and contact_phone; all of them are in contacts. Nothing is guessed: a field the notice leaves blank stays empty.

#### How fresh is it?

TED and CanadaBuys update daily. SAM.gov's public extract is refreshed daily and runs one to two days behind the live site, so use 'days back' of 2 or more for SAM.gov.

#### Why did I get only 500 TED notices?

'Max results per source' defaults to 500, newest first, so a default run is cheap. The run status says 'newest 500 per source only' with the source names whenever the cap cut a source short. Set it higher, or to 0 for everything, and use incremental mode on a daily schedule.

#### How do code filters work?

Give code prefixes: '5415' matches NAICS 541511, 541512 and so on. A notice passes if it matches any NAICS, UNSPSC or CPV prefix you give. Sources that do not publish any code system you gave are skipped (SAM.gov uses NAICS, CanadaBuys UNSPSC, TED CPV).

#### How does 'new since last run' work?

The Actor remembers the tender IDs it has returned for the same sources and filters (or for the state name you set) and returns only unseen ones. IDs are forgotten 60 days after they were last seen.

#### Why is the value empty for many notices?

Value is returned only when the buyer publishes one. SAM.gov publishes values on award notices; CanadaBuys tender notices carry none; many TED notices do. On TED, placeholder values of 0 or 1 are dropped.

#### What am I charged when nothing matches?

Only the start fee. You pay per tender written to the dataset, so a source with no matching notices costs nothing, and a run that returns nothing costs the start fee alone.

#### What happens if one source is down?

The other sources are still read and returned. The run status lists the failed source after 'failed:'. CanadaBuys and TED requests are retried up to four times on connection errors, rate limits and server errors first. The run is marked failed only when every source failed and nothing was returned.

#### Are duplicates removed?

Yes. Each tender appears once per run, keyed by `tender_id` (the source plus its notice ID). With 'Only new tenders since last run' on, tenders returned by earlier runs are left out too.

#### Why does closes_at sometimes have no time?

When the source publishes only a closing date, closes_at stays a plain date (YYYY-MM-DD). Otherwise it is a full ISO 8601 time in UTC; CanadaBuys times are published in Eastern time and converted.

#### How does the countries filter work for each source?

Give two-letter ISO codes. For TED it is the buyer's country, for SAM.gov the place of performance (US when none is given), and CanadaBuys notices are always CA. A TED run with country codes that are not recognised returns no TED notices.

#### How long does a run take?

In our cloud test runs, the default input took about 8 seconds, a full week of CanadaBuys and TED with no cap about 72 seconds, and a 7-day run of all three sources where nothing matched about 203 seconds, because every notice in the window has to be read.

#### How do I keep two new-only feeds apart?

Give each one its own 'Incremental state name'. Without it, the memory is named after the sources and filters (days back excluded), so changing a filter starts a fresh memory and the next run returns every current match again.

#### What happens if I set a maximum charge for the run?

The run stops writing tenders when the limit is reached. In new-only mode, tenders that were not written are not marked as seen, so they come back on the next run.

### Lawful use

- B2B use only: records carry the contracting officer or buyer contact (name, title, email, phone) the government publishes for bidders. Use it for bidding and related business communication only. Data is returned as shown publicly on the source; people can ask for removal by opening an issue on this Actor's Issues tab.
- No spam: contact people only with relevant, individual business messages, identify yourself, and honour every opt-out at once. Bulk unsolicited email built from this data is not allowed.
- You are responsible for complying with the anti-spam and privacy laws that apply to you and to the people you contact, including Canada's CASL, the US CAN-SPAM Act and the EU/UK GDPR (lawful basis, transparency, the right to object).
- Removal requests: open an issue on this Actor's Issues tab naming the person, email address or domain to remove. It is added to our suppression list and honoured within 7 days; from then on matching records are not returned.

### Limits (stated honestly)

- Federal level only for the US and Canada: SAM.gov and CanadaBuys. State, provincial and municipal portals are not covered (several forbid automated access).
- SAM.gov comes from the daily public extract, which runs one to two days behind the live site; attachments and full amendment history are not included, and descriptions longer than 32,000 characters end at 32,000 characters followed by "..." (open the notice link for the full text).
- CanadaBuys includes currently open notices only, so 'open tenders only' off adds no closed Canadian notices.
- TED titles are TED's English rendering ('Country - CPV label - original title'); the original title stays in the buyer's language.
- Look-back is capped at 7 days; use incremental mode on a schedule for a continuous feed.
- Default cap of 500 per source per run, newest first (stated in the run status when hit); keywords match the title and description.

### Related Aurelix tools

Public Aurelix Actors, grouped by the data they collect. All are pay-per-result and need no login.

#### Canada and government data

- **[Canada Building Permits](https://apify.com/aurelix/canada-building-permits-scraper)**: Building permits and development applications from 7 Canadian cities: address, type, status, dates, value, applicant, contractor and Toronto planner contact.
- **[USPTO Trademark API](https://apify.com/aurelix/uspto-trademark-search)**: US trademark search and watch from USPTO: mark, owner or number lookups, new filings, owner, attorney, goods.

#### Jobs and hiring data

- **[Greenhouse Jobs Scraper](https://apify.com/aurelix/greenhouse-jobs-scraper)**: Live jobs from a company's Greenhouse, Lever, Ashby or SmartRecruiters board, with salary and Canadian province tags.
- **[LinkedIn Jobs Country Filter Scraper](https://apify.com/aurelix/linkedin-jobs)**: Public LinkedIn job postings by keyword and country: title, company, location, seniority, job type, salary text, description.
- **[Multiple Job Boards Scraper](https://apify.com/aurelix/multi-job-board-scraper)**: LinkedIn, about 50 company career sites, Remote OK and We Work Remotely jobs in one deduplicated list.
- **[Remote Job Board Scraper API](https://apify.com/aurelix/remote-jobs-scraper)**: Remote OK and We Work Remotely jobs in one deduplicated list with salary, regions and tags.

#### E-commerce and product data

- **[AliExpress Scraper API](https://apify.com/aurelix/aliexpress-product-search)**: AliExpress search results by keyword: price, discount, rating, units sold, ship-from country and sponsored flag.
- **[Amazon New Releases & Best Sellers](https://apify.com/aurelix/amazon-best-sellers)**: Amazon Best Sellers and New Releases top 100 on 10 marketplaces: rank, ASIN, price, rating, rank change.
- **[Shopify Product Export Scraper](https://apify.com/aurelix/shopify-products-scraper)**: Every public product of any Shopify store with variants, SKUs, prices, barcodes, stock counts and collections.

#### Leads and company data

- **[Contact Page Scraper](https://apify.com/aurelix/contact-details-scraper)**: Published company emails, phones, addresses, social pages and team members from a list of company websites.
- **[Decision Maker Finder](https://apify.com/aurelix/decision-maker-finder)**: Founders, CEOs, VPs and department heads from company team pages, with title, seniority and function.
- **[Newly Funded Companies Hiring](https://apify.com/aurelix/funded-companies-hiring)**: Companies that just raised money (SEC Form D), with their open roles and business contacts, as a new-only monitor.
- **[Google Maps Phone Scraper](https://apify.com/aurelix/google-maps-scraper)**: Local business lists from Google Maps: phones, websites, ratings, hours, coordinates; optional website emails and socials.
- **[Recently Funded Companies API](https://apify.com/aurelix/recently-funded-companies)**: US companies that just filed an SEC Form D: amount raised, industry, state, executives, confirmed website.
- **[Tech Stack API](https://apify.com/aurelix/tech-stack-detector)**: CMS, e-commerce platform, analytics, ad pixels, chat, CDN and email provider for each domain you enter.

#### Ad intelligence

- **[Competitor Watch](https://apify.com/aurelix/competitor-watch)**: One report per competitor with only what is new: Meta and TikTok ads, page changes, Shopify products and prices, jobs.
- **[Facebook Ad Library Search & API](https://apify.com/aurelix/facebook-ad-library-scraper)**: Facebook and Instagram business ads from the Meta Ad Library: copy, creatives, landing pages, dates, optional EU reach.
- **[TikTok Ads Library API](https://apify.com/aurelix/tiktok-ads-library-scraper)**: TikTok Ads Library ads for Europe, UK, Switzerland and Turkey with targeting, reach, ad text and landing pages.

#### AI, content and SEO

- **[Google Trends by Region](https://apify.com/aurelix/google-trends-scraper)**: Google Trends interest over time, by region and rising queries for any number of keywords, plus trending searches.
- **[Google Autocomplete API](https://apify.com/aurelix/google-autocomplete-scraper)**: Expands seed keywords into hundreds of real Google and YouTube autocomplete phrases, tagged by search intent.
- **[PDF Table Extraction & PDF to Markdown OCR](https://apify.com/aurelix/pdf-to-markdown)**: Turns linked PDF and Word files into Markdown per page, with tables as JSON rows, RAG chunks and OCR.
- **[Broken Link Crawler & SEO Audit](https://apify.com/aurelix/seo-audit-crawler)**: Audits a whole site: one row per page with SEO checks and broken links, plus a ranked issues summary.
- **[Website to Markdown API](https://apify.com/aurelix/website-to-markdown)**: Crawls a site and returns one row of clean main-content Markdown per page, with title, headings and links.
- **[YouTube Transcript Scraper](https://apify.com/aurelix/youtube-transcript-scraper)**: Returns YouTube video transcripts as text, timed segments and AI chunks, from videos, channels, playlists or searches.

#### More data tools

- **[Tennis Betting Odds Scraper](https://apify.com/aurelix/tennis-odds-scraper)**: Tennis results and upcoming matches with opening and closing odds per bookmaker and implied probabilities.

### Recent changes

- **0.4**: New fields: contact_name, contact_title, contact_email, contact_phone and a contacts list with every point of contact the notice publishes (SAM.gov primary and secondary, CanadaBuys, TED buyer).
- **0.3**: Price lowered to $2.00 per 1,000 tenders ($1.40 on paid plans).
- **0.2**: Description text removed from all sources (privacy); keywords now match the title. Structured fields and the notice link are unchanged.

The full history is on the **Changelog** tab.

### Tested daily

An automated health check runs this Actor every day on a fixed input and checks that at least 11 tenders come back with `tender_id`, `source`, `title`, `status`, `url`, `published_date` filled in; a failed check alerts the maintainer straight away.

### Your feedback

Missing a field, found a bug or need another filter? Open an issue on the **Issues** tab; we aim to answer within a day. If this Actor saved you time, a short review helps other people find it.

# Changelog

This Actor's version history is a separate document: https://apify.com/aurelix/government-tenders-scraper/changelog.md

# Actor input Schema

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

Which official sources to read: 'sam.gov' (US federal contract opportunities, public extract), 'canadabuys' (Government of Canada tender notices, open data), 'ted' (EU Tenders Electronic Daily). Example: \['sam.gov', 'canadabuys'].

## `daysBack` (type: `integer`):

Keep notices published on or after today minus this many days (UTC). Example: 1 for a daily feed, 7 for a weekly one. At most 7; use incremental mode on a schedule for a longer feed.

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

Keep only notices still open for bids (closing date not passed; award notices and SAM.gov justifications and special notices excluded). Turn off to include awards and closed notices.

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

Keep only notices whose title or description contains at least one of these words (case-insensitive), e.g. \['software', 'cybersecurity']. Empty = all.

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

Keep only notices from buyers in these countries, as two-letter ISO codes, e.g. \['US', 'CA', 'DE', 'IE']. SAM.gov uses the place of performance. Empty = all.

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

Keep notices whose NAICS code starts with one of these, e.g. \['5415', '236220']. When any code filter is set, a notice passes if it matches any of the NAICS, UNSPSC or CPV prefixes, and sources that publish none of the given code systems are skipped.

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

Keep notices whose UNSPSC code starts with one of these, e.g. \['4321', '8111'].

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

Keep notices whose CPV code starts with one of these digits, e.g. \['72', '48000000'].

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

Upper limit of results per source after filters, newest first; the run status says when it was hit. TED alone publishes about 3,500 notices a working day. 0 = no limit.

## `includeDescription` (type: `boolean`):

Include the notice description text (SAM.gov, CanadaBuys, TED). Turn off for smaller output.

## `incremental` (type: `boolean`):

Return only notices not returned by a previous run with the same sources and filters. Use with a daily schedule for a new-tenders feed.

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

Name for the 'new since last run' memory. Leave empty to derive it from the sources and filters; set it to keep separate feeds apart, e.g. 'it-services-feed'.

## `slackWebhookUrl` (type: `string`):

After each run, post a short digest to Slack: how many results were saved (new ones only when 'Only new tenders since last run' is on) and the top 10 with links, e.g. https://hooks.slack.com/services/T000/B000/XXXX. Nothing is posted when the run saved nothing. Leave empty to skip.

## `webhookUrl` (type: `string`):

After each run, POST the same digest as JSON (actor, newOnly, count, items = top 10 results, runUrl, text) to any URL, e.g. a Zapier, Make or n8n webhook. Nothing is sent when the run saved nothing. Leave empty to skip.

## Actor input object example

```json
{
  "sources": [
    "sam.gov",
    "canadabuys",
    "ted"
  ],
  "daysBack": 3,
  "openOnly": true,
  "keywords": [],
  "countries": [],
  "naicsCodes": [],
  "unspscCodes": [],
  "cpvCodes": [],
  "maxResultsPerSource": 10,
  "includeDescription": true,
  "incremental": false
}
```

# Actor output Schema

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

All tender notices found in this run, one item per notice.

# 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.gov",
        "canadabuys",
        "ted"
    ],
    "maxResultsPerSource": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("aurelix/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": [
        "sam.gov",
        "canadabuys",
        "ted",
    ],
    "maxResultsPerSource": 10,
}

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

```

## MCP server setup

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