# French Public Tenders Scraper: BOAMP Alerts & DECP Winners (`rigel/fr-marches-publics-intel`) Actor

Daily alerts for new French public tenders (BOAMP) by keyword, department and notice type, plus who wins contracts (DECP) in your CPV codes, with SIRENE data on each winner and a winners leaderboard. Official open data, Licence Ouverte 2.0. No personal data. From $0.003 per notice.

- **URL**: https://apify.com/rigel/fr-marches-publics-intel.md
- **Developed by:** [Rigel](https://apify.com/rigel) (community)
- **Categories:** Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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

**Get new French public tenders (BOAMP) every morning and see who wins the contracts in your market (DECP), from official open data with no personal data.**

### What is French Public Tenders & Awards Intel?

This Actor is a **BOAMP scraper and French public procurement API** built on official open data. It does two jobs:

1. **`tenders` mode: find French public tenders to bid on.** It searches new BOAMP notices (*Bulletin officiel des annonces des marchés publics*) by keyword, department, notice type and BOAMP descriptor. It can return only notices that are still open. With `onlyNew` and an Apify Schedule, you get a **daily tender alert** that only returns notices you have not seen yet.
2. **`awards` mode: see who wins French public contracts.** It reads awarded contracts from the consolidated DECP data (*données essentielles de la commande publique*), filtered by CPV prefix, department, date and minimum amount. Each winner is checked against the official company register (SIRENE), and you get a **winners leaderboard**: who wins most often in your market, total declared amount, number of distinct buyers.

It reads public APIs, not web pages, so it is not blocked by layout changes on boamp.fr.

### Use cases

- **SMEs and freelancers looking for tenders (*appels d'offres*)**: a daily list of new notices for "nettoyage" in Lyon and Paris, sent to e-mail, Slack, Make, Zapier or n8n.
- **Competitor research**: "Who wins IT contracts (CPV 72) in Gironde, and with which buyers?"
- **Bid consultants**: monitor several clients' keywords with one named monitor per client.
- **B2B sales teams selling to public-sector suppliers**: build a list of companies that regularly win contracts in a CPV family.
- **Market sizing**: order of magnitude of public spending per CPV family and department.

### What data do you get?

| Mode | Fields |
|---|---|
| `tenders` | BOAMP id, title, buyer, departments, publication date, response deadline, notice type, procedure, contract type, BOAMP descriptors, notice family, link to boamp.fr |
| `awards` | contract title, buyer and buyer SIRET, department, CPV code, declared amount, notification date, procedure, contract type, duration, winner SIRET and name, winner company data (SIREN, NAF code, size, headcount band, active or closed, creation date, legal form) |
| winners leaderboard | SIREN, name, number of contracts, total declared amount, CPV codes, last win, number of distinct buyers |

Every record carries its source and licence.

### How to use it

1. Pick `tenders` (new notices) or `awards` (contracts already awarded).
2. Add your filters: keywords, departments (`33`, `69`, `2A`…), CPV prefixes (`72` = IT services, `4542` = joinery…).
3. For a daily alert: turn on `onlyNew`, give the monitor a name, and add an Apify Schedule (for example every day at 7:00).
4. Export the dataset as JSON, CSV or Excel, or call the Actor through the Apify API.

#### Input example: daily tender alert

```json
{
  "mode": "tenders",
  "keywords": ["nettoyage"],
  "departments": ["69", "75"],
  "publishedWithinDays": 7,
  "onlyNew": true,
  "monitorName": "nettoyage-lyon-paris"
}
```

#### Input example: who wins IT contracts in Gironde

```json
{
  "mode": "awards",
  "cpvPrefixes": ["72"],
  "departments": ["33"],
  "awardedSince": "2026-01-01",
  "minAmountEur": 20000,
  "maxItems": 200
}
```

### Output example

Real tender returned by a public run on 17 October 2026 (input: `"keywords": ["informatique"]`, `"maxItems": 1`):

```json
{
  "type": "tender",
  "id": "26-100506",
  "title": "FOURNITURE DE MATERIELS INFORMATIQUES ET PRESTATIONS ASSOCIEES",
  "buyer": "SYNDICAT INTERCOMMUNAL DU BASSIN D'ARCACHON",
  "departments": ["33"],
  "publishedAt": "2026-10-16",
  "deadline": "2026-11-16T12:00:00+00:00",
  "noticeType": "Avis de marché",
  "procedure": "Procédure Ouverte",
  "contractTypes": ["FOURNITURES"],
  "descriptors": [{ "code": "162", "label": "Informatique (matériel)" }],
  "family": "Marchés entre 90 k€ et seuils européens",
  "url": "https://www.boamp.fr/pages/avis/?q=idweb:26-100506",
  "source": "Source : DILA – BOAMP, Licence Ouverte 2.0",
  "charged": true
}
```

Real award, read from DECP with the Actor's code on 17 October 2026 (CPV 72, department 33, since 2026-01-01, at least €20,000; abridged):

```json
{
  "type": "award",
  "title": "MULTIMÉDIA - AUDIT ET EXPERTISE DE L’INTÉGRATION",
  "buyer": "COMMUNE DE CENON (MAIRIE)",
  "buyerDepartment": "33",
  "cpv": "72150000",
  "amountEur": 10000000,
  "notifiedAt": "2026-10-07",
  "procedure": "Appel d'offres ouvert",
  "durationMonths": 48,
  "winnerSiret": "44208228500051",
  "winnerName": "SCENARCHIE",
  "winnerCompany": {
    "siren": "442082285",
    "naf": "71.12B",
    "category": "PME",
    "headcountBand": "11",
    "active": true,
    "createdAt": "2002-05-02"
  },
  "source": "Source : DECP consolidées (data.gouv.fr), Licence Ouverte 2.0"
}
```

The €10,000,000 above is the amount declared by the buyer. For a framework agreement it is usually a ceiling, not money spent (see Limitations).

### How much does it cost?

Pay per event: you pay only for results returned. Prices in USD:

| Event | What you get | Price |
|---|---|---|
| `tender` | one BOAMP notice | $0.003 |
| `award` | one awarded contract whose winner is a verifiable company, enriched | $0.005 |
| `winner-summary` | one row of the winners leaderboard | $0.005 |
| `apify-actor-start` (Apify platform event) | charged once per run, per GB of memory (default 512 MB = 1 event) | $0.00005 |

Examples (plus the start event): 100 tender notices cost $0.30. 200 awards plus a 25-row leaderboard cost $1.00 + $0.125 = $1.125.

**Free rows:** masked awards (natural person, non-diffusible, unknown or not identified by a SIRET), duplicates and errors are free and marked `"charged": false`.

The leaderboard is **on by default** (`winnersSummary`) and is computed on up to 500 matching contracts, which can be more than the award rows returned. Turn it off if you do not need it. When your spending limit is reached, the Actor stops; it never charges beyond the limit (minimum limit: $0.05).

### FAQ

#### Is there an official BOAMP API?

Yes. DILA publishes BOAMP as open data on an Opendatasoft API. This Actor uses that API, adds filters (open notices only, "only new" memory), and joins it with DECP and SIRENE so you do not have to write that code.

#### Can I get a daily e-mail of new French tenders?

Yes. Set `onlyNew: true` and a `monitorName`, then schedule the Actor daily. Only notices you have not received yet are returned (and charged). Connect the run to e-mail, Slack, Make, Zapier or n8n with Apify integrations.

#### What is a CPV code?

The Common Procurement Vocabulary classifies what is bought (e.g. `72` IT services, `45` construction works, `90` cleaning and environmental services). A prefix matches every code that starts with it.

#### Does it cover tenders above EU thresholds (TED)?

BOAMP publishes French notices, including many above EU thresholds. This Actor does not query TED directly.

#### Can I use the data commercially?

BOAMP, DECP and SIRENE data are published under Licence Ouverte / Open Licence 2.0, which allows commercial reuse with attribution. The attribution is included on every record.

#### Does it return personal data?

No. Winners who are natural persons or sole traders, non-diffusible entities, and winners not identified by a SIRET are masked. Company officers are never collected.

### Limitations

- **DECP amounts are declared by buyers.** For framework agreements they are often the maximum amount, so treat totals as an order of magnitude.
- DECP coverage depends on what buyers publish. A missing contract in DECP will be missing here.
- `openOnly` excludes notices with no deadline: a missing deadline is not treated as open.
- The company API (API Recherche d'entreprises) is limited to about 7 requests/s on the service and about 30 requests/s per network (ASN), shared with other clients. The Actor stays at 6/s with a cache. If a lookup fails, the winner is masked and the award row is free.
- More than 20 CPV × department combinations: the shorter list is queried in full and the other side is filtered locally. Nothing is dropped; the run log says so.

### Data sources and licences

| Source | Publisher | Licence |
|---|---|---|
| [BOAMP open data](https://boamp-datadila.opendatasoft.com) | DILA | Licence Ouverte / Open Licence 2.0 |
| [DECP consolidées](https://www.data.gouv.fr/datasets/donnees-essentielles-de-la-commande-publique-consolidees-format-tabulaire) | data.gouv.fr | Licence Ouverte / Open Licence 2.0 |
| [API Recherche d'entreprises](https://recherche-entreprises.api.gouv.fr) | DINUM (INSEE and RNE data) | Licence Ouverte / Open Licence 2.0 |

### Related Actors

- [French Supplier Check](https://apify.com/rigel/fr-supplier-check): due-diligence card (status, BODACC insolvency notices, public contracts) for any winner.
- [French SIREN/SIRET Bulk Enricher](https://apify.com/rigel/fr-siren-enricher): enrich a list of companies with official SIRENE data.

### En français

**Veille BOAMP quotidienne et analyse des attributaires DECP, à partir des données ouvertes officielles.**

- Mode `tenders` : nouveaux avis BOAMP filtrés par mots-clés, départements, type d'avis et descripteurs, avec option « avis encore ouverts » et alerte quotidienne (`onlyNew` + planification Apify).
- Mode `awards` : marchés attribués (DECP) par préfixe CPV, département, date et montant minimum, avec les données SIRENE de l'attributaire et un classement des entreprises qui gagnent le plus.
- Prix : 0,003 $ par avis, 0,005 $ par marché attribué, 0,005 $ par ligne du classement (activé par défaut). Les lignes masquées, doublons et erreurs sont gratuits.
- Limites : les montants DECP sont déclarés par les acheteurs (souvent des plafonds d'accords-cadres). Aucune donnée personnelle : personnes physiques, entrepreneurs individuels et entités non diffusibles sont masqués.
- Sources : DILA (BOAMP), data.gouv.fr (DECP), API Recherche d'entreprises (DINUM), toutes sous Licence Ouverte 2.0.

# Actor input Schema

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

tenders = new notices; awards = who won which contracts.

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

Full-text search in notice subject (OR).

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

French department codes, e.g. 69, 75, 2A.

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

BOAMP 'nature' codes, e.g. APPEL_OFFRE, ATTRIBUTION, RECTIFICATIF. Empty = all.

## `descriptorCodes` (type: `array`):

BOAMP descriptor codes (e.g. 415 = Télésurveillance).

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

Published within (days).

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

Only notices whose response deadline is still in the future. Award notices (ATTRIBUTION) and rectifications are excluded unless you list them in notice types. A missing deadline is not treated as open.

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

Use with a Schedule for daily alerts.

## `monitorName` (type: `string`):

Named key-value store used to remember seen tenders. 1–63 characters: letters, digits, '.', '\_' or '-'.

## `cpvPrefixes` (type: `array`):

e.g. 72 (IT services), 4542 (joinery).

## `awardedSince` (type: `string`):

YYYY-MM-DD. Default: last 365 days. Any other format stops the run with an error.

## `minAmountEur` (type: `integer`):

Min amount € (awards).

## `enrichWinners` (type: `boolean`):

Add SIRENE company details for each winner. Privacy masking (natural persons, sole traders, non-diffusible or unverifiable winners) always applies, even when this is off.

## `winnersSummary` (type: `boolean`):

Add a winners leaderboard. On by default. Each row is a winner-summary event at $0.005, computed on up to 500 matching contracts (wider than the award rows returned). Framework-agreement amounts are often ceilings.

## `topWinners` (type: `integer`):

Leaderboard size.

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

Max items.

## Actor input object example

```json
{
  "mode": "tenders",
  "keywords": [
    "maintenance",
    "informatique"
  ],
  "publishedWithinDays": 7,
  "openOnly": true,
  "onlyNew": false,
  "cpvPrefixes": [
    "4542"
  ],
  "enrichWinners": true,
  "winnersSummary": true,
  "topWinners": 25,
  "maxItems": 200
}
```

# Actor output Schema

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

Default dataset, overview view selected.

# 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": [
        "maintenance",
        "informatique"
    ],
    "cpvPrefixes": [
        "4542"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("rigel/fr-marches-publics-intel").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": [
        "maintenance",
        "informatique",
    ],
    "cpvPrefixes": ["4542"],
}

# Run the Actor and wait for it to finish
run = client.actor("rigel/fr-marches-publics-intel").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": [
    "maintenance",
    "informatique"
  ],
  "cpvPrefixes": [
    "4542"
  ]
}' |
apify call rigel/fr-marches-publics-intel --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,rigel/fr-marches-publics-intel"
        }
    }
}
```

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/eSy9TqthrpO3nLiEV/builds/gU8w7o4v9W0aUXOhZ/openapi.json
