# DECP Scraper: French Public Contracts Awarded (Marches Publics) (`dltik/decp-fr-scraper`) Actor

Scrape 650K+ awarded French public contracts (DECP) — buyer SIRET, winner SIRET, amount, CPV, procedure. Filter by date, CPV, montant, departement. For B2G prospection, market intel, lead gen. $5/1K records.

- **URL**: https://apify.com/dltik/decp-fr-scraper.md
- **Developed by:** [Walid](https://apify.com/dltik) (community)
- **Categories:** Business, Lead generation, Marketing
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.00005 / actor start

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

## DECP Scraper — 650K+ Awarded French Public Contracts API

⭐ **Bookmark this actor → [apify.com/dltik/decp-fr-scraper](https://apify.com/dltik/decp-fr-scraper)** — Apify ranks by bookmarks, so it directly drives the visibility of this scraper. **One click. No signup beyond your existing Apify account.**

> Scrape **650K+ awarded French public contracts** from **DECP** (Données Essentielles de la Commande Publique — Arrêté du 22 décembre 2022). Get the **buyer SIRET, winner SIRET, contract amount in euros, notification date, CPV code, procedure, duration, location** for every public contract awarded by French communes, départements, regions, hospitals, ministries and public agencies. Filter by **date, CPV, montant, département, buyer, winner**. **No OAuth, no API key, no monthly subscription.**

### What makes this scraper different

| Feature | This DECP scraper | TED-only scrapers | Generic procurement scrapers |
|---|:---:|:---:|:---:|
| French municipal contracts (sub-EU threshold) | ✅ 650K+ | ❌ | ⚠️ shallow |
| Buyer SIRET (joinable to Sirene / Pappers) | ✅ | ❌ | ❌ |
| Winner SIRET (titulaire 1/2/3) | ✅ | ❌ partial | ❌ |
| Contract amount in euros (`montant`) | ✅ structured | ⚠️ rare | ❌ |
| CPV prefix filter (`72`, `45`, `85`...) | ✅ | ✅ | ⚠️ |
| Montant min/max filter | ✅ | ❌ | ❌ |
| Département filter (prefix on `lieu_execution`) | ✅ | ❌ | ❌ |
| Innovative-contract toggle (`marcheinnovant`) | ✅ | ❌ | ❌ |
| Green-procurement toggle (`considérations env.`) | ✅ | ❌ | ❌ |
| Per-record charge (no actor-start fee) | ✅ | ❌ inflated | ✅ |
| Concessions dataset toggle | ✅ | ❌ | ❌ |

### What can this scraper do?

- 🇫🇷 **650K+ awarded French public contracts** from the official DECP feed (Arrêté 22/12/2022, live)
- 🏛️ **Every type of public buyer** — communes, départements, régions, CHU, ministères, agences, syndicats intercommunaux
- 💰 **Structured montant in euros** — filter sub-threshold MAPA, mid-range marchés, mega-contrats by exact value
- 🏢 **Buyer and winner SIRET** — directly joinable to [Sirene](https://apify.com/dltik/pappers-sirene-scraper) for instant company enrichment
- 🎯 **CPV prefix filter** — `72` for IT services, `45` for construction, `85` for health, `50410000` for metrology, etc.
- 🌿 **Green / innovation toggles** — `marcheinnovant=oui` + `considerationsenvironnementales` for ESG-aware prospection
- 🗺️ **Lieu d'exécution code** — INSEE / postcode / département for geo-targeted bidding
- 🚀 **No auth, no quota** — HTTP-only, Opendatasoft Explore v2.1, datacenter proxy optional

### What data can you extract per contract?

| Field | Description |
|---|---|
| `contract_id` | DECP contract identifier (`id`) |
| `objet` | Free-text object of the contract |
| `nature` | Marché / Accord-cadre / Marché subséquent |
| `montant_eur` | Awarded amount, in EUR (numeric) |
| `date_notification` | Date the contract was notified to the winner (YYYY-MM-DD) |
| `annee_notification` | Year extracted from `date_notification` (numeric) |
| `date_publication_donnees` | Date the DECP record was published |
| `acheteur_siret` | 14-digit SIRET of the public buyer |
| `acheteur_nom_resolved` | Buyer name (null — join Sirene to enrich) |
| `titulaire_siret` | 14-digit SIRET of the primary winner (titulaire 1) |
| `titulaire_type_identifiant` | `SIRET`, `TVA`, `UE`, `HORS-UE` |
| `titulaire_nom_resolved` | Winner name (null — join Sirene to enrich) |
| `titulaires_all` | All co-titulaires (1-3) with id + type |
| `code_cpv` | Common Procurement Vocabulary code (8 digits + check) |
| `cpv_label` | CPV human label (null — combine with a CPV reference table) |
| `procedure` | "Procédure adaptée", "Appel d'offres ouvert", "Marché négocié"... |
| `duree_mois` | Contract duration in months |
| `lieu_execution_code` | Execution location code (INSEE / postcode / dept) |
| `lieu_execution_type` | "Code postal", "Code commune", "Code département"... |
| `forme_prix` | Unitaire / Forfaitaire / Mixte |
| `offres_recues` | Number of offers received (proxy for competitiveness) |
| `considerations_sociales` | Social-clauses status |
| `considerations_environnementales` | Environmental-clauses status |
| `marche_innovant` | Boolean — innovation procurement flag |
| `ccag` | CCAG reference (Cahier des Clauses Administratives Générales) |
| `modalites_execution`, `techniques`, `types_prix` | Contract-shape details |
| `origine_france_pct`, `origine_ue_pct` | Stated French / EU origin share |
| `sous_traitance_declaree` | Sub-contracting flag |
| `type_groupement_operateurs` | Joint-venture grouping type |
| `source_publication` | DECP source feed (e.g. "DGFIP – PES MARCHÉ") |
| `source_dataset` | `decp-2022-marches-valides` or `decp-2022-concessions-valides` |
| `source_url` | data.economie.gouv.fr permalink |
| `scraped_at` | UTC timestamp of the run |

### How to scrape DECP in 5 steps

1. **[Create a free Apify account](https://apify.com/sign-up)** — no credit card required.
2. **Open [DECP Scraper](https://apify.com/dltik/decp-fr-scraper)** on Apify Store.
3. **Set your filters** — for example `cpv=["72"]` (IT), `departement="75"` (Paris), `notifiedSince="today-180"`, `montantMin=50000`.
4. **Pick `maxResults`** — start at 20 to validate, scale to 5,000 once happy. Hard cap 10,000 per run (Opendatasoft window).
5. **Click Start** — clean JSON in seconds, exportable to CSV / JSON / Excel from the Apify dataset UI.

### How much does it cost to scrape DECP contracts?

**PAY_PER_EVENT — $0.005 per contract scraped** ($5 per 1,000 results). Failed / empty runs not charged. Optional AI analysis is billed separately at **$0.01 per analyzed contract** (`record-analyzed`, paid plans only).

| Run size | Contracts | Apify cost | Time |
|---|---|---|---|
| Quick test | 20 | $0.10 | ~3s |
| Standard | 200 | $1.00 | ~15s |
| Deep | 1,000 | $5.00 | ~1 min |
| Massive | 5,000 | $25.00 | ~5 min |

Add `includeConcessions=true` to also pull the small concessions dataset (~600 records, long-term public service delegations).

### AI analysis (premium, opt-in)

Set `analyzeContracts: true` to add an `ai` object to every awarded contract: a plain-language `summary` (what was bought, from whom), the extracted `deliverables`, and a `recommended_action` — `prospect` (this buyer/winner is worth contacting), `watch` (recurring contract likely to be re-tendered — track its expiry), or `skip`. Provide a `businessProfile` to also get a `relevance_score` (0-100) with a one-line reason, turning the 650K-row DECP archive into a ranked prospecting and market-intelligence list.

DECP is post-award data, so the angle is **market intelligence, not bidding**: find who won contracts like yours (to prospect the buyer for the next one, or the winner for subcontracting). Requires a paid Apify plan; billed as a separate `record-analyzed` event. Without a paid plan the scrape still runs, without the `ai` field. For live open calls-for-tender to bid on, use the sister actor [BOAMP Scraper](https://apify.com/dltik/boamp-fr-scraper).

### Input parameters

| Parameter | Type | Default | Description |
|---|---|---|---|
| `query` | string | — | Free-text search in `objet` |
| `cpv` | array | `[]` | CPV codes, prefix-matched. `["72"]` = all IT, `["45","85"]` = construction OR health |
| `acheteurSiret` | string | — | Exact buyer SIRET (14 digits) |
| `titulaireSiret` | string | — | Exact winner SIRET — every contract a given company has won |
| `notifiedSince` | string | — | ISO date `YYYY-MM-DD` or `today-N` |
| `notifiedUntil` | string | — | ISO date `YYYY-MM-DD` |
| `montantMin` | integer | — | Minimum contract value (EUR) |
| `montantMax` | integer | — | Maximum contract value (EUR) |
| `lieuExecutionCode` | string | — | Exact location code (INSEE / postcode / dept as published) |
| `departement` | string | — | Two-digit dept prefix on `lieu_execution_code` |
| `procedure` | string | — | Partial match — `adaptee`, `ouvert`, `restreint`, `negocie` |
| `marcheInnovant` | bool | `false` | Keep only `marcheinnovant=oui` |
| `considerationsEnv` | bool | `false` | Keep contracts with environmental clauses |
| `includeConcessions` | bool | `false` | Also pull the concessions dataset (~600 rows) |
| `maxResults` | integer | `50` | 1–10000 |
| `analyzeContracts` | bool | `false` | AI summary + deliverables + prospect/watch/skip per contract (premium, paid plans) |
| `businessProfile` | string | — | Your company in 1–2 sentences → adds a 0–100 relevance score when AI is on |
| `proxyConfig` | object | none | Apify proxy (rarely needed) |

### Output example

```json
{
  "type": "marche",
  "source_dataset": "decp-2022-marches-valides",
  "contract_id": "202424.02",
  "objet": "Prestations relatives au contrôle métrologique des instruments de pesage",
  "nature": "Marché",
  "montant_eur": 40000.0,
  "date_notification": "2024-04-25",
  "annee_notification": 2024,
  "date_publication_donnees": "2024-04-26",
  "acheteur_siret": "25020879000098",
  "titulaire_siret": "34974317900203",
  "titulaire_type_identifiant": "SIRET",
  "titulaires_all": [
    { "id": "34974317900203", "type": "SIRET" }
  ],
  "code_cpv": "50410000-2",
  "procedure": "Procédure adaptée",
  "duree_mois": 48,
  "lieu_execution_code": "02000",
  "lieu_execution_type": "Code postal",
  "forme_prix": "Unitaire",
  "offres_recues": 1,
  "considerations_sociales": "Pas de considération sociale",
  "considerations_environnementales": "Pas de considération environnementale",
  "marche_innovant": true,
  "ccag": "Fournitures courantes et services",
  "source_publication": "DGFIP – PES MARCHÉ",
  "source_url": "https://data.economie.gouv.fr/explore/dataset/decp-2022-marches-valides/table/?q=202424.02",
  "scraped_at": "2026-06-20T14:32:01Z"
}
```

### Use cases

- 🎯 **B2G prospection pipeline** — feed your CRM with every new contract matching your CPV + département; never miss a public buyer who's actively spending in your category.
- 📊 **Win/loss intelligence** — pull every contract awarded to a competitor SIRET (`titulaireSiret`) to learn which buyers they own and what amounts they win at.
- 💼 **Account-based marketing** — pull every contract awarded by a target buyer SIRET (`acheteurSiret`) — see exactly which prestataires they trust and what they spend on each line.
- 🏛️ **Public-spend dashboards** — aggregate `montant_eur` per `code_cpv` × `annee_notification` × `departement` for sector-level dashboards.
- 🌿 **ESG / green-procurement intel** — filter `marcheInnovant=true` or `considerationsEnv=true` to track public buyers leading on innovation and environmental clauses.
- 🤖 **Public-tender bot** — combine with [BOAMP Scraper](https://apify.com/dltik/boamp-fr-scraper) (live calls for tender) for full upstream-to-downstream coverage of the French public procurement funnel.

### Use the actor via API

**Python:**

```python
import requests

run = requests.post(
    "https://api.apify.com/v2/acts/dltik~decp-fr-scraper/run-sync-get-dataset-items",
    headers={"Authorization": "Bearer YOUR_APIFY_TOKEN", "Content-Type": "application/json"},
    json={
        "cpv": ["72"],
        "departement": "75",
        "notifiedSince": "today-180",
        "montantMin": 100000,
        "maxResults": 200,
    },
).json()
print(f"Scraped {len(run)} contracts")
```

**curl:**

```bash
curl -X POST "https://api.apify.com/v2/acts/dltik~decp-fr-scraper/run-sync-get-dataset-items" \
  -H "Authorization: Bearer YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"cpv":["45"],"departement":"13","notifiedSince":"2024-01-01","montantMax":1000000,"maxResults":500}'
```

### FAQ

**What is DECP exactly?**
DECP (Données Essentielles de la Commande Publique) is the legal obligation, since 2018 and reinforced by the Arrêté du 22/12/2022, for every French public buyer to publish the essential data of every awarded contract above €40K (sometimes lower, depending on the buyer category). Data is centralised on `data.economie.gouv.fr`.

**How fresh is the data?**
DECP has a structural 2–6 month publication lag — public buyers consolidate then publish in batches. For real-time call-for-tenders, combine with [BOAMP Scraper](https://apify.com/dltik/boamp-fr-scraper). For EU-threshold tenders, see TED Europa scrapers.

**Is every French public contract included?**
Compliance is enforced unevenly — ~85% of communes publish, ~15% of small communes still don't. Large buyers (régions, ministères, CHU) are very well covered.

**Why is `acheteur_nom_resolved` null?**
DECP only publishes the buyer SIRET, not the name. Join the SIRET with our [Pappers Sirene Scraper](https://apify.com/dltik/pappers-sirene-scraper) or [MCP Pappers server](https://apify.com/dltik/mcp-server-pappers) to enrich with the buyer's legal name, address, and effectif.

**Will I get blocked?**
The `data.economie.gouv.fr` Opendatasoft instance has no anti-bot and no published rate limit. We've never been blocked at moderate volume. Datacenter proxy is the default.

**Can I export to CSV?**
Yes — the Apify dataset UI exports to JSON, CSV, XLSX, RSS and HTML out of the box.

***

⭐ **Found this DECP Scraper useful? [Bookmark it](https://apify.com/dltik/decp-fr-scraper)** — Apify ranks actors by bookmarks, so it's the strongest single signal for Store visibility. One click.

### Other scrapers by dltik

| Actor | What it does | Price |
|---|---|---|
| [BOAMP Scraper](https://apify.com/dltik/boamp-fr-scraper) | French national calls for tender (upstream of DECP) | $0.005/tender |
| [TED Europa Scraper](https://apify.com/dltik/ted-europa-scraper) | EU-threshold public procurement (above DECP) | $0.005/tender |
| [Pappers Sirene Scraper](https://apify.com/dltik/pappers-sirene-scraper) | 26M French companies — enrich SIRETs from DECP | $0.001/result |
| [Pappers MCP Server](https://apify.com/dltik/mcp-server-pappers) | French company data for AI agents (Claude / GPT) | $0.01/tool-call |
| [BODACC Scraper](https://apify.com/dltik/bodacc-fr-scraper) | French commercial court announcements | $0.003/record |
| [Annuaire Administration FR](https://apify.com/dltik/annuaire-administration-fr-scraper) | French gov agencies & contacts | $0.003/org |
| [HATVP Scraper](https://apify.com/dltik/hatvp-fr-scraper) | French elected officials' financial declarations | varies |
| [France Travail Scraper](https://apify.com/dltik/francetravail-scraper) | 700K+ FR public job offers | $0.0015/job |

License: MIT · Author: [dltik](https://apify.com/dltik)

# Actor input Schema

## `query` (type: `string`):

Free-text search in the contract object (objet). Examples: 'voirie', 'restauration scolaire', 'logiciel'. Leave empty to get every contract matching the other filters.

## `cpv` (type: `array`):

Common Procurement Vocabulary codes. Prefix-matched against codecpv. Examples: '72' (IT), '45' (construction), '85' (health), '50410000' (metrology). Multiple = OR.

## `acheteurSiret` (type: `string`):

Exact 14-digit SIRET of the public buyer (mairie, departement, region, CHU, ministry...). Example: '21750001600019' (Mairie de Paris).

## `titulaireSiret` (type: `string`):

Exact 14-digit SIRET of the awarded company (titulaire). Use to track every public contract a given company has won.

## `notifiedSince` (type: `string`):

ISO date (YYYY-MM-DD). Only contracts notified on or after this date. Tip: 'today-30' for the last 30 days. DECP has a typical 2-6 month publication lag — use 6-12 month windows for active prospection.

## `notifiedUntil` (type: `string`):

ISO date (YYYY-MM-DD). Only contracts notified on or before this date. Combine with 'Notified since' for a window.

## `montantMin` (type: `integer`):

Minimum contract value in euros (montant). Useful to skip micro-contracts. Example: 100000 = ignore contracts under 100k.

## `montantMax` (type: `integer`):

Maximum contract value in euros. Useful for sub-threshold (MAPA) targeting where smaller B2G specialists win.

## `lieuExecutionCode` (type: `string`):

INSEE code, postcode, or departement code. The DECP feed mixes types — use the raw code as published. Examples: '75056' (Paris commune), '75001' (Paris postcode), '75' (Paris departement).

## `departement` (type: `string`):

Two-digit French department code, prefix-matched against lieuexecution_code. Examples: '75' (Paris), '13' (Bouches-du-Rhone), '2A' (Corse-du-Sud). Most municipalities publish a 5-digit postcode that starts with the departement.

## `procedure` (type: `string`):

Partial match on the procedure type. Examples: 'adaptee' (Procedure adaptee / MAPA), 'ouvert' (Appel d'offres ouvert), 'restreint' (Appel d'offres restreint), 'negocie'.

## `marcheInnovant` (type: `boolean`):

Filter on marcheinnovant=oui. Use to find R\&D-flavoured contracts (innovation procurement).

## `considerationsEnv` (type: `boolean`):

Keep only contracts with explicit environmental considerations (green public procurement / RSE).

## `includeConcessions` (type: `boolean`):

Also pull contracts from the decp-2022-concessions-valides dataset (~600 records, long-term public service delegations). Off by default — the main marches dataset already covers 650K+ rows.

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

Maximum contracts to return (newest first). Hard cap of 10000 per run (Opendatasoft window limit) — narrow with filters for large searches. Aliases accepted: 'limit', 'max'. Each result is charged at the per-event price — start small to validate.

## `analyzeContracts` (type: `boolean`):

Enrich each awarded contract with an AI 'ai' object: a plain-language summary (what was bought, from whom), the concrete deliverables, and a recommended action (prospect / watch / skip). Add 'Business profile' below to also get a 0-100 relevance score per contract - turns the DECP archive into a ranked prospecting/market-intelligence list. Requires a paid Apify plan; billed as a separate 'record-analyzed' event. If not on a paid plan the scrape still runs without analysis.

## `businessProfile` (type: `string`):

One or two sentences describing what your company sells or does, e.g. 'Entreprise de nettoyage industriel et proprete, region PACA' or 'ESN specialisee data et IA, 60 personnes'. When set (and AI analysis is on), each contract gets a relevance_score (0-100) and a one-line reason for how relevant it is to prospect or watch. Leave empty to get summaries only.

## `proxyConfig` (type: `object`):

Optional Apify proxy. The data.economie.gouv.fr endpoint has no anti-bot — proxy is rarely useful unless your egress IP is rate-limited.

## Actor input object example

```json
{
  "cpv": [],
  "marcheInnovant": false,
  "considerationsEnv": false,
  "includeConcessions": false,
  "maxResults": 50,
  "analyzeContracts": false,
  "proxyConfig": {
    "useApifyProxy": false
  }
}
```

# 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("dltik/decp-fr-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 = {}

# Run the Actor and wait for it to finish
run = client.actor("dltik/decp-fr-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 '{}' |
apify call dltik/decp-fr-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,dltik/decp-fr-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/KPC7077nkkgav40xN/builds/8ZFiwz0eorkkaJkfC/openapi.json
