# MATCH.ONE French Tender Radar (`spherical_distinction/french-tender-radar`) Actor

Find fresh French public tenders (BOAMP + EU TED) and IT contracts coming up for renewal (DECP) for web, software, TMA/hosting, automation, data and more. Scored, deduplicated, with deadline, budget and source link. No personal data.

- **URL**: https://apify.com/spherical_distinction/french-tender-radar.md
- **Developed by:** [Baron Sigma](https://apify.com/spherical_distinction) (community)
- **Categories:** Lead generation, Business
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $30.00 / 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.

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

## MATCH.ONE French Tender Radar

An Apify Python actor that searches French public procurement notices in BOAMP and TED, matches them against technology niches, removes expired opportunities, scores matches, and writes a deduplicated dataset. It only makes read-only requests to the free public BOAMP and TED APIs. It does not submit tenders or collect personal contact data.

### Inputs

| Input | Meaning | Default |
| --- | --- | --- |
| `niches` | One or more of `web`, `software`, `automation`, `data`, `cyber`, `hosting_tma`, `marketing`, `elearning`, `crm`, `ged`, `ux_access` | `web`, `software`, `hosting_tma` |
| `departments` | Optional department codes, such as `75` or `69` | `[]` |
| `regions` | Optional region names | `[]` |
| `minBudget` | Minimum disclosed estimated budget in EUR | `0` |
| `minScore` | Minimum match score from 0 to 100 | `0` |
| `days` | Publication lookback, 1–60 days | `7` |
| `sources` | `boamp`, `ted`, or both | both |
| `maxResults` | Maximum dataset rows, 1–2000 | `200` |
| `includeRenewals` | Include upcoming DECP contract expiries | `false` |
| `renewalMonthsMin` | Earliest estimated expiry window in months (1–36) | `3` |
| `renewalMonthsMax` | Latest estimated expiry window in months (1–36) | `9` |

Scores combine niche phrase or TED CPV match, disclosed budget, remaining response time, and department/region filter evidence. Expired notices are removed. Unknown or nonpositive budgets are `null`.

### Example output

```json
{
  "source": "BOAMP",
  "id": "26-123456",
  "title": "Refonte du site internet de la collectivité",
  "buyer": "Ville de Exemple",
  "department": "75",
  "deadline": "2026-11-05",
  "budget_eur": 85000,
  "niche": "web",
  "score": 65,
  "reason": "niche phrase match: site internet, refonte du site; estimated budget disclosed; 22 days until deadline",
  "url": "https://www.boamp.fr/pages/avis/?q=idweb:26-123456",
  "published": "2026-10-14",
  "attribution": "Source: BOAMP – DILA, Licence Ouverte/Open Licence"
}
```

### Pricing

You pay only for results, with no platform usage charge:

- **$0.03 per tender result** (one scored BOAMP or TED notice).
- **$0.05 per renewal result** (one DECP contract likely to be re-tendered, only when `includeRenewals` is on).

For reference, a run with the default input (7-day lookback; web, software and hosting/TMA niches) returned 74 tenders on 15 Oct 2026, about $2.22. Use `maxResults` or a maximum charge limit on the run to cap your spend; the actor stops cleanly when the limit is reached.

### Data sources and licences

- **BOAMP**, published by DILA, via the BOAMP Opendatasoft Explore API. Attribution: `Source: BOAMP – DILA, Licence Ouverte/Open Licence`.
- **TED**, via the anonymous TED Search API of the Publications Office of the European Union. Attribution: `Source: TED – Publications Office of the EU, © European Union, reuse authorised`.
- **DECP**, via the Opendatasoft DECP valid-contract dataset. Renewal rows estimate the contract end from notification date plus duration and include the previous award amount. Buyer names may be enriched from the free French company search API; enrichment is optional and failures leave buyer blank. Attribution: `Source: DECP – data.economie.gouv.fr, Licence Ouverte / Etalab; amount is the previous contract award`.

### Limitations and privacy

Budget estimates are often missing or expressed in formats the source does not expose consistently. BOAMP and TED can contain overlapping notices; the actor deduplicates by normalized title and buyer, which can also merge distinct notices with identical values. Department and region metadata are not consistently available, so geographic filters only affect scores when source data provides a match; TED results do not currently provide department mapping. DECP renewal estimates use a 30-day month approximation and its previous award amount is not a current budget quote. Matching is heuristic and should be checked against the source. No contact names, email addresses, phone numbers, or contract-holder fields are requested or emitted.

# Actor input Schema

## `niches` (type: `array`):

Technology procurement niches to match

## `departments` (type: `array`):

Optional French department codes, such as 75 or 69

## `regions` (type: `array`):

Optional region names

## `minBudget` (type: `integer`):

Minimum estimated budget in EUR; 0 keeps tenders with unknown budget.

## `minScore` (type: `integer`):

Minimum match score (0-100).

## `days` (type: `integer`):

Look back this many days for published tenders.

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

Tender sources to query.

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

Maximum number of rows to output.

## `includeRenewals` (type: `boolean`):

Include upcoming expiries from DECP awarded-contract data

## `renewalMonthsMin` (type: `integer`):

Earliest estimated contract end, in months from today.

## `renewalMonthsMax` (type: `integer`):

Latest estimated contract end, in months from today.

## Actor input object example

```json
{
  "niches": [
    "web",
    "software",
    "hosting_tma"
  ],
  "departments": [],
  "regions": [],
  "minBudget": 0,
  "minScore": 0,
  "days": 7,
  "sources": [
    "boamp",
    "ted"
  ],
  "maxResults": 200,
  "includeRenewals": false,
  "renewalMonthsMin": 3,
  "renewalMonthsMax": 9
}
```

# Actor output Schema

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

No description

## `resultsAll` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

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

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("spherical_distinction/french-tender-radar").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("spherical_distinction/french-tender-radar").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call spherical_distinction/french-tender-radar --silent --output-dataset

```

## MCP server setup

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

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/zjpRt3EvXvJIdUFX6/builds/49taEw0MUukoowJ0W/openapi.json
