# DECP Win Intelligence (`dr1ms/decp-win-intelligence`) Actor

French public-procurement (DECP) market intelligence: competitor dossiers, market benchmarks and buyer histories over the consolidated data.gouv.fr dataset, served from a normalized cache.

- **URL**: https://apify.com/dr1ms/decp-win-intelligence.md
- **Developed by:** [Adrien](https://apify.com/dr1ms) (community)
- **Categories:** Other, SEO tools, Lead generation
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $50.00 / 1,000 competitor-dossiers

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## DECP Win Intelligence — who won French public contracts

**Query France's public-procurement award data (DECP) as clean, structured JSON.**
One identifier in — a company SIREN, a buyer SIRET, or a CPV code plus a department —
one auditable JSON answer out: competitors, price benchmarks, buyer behaviour.

The award data itself is open and free. What this Actor sells is the hard part:
turning a **3.1-million-row, trap-filled consolidated file** into answers you can
trust, with a **per-record quality score** and every source market listed for audit.

---

### What you get in 30 seconds

Three query modes, each returning **one JSON object** (agent- and spreadsheet-friendly):

| Mode | You give | You get back |
|---|---|---|
| **competitor-dossier** | a company `siren` | its markets, top buyers, CPV mix, yearly trend, weighted win-rate |
| **market-benchmark** | a `cpv` prefix + a `departement` | price distribution (q1 / median / q3), top suppliers, top buyers on that segment |
| **buyer-history** | a buyer `siret` | its markets, recurring CPV, favourite suppliers, monthly seasonality |

Every response carries a `qualite` block (how many amounts were kept vs set aside,
and why), a `data_version` date, and the **complete list of source market IDs** so
any number can be re-checked against the open data.

---

### Concrete use cases

#### 1. Competitive analysis — "how dominant is this company, and where?"

Call `competitor-dossier` on a SIREN. Example: **ENEDIS (SIREN `444608442`)**.

- **130 markets**, total **€3,291,593,920** — but the **median market is €16,272.87**.
  The gap is not a bug: `montant_top1_part = 0.996` tells you a **single €3.28 bn
  market makes up 99.6 % of the total**. You see the concentration instead of being
  misled by the headline sum.
- **Weighted win-rate = 0.69 %** across **60 CPV×department segments** — an
  approximate *share of awards where the company is actually active* (definition and
  honest limits below), with a `segments_top` breakdown so you can read exactly which
  CPV division and department drive it.
- **Recurring buyers**: EPFL Béarn Pyrénées (`53042890300013`, 40 markets), Région
  Île-de-France (`23750007900312`, 11 markets), and so on — a ready-made account map.

#### 2. Price benchmarks — "what does this kind of contract go for, in this area?"

Call `market-benchmark` with a CPV prefix and a department. Example: **CPV `71`
(engineering & architecture services) in Corse-du-Sud (`2A`)**.

- **518 awards**, price distribution **q1 €45,655 · median €97,874 · q3 €300,000**
  (min €1,400, max €6,435,734). Sentinel and missing amounts are excluded from these
  statistics and reported separately (`n_ecartes`), so the quartiles are clean.
- **Top suppliers on the segment**: Cabinet Sibella & Associés (`532822202`, 26
  markets), Artelia (`444523526`, 19), Rocca e Terra (`792993602`, 19).
- **Top buyers**: Collectivité de Corse (`20007695800012`, 261 markets) far ahead of
  the rest.

> Benchmarks are always scoped to **one CPV prefix × one department** — a national
> aggregate is deliberately out of scope (see *The three modes*).

#### 3. B2B commercial signals — "how does this buyer buy, and from whom?"

Call `buyer-history` on a buyer SIRET. Example: a French local-authority buyer,
SIRET `21690271800016`.

- **150 markets**, total **€61,096,071**, median **€91,437**.
- **Favourite suppliers**: Orange (`380129866`, 6 markets), Parcs et Sports
  (`329263164`, 5), Engie Énergie Services (`552046955`, 4).
- **Seasonality**: award activity peaks in **May and June (20 markets each)** — useful
  timing for outreach and pipeline planning.

#### 4. Unit queries for AI agents

Each mode is a **single deterministic call → single JSON dict**. No pagination to
stitch, no HTML to scrape, no login. That shape is built for tool-use: an agent passes
one identifier and gets a bounded, well-typed object it can reason over. See
*Using it from an AI agent* below.

---

### The three modes

The Apify **input** `mode` enum is hyphenated (`competitor-dossier`,
`market-benchmark`, `buyer-history`); the **output** `mode` field mirrors the domain
function name with an underscore (`competitor_dossier`, …). All examples below are
**real answers from the current build**, arrays truncated for readability (never a
structural field removed — the shapes are copied verbatim).

#### `competitor-dossier`

**Input**

```json
{ "mode": "competitor-dossier", "siren": "444608442", "top_n": 20 }
````

**Output** (arrays cut; the three modes have genuinely different result shapes)

```jsonc
{
  "mode": "competitor_dossier",
  "parametres": { "siren": "444608442", "top_n": 20 },
  "data_version": "2026-07-23",
  "enrichable_siren": "444608442",
  "resultat": {
    "nb_marches": 130,
    "montant_total": 3291593920.23,
    "montant_median": 16272.87,
    "repartition_cpv": [
      { "cpv": "45100000", "nb_marches": 20, "montant_total": 39866.92, "part_marches": 0.153846 },
      { "cpv": "09310000", "nb_marches": 13, "montant_total": 1134706.05, "part_marches": 0.1 }
      // … up to top_n CPV codes
    ],
    "acheteurs_recurrents": [
      { "acheteur_id": "53042890300013", "acheteur_nom": "ETABLISSEMENT PUBLIC FONCIER LOCAL BEARN PYRENEES", "nb_marches": 40, "montant_total": 61268.61, "recurrent": true }
      // … recurrent = true when nb_marches >= 2
    ],
    "win_rate": {
      "valeur": 0.006911,
      "definition": "weighted mean of award shares per (CPV division x department) segment where the holder is present",
      "n_segments": 60,
      "n_marches_titulaire_dans_segments": 127,
      "n_marches_hors_segment": 3,
      "segments_top": [
        { "cpv2": "45", "departement": "64", "n_marches_titulaire": 37, "n_marches_segment": 9838, "part": 0.003761 }
        // … most-contributing segments
      ]
    },
    "tendance_annuelle": [
      { "annee": 2024, "nb_marches": 27, "montant_total": 6550723.09 }
      // … one row per notification year
    ]
  },
  "qualite": {
    "n_marches_total": 130,
    "n_lignes_etat_courant": 131,
    "score_qualite_moyen": 0.99,
    "montant": { "n_retenus": 130, "n_ecartes": 0, "par_raison": {} },
    "win_rate_marches_hors_segment": 3,
    "date_notification_exclue": 0,
    "montant_top1_part": 0.996138
  },
  "sources": { "n_uid": 130, "uid": ["120001029000122021100015168000", "130001902003082022110005847000"] }
  // sources.uid is the COMPLETE, unbounded list of source markets — 130 here — for audit
}
```

#### `market-benchmark`

**Input**

```json
{ "mode": "market-benchmark", "cpv": "71", "departement": "2A", "top_n": 20 }
```

Optional `annee_min` / `annee_max` restrict the window to notification years
(e.g. `"annee_min": 2022, "annee_max": 2024`); omit both to cover all years.

**Output** — note this result carries `distribution_montants` **with** `total` and
`moyenne`, and has **no** root `montant_total`:

```jsonc
{
  "mode": "market_benchmark",
  "parametres": { "cpv_prefix": "71", "zone": "2A", "periode": null, "top_n": 20 },
  "data_version": "2026-07-23",
  "resultat": {
    "nb_attributions": 518,
    "distribution_montants": {
      "n_retenus": 517, "total": 158956854.39, "moyenne": 307460.07,
      "q1": 45655.0, "mediane": 97874.0, "q3": 300000.0, "min": 1400.0, "max": 6435734.0
    },
    "top_titulaires": [
      { "titulaire_siren": "532822202", "titulaire_nom": "CABINET SIBELLA ET ASSOCIES", "nb_marches": 26, "montant_total": 15627803.4 },
      { "titulaire_siren": "444523526", "titulaire_nom": "ARTELIA", "nb_marches": 19, "montant_total": 6693070.03 }
      // … up to top_n
    ],
    "top_acheteurs": [
      { "acheteur_id": "20007695800012", "acheteur_nom": "COLLECTIVITE DE CORSE", "nb_marches": 261, "montant_total": 93828321.74 }
      // … up to top_n
    ]
  },
  "qualite": {
    "n_marches_total": 518,
    "n_lignes_etat_courant": 852,
    "score_qualite_moyen": 0.98,
    "montant": { "n_retenus": 517, "n_ecartes": 1, "par_raison": { "manquant": 1 } },
    "zone_regle": "department derived from normalised lieuExecution, postal-code -> department fallback",
    "zone_couverture_globale": { "n_total": 2008019, "n_avec_departement": 1871103, "pct_couverture": 93.18 }
  },
  "sources": { "n_uid": 518, "uid": ["058811670000152020002301280000", "060804770000752022xgsg30000000"] }
}
```

#### `buyer-history`

**Input**

```json
{ "mode": "buyer-history", "siret": "21690271800016", "top_n": 20 }
```

**Output** — carries a root `montant_total` **and** a `distribution_montants`, but the
distribution here has **no** `total`/`moyenne`:

```jsonc
{
  "mode": "buyer_history",
  "parametres": { "siret": "21690271800016", "top_n": 20 },
  "data_version": "2026-07-23",
  "resultat": {
    "nb_marches": 150,
    "montant_total": 61096071.18,
    "distribution_montants": { "n_retenus": 150, "q1": 45000.0, "mediane": 91437.3, "q3": 235000.0, "min": 48.0, "max": 7916968.0 },
    "cpv_recurrents": [
      { "cpv": "03120000", "nb_marches": 10, "montant_total": 507000.0, "part_marches": 0.066667, "recurrent": true }
      // … up to top_n
    ],
    "titulaires_favoris": [
      { "titulaire_siren": "380129866", "titulaire_nom": "ORANGE (SERVICES DIVERS)", "nb_marches": 6, "montant_total": 808000.0 }
      // … up to top_n
    ],
    "saisonnalite_mensuelle": [
      { "mois": 5, "nb_marches": 20 }, { "mois": 6, "nb_marches": 20 }
      // … fixed 12 months
    ],
    "notifications_datees": 150
  },
  "qualite": {
    "n_marches_total": 150,
    "n_lignes_etat_courant": 155,
    "score_qualite_moyen": 0.98,
    "montant": { "n_retenus": 150, "n_ecartes": 0, "par_raison": {} },
    "date_notification_exclue": 0,
    "montant_top1_part": 0.129582
  },
  "sources": { "n_uid": 150, "uid": ["2169027180001620", "216902718000162018180400"] }
}
```

> **Input validation is strict and typed.** `siren` = 9 digits, `siret` = 14 digits
> (leading zeros are real and preserved — SIRETs are strings, never integers), `cpv` =
> 2–8 digits, `departement` = a metropolitan code (`01`–`95` except `20`), Corsica
> `2A`/`2B`, or an overseas code. A valid-but-absent identifier is **not** an error: it
> returns a structured empty dossier, never a crash.

***

### Why this is worth paying for (the honest version)

**The data is free.** France publishes *Données Essentielles de la Commande Publique*
(DECP) as open data. If you download the consolidated file yourself, here is what you
actually receive — and why raw numbers off it will mislead you:

- **3,141,176 rows, but only 1,738,976 distinct markets.** One market spreads across
  many rows: **118,771 markets are co-awarded** (several holders) and **307,753 carry
  at least one amendment** (avenant, up to ~80 versions). Naïvely summing the `montant`
  column double-, triple-, or eighty-folds real spend. This Actor resolves each market
  to its **current version** and counts each market **once**.
- **Duplicate markets across sources.** The file aggregates **61 upstream feeds**;
  **12,449 markets appear in 2 or more of them** (up to 7). Deduplication has to happen
  at the *market* level — the sources never share a row key.
- **~14,500 malformed supplier SIRETs** (wrong length), plus thousands more failing the
  Luhn checksum. **Leading zeros are load-bearing** (46,000+ rows would corrupt if read
  as integers, as the published schema wrongly suggests).
- **Sentinel and junk amounts.** The 99.9th percentile amount is *exactly*
  `999,999,999`; the maximum is `99,999,999,999.99` (**1,237 rows ≥ €10 bn** — nine-fill
  placeholders, not real money). There are **2,138 negative** amounts and **62,270
  zeros**. Left in, they wreck every average.
- **Un-normalised categories.** The identifier-type field has **16 spellings** where the
  spec allows 7; `nature` has 13; the location-type field has 18 — `SIRET`/`Siret`/
  `siret`, `Marché`/`MARCHE`/`marché`, and so on. Filter on the raw text and you silently
  drop matches.

**What you pay for is the normalisation and the derived metrics** — plus a guarantee we
never quietly delete a bad record. Every anomaly becomes an **auditable flag and a score
penalty**, never a silent drop. Numbers you can act on, and a paper trail behind each one.

***

### The quality block and the per-record score

Normalisation runs at the row level and attaches, to **every record**:

- `quality_flags` — the auditable list of everything abnormal about that row
  (e.g. `montant_sentinelle`, `siret_format_invalide`, `divergence_intersource`,
  `date_notification_aberrante`).
- `quality_score` = `clamp(1 − Σ penalties, 0, 1)` — a single number in `[0, 1]`.
  Heavier problems cost more: a sentinel or negative amount costs 0.30, a malformed
  SIRET 0.25, a leading duplicate-source divergence 0.15, a mere casing variant 0.03.

Each query answer then rolls these up in its `qualite` block:

- `score_qualite_moyen` — average record score over the markets used.
- `montant` = `{ n_retenus, n_ecartes, par_raison }` — how many amounts fed the
  statistics, how many were set aside, and **why**, broken down by reason (`nul`,
  `manquant`, `negatif`, `sentinelle`). An excluded amount is **counted and reported**,
  never dropped: `n_retenus + n_ecartes = n_marches_total`, always.
- `montant_top1_part` (competitor & buyer modes) — the share of `montant_total` held by
  the single largest market. A blunt outlier signal with no hidden threshold: ENEDIS
  reads `0.996` (one market dominates), the buyer above reads `0.130` (spread out).
- `zone_regle` / `zone_couverture_globale` (benchmark mode) — how the department was
  derived and what fraction of the whole dataset carries a derivable department
  (**93.18 %**; the rest is reported, never guessed).

***

### Data freshness

- **Source**: *Données essentielles de la commande publique consolidées (format
  tabulaire)* on **data.gouv.fr**, produced by the **Colmo / decp.info** pipeline
  (Colin Maudry). Licence: **Licence Ouverte v2.0**.
- **Refresh**: the upstream file is rebuilt roughly **daily** (early morning UTC); the
  Actor's cache is refreshed on the same cadence by an internal maintenance run.
- **Traceability**: every response carries a **`data_version`** date, and
  `sources.uid` lists **every** source market — so any answer can be pinned to a build
  and re-verified against the open data.

***

### FAQ

**How reliable are the numbers?**
Ten `competitor-dossier` dossiers were compared against **decp.info** (the free
reference explorer): **10/10 within a tight tolerance** — market counts within ≤ 1.7 %
(≤ 2 markets), amounts **7/7 within ±2 %** (4 identical to the cent), top buyer matching
6/7 (the 7th a legitimate tie). A second, independent government source (the DAJ
Opendatasoft dataset) confirmed **containment on all 10** (its validated subset ⊆ ours,
no inversions). **Honest limit**: decp.info runs the *same* Colmo pipeline as our source,
and DAJ is an upstream subset — so this proves **faithful reproduction and consistency,
not independent ground truth**. No strictly independent oracle exists for free; we say so
rather than overclaim.

**Why are some amounts excluded from the statistics but still shown?**
Because dropping them silently would be dishonest. A `montant` that is null, zero,
negative, or a nine-fill sentinel (`999,999,999`, `≥ €10 bn`) is **excluded from totals,
means, medians and quartiles** — those figures would otherwise be meaningless — but it is
**counted and itemised** in `qualite.montant.par_raison`. You always see how many records
were set aside and for what reason.

**What exactly is the "win-rate"? Is it a bid win probability?**
**No — and we are explicit about it.** The DECP only record contracts that were
*awarded*; lost bids are invisible, so a true tender win-rate is **not computable** from
this data. Our `win_rate` is a **proxy for market share**: the average, over the CPV
division × department segments where the company is active, of its share of awards in
each segment, **weighted by how many markets it holds there**. Read it as "on the
segments where it operates, what share of awards does it typically win," never as "what
% of tenders it wins." A `segments_top` list ships alongside so you can see the drivers.

**What does `montant_top1_part` mean?**
The fraction of a company's (or buyer's) total amount contributed by its single largest
market. It is a raw outlier flag, with no judgement threshold applied. ENEDIS's `0.996`
warns you that €3.28 bn of a €3.29 bn total is **one** market — the median market is
€16,273. The total is real, but it is not "typical," and this field makes that visible.

**Can I get the raw underlying records, not just the aggregates?**
The product is designed around one aggregated JSON dossier per query. Line-by-line
delivery of the raw award records is available as a separate, opt-in metered event when
you need the full detail: set `"include_records": true` in the input (volume capped by
`records_limit`), and each delivered record is billed as its own event.

***

### Using it from an AI agent

Each mode is a **single call returning a single, bounded JSON object** — no pagination,
no scraping, no session state — which is exactly the shape an LLM tool-call wants.
Billing is **pay-per-event** (you pay per query, described below), which fits agent
budgets that meter individual actions. The Actor is built to be callable by autonomous
agents and via MCP-style tool use; the specific agentic-payment eligibility flag is being
finalised on the platform side and is not asserted here.

Typical agent loop: resolve a company to its **SIREN** → `competitor-dossier` →
read `enrichable_siren` from the response → hand it to a company-enrichment tool (below)
→ combine award history with legal/financial profile.

***

### Related Actors

- **[dr1ms/french-company-enricher](https://apify.com/dr1ms/french-company-enricher)** —
  every `competitor-dossier` response exposes a root **`enrichable_siren`** field (the
  subject SIREN). Feed it straight into the French Company Enricher to attach legal
  status, NAF activity, headcount and financials to the award history you just pulled.
  Award behaviour on one side, company identity on the other.
- **Tender Triage** — the **upstream** half of the same workflow. Tender Triage looks at
  the *calls for tenders* (the opportunities still open, who might bid); **DECP Win
  Intelligence looks at who actually won** once the contracts were awarded. Use them
  together to go from "what's on the market" to "who takes it."

***

### Pricing

**Pay-per-event: you pay per query, nothing for idle time.** Each of the three query
modes is a metered event; retrieving the raw underlying records (opt-in) is a separate
per-record event. There is no subscription and no charge for the daily cache refresh.

Final per-event prices are being set with the maintainer and are **not published here
yet**. There is no SLA and no real-time streaming — the data follows the daily
open-data release cadence.

***

### Bookmark this Actor

If French public-procurement intelligence is on your roadmap, **bookmark this Actor**
so you can find it again — and it helps others discover it on the Store. Questions or a
segment you want covered? Open an issue on the Actor.

# Actor input Schema

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

Which operation to run. / Opération à exécuter. Query modes read a cache that 'refresh-cache' must build first.

## `siren` (type: `string`):

competitor-dossier: 9-digit SIREN of the company to profile. / SIREN (9 chiffres) du titulaire. Example: 444608442 (ENEDIS).

## `cpv` (type: `string`):

market-benchmark: 2 to 8 digit CPV code prefix (first 2 = CPV division). / Préfixe CPV (2 à 8 chiffres). Example: 45 (construction works).

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

market-benchmark: département of execution — 01-95 (except 20), Corsica 2A/2B, overseas 971-978 / 984-989. / Département d'exécution. Example: 35 (Ille-et-Vilaine).

## `annee_min` (type: `integer`):

market-benchmark (optional): earliest notification year. Provide both years or neither. / Année de début (les deux ou aucune).

## `annee_max` (type: `integer`):

market-benchmark (optional): latest notification year. / Année de fin.

## `siret` (type: `string`):

buyer-history: 14-digit SIRET of the public buyer. / SIRET (14 chiffres) de l'acheteur. Example: 21750001600019 (Ville de Paris).

## `top_n` (type: `integer`):

Size of the ranked lists (CPV, buyers, awardees, win-rate segments). Default 20, range 1-100. / Taille des classements (défaut 20).

## `include_records` (type: `boolean`):

competitor-dossier / buyer-history only: also deliver the raw line-to-line attribution records (billed per record, capped). Default off. / Livrer aussi le détail ligne à ligne (facturé par enregistrement, plafonné).

## `records_limit` (type: `integer`):

Hard cap on delivered/charged attribution records when include\_records is on. Default 5000, max 20000. / Plafond d'enregistrements livrés.

## Actor input object example

```json
{
  "mode": "competitor-dossier",
  "siren": "444608442",
  "cpv": "45",
  "departement": "35",
  "annee_min": 2022,
  "annee_max": 2024,
  "siret": "21750001600019",
  "top_n": 20,
  "include_records": false,
  "records_limit": 5000
}
```

# Actor output Schema

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

The aggregated JSON dossier (one item per query: parametres, data\_version, resultat, qualite, sources.uid) and, when include\_records=true, the raw attribution records.

# 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 = {
    "siren": "444608442",
    "cpv": "45",
    "departement": "35",
    "siret": "21750001600019"
};

// Run the Actor and wait for it to finish
const run = await client.actor("dr1ms/decp-win-intelligence").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 = {
    "siren": "444608442",
    "cpv": "45",
    "departement": "35",
    "siret": "21750001600019",
}

# Run the Actor and wait for it to finish
run = client.actor("dr1ms/decp-win-intelligence").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "siren": "444608442",
  "cpv": "45",
  "departement": "35",
  "siret": "21750001600019"
}' |
apify call dr1ms/decp-win-intelligence --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=dr1ms/decp-win-intelligence",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "DECP Win Intelligence",
        "description": "French public-procurement (DECP) market intelligence: competitor dossiers, market benchmarks and buyer histories over the consolidated data.gouv.fr dataset, served from a normalized cache.",
        "version": "0.1",
        "x-build-id": "47Qp9DUNV3igiYmJS"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/dr1ms~decp-win-intelligence/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-dr1ms-decp-win-intelligence",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/dr1ms~decp-win-intelligence/runs": {
            "post": {
                "operationId": "runs-sync-dr1ms-decp-win-intelligence",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/dr1ms~decp-win-intelligence/run-sync": {
            "post": {
                "operationId": "run-sync-dr1ms-decp-win-intelligence",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "mode"
                ],
                "properties": {
                    "mode": {
                        "title": "Mode",
                        "enum": [
                            "competitor-dossier",
                            "market-benchmark",
                            "buyer-history",
                            "refresh-cache"
                        ],
                        "type": "string",
                        "description": "Which operation to run. / Opération à exécuter. Query modes read a cache that 'refresh-cache' must build first.",
                        "default": "competitor-dossier"
                    },
                    "siren": {
                        "title": "Awardee SIREN",
                        "pattern": "^[0-9]{9}$",
                        "type": "string",
                        "description": "competitor-dossier: 9-digit SIREN of the company to profile. / SIREN (9 chiffres) du titulaire. Example: 444608442 (ENEDIS)."
                    },
                    "cpv": {
                        "title": "CPV prefix",
                        "pattern": "^[0-9]{2,8}$",
                        "type": "string",
                        "description": "market-benchmark: 2 to 8 digit CPV code prefix (first 2 = CPV division). / Préfixe CPV (2 à 8 chiffres). Example: 45 (construction works)."
                    },
                    "departement": {
                        "title": "Département",
                        "type": "string",
                        "description": "market-benchmark: département of execution — 01-95 (except 20), Corsica 2A/2B, overseas 971-978 / 984-989. / Département d'exécution. Example: 35 (Ille-et-Vilaine)."
                    },
                    "annee_min": {
                        "title": "Period start year",
                        "minimum": 2000,
                        "maximum": 2100,
                        "type": "integer",
                        "description": "market-benchmark (optional): earliest notification year. Provide both years or neither. / Année de début (les deux ou aucune)."
                    },
                    "annee_max": {
                        "title": "Period end year",
                        "minimum": 2000,
                        "maximum": 2100,
                        "type": "integer",
                        "description": "market-benchmark (optional): latest notification year. / Année de fin."
                    },
                    "siret": {
                        "title": "Buyer SIRET",
                        "pattern": "^[0-9]{14}$",
                        "type": "string",
                        "description": "buyer-history: 14-digit SIRET of the public buyer. / SIRET (14 chiffres) de l'acheteur. Example: 21750001600019 (Ville de Paris)."
                    },
                    "top_n": {
                        "title": "Top-N",
                        "minimum": 1,
                        "maximum": 100,
                        "type": "integer",
                        "description": "Size of the ranked lists (CPV, buyers, awardees, win-rate segments). Default 20, range 1-100. / Taille des classements (défaut 20).",
                        "default": 20
                    },
                    "include_records": {
                        "title": "Include raw attribution records",
                        "type": "boolean",
                        "description": "competitor-dossier / buyer-history only: also deliver the raw line-to-line attribution records (billed per record, capped). Default off. / Livrer aussi le détail ligne à ligne (facturé par enregistrement, plafonné).",
                        "default": false
                    },
                    "records_limit": {
                        "title": "Max attribution records",
                        "minimum": 1,
                        "maximum": 20000,
                        "type": "integer",
                        "description": "Hard cap on delivered/charged attribution records when include_records is on. Default 5000, max 20000. / Plafond d'enregistrements livrés.",
                        "default": 5000
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
