# France Tender Matcher - Public Tenders for Your Company (SIRET) (`zkrobotics/tender-matcher`) Actor

Enter a SIRET: get open French public tenders that fit that company, scored 0-100 from the contracts it already won (official BOAMP data), with the reasons, its existing clients and its likely competitors. For sales teams, bid managers and consultants.

- **URL**: https://apify.com/zkrobotics/tender-matcher.md
- **Developed by:** [ZK Robotics](https://apify.com/zkrobotics) (community)
- **Categories:** Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $20.00 / 1,000 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

### What does France Tender Matcher do?

**Type a company's SIRET, get the open French public tenders it has the best chance to win.**

Most tender tools ask you to configure keywords and CPV codes, then send you hundreds of notices to sort by hand. This Actor works the other way round: it first looks at **the public contracts the company has already won** (official BOAMP award notices, last 36 months), learns what it sells, to whom and where, then **scores every open tender from 0 to 100** and tells you why.

**FR :** saisissez le SIRET d'une entreprise : le robot étudie les marchés publics qu'elle a déjà remportés, puis classe les appels d'offres ouverts qui lui ressemblent, avec la raison de chaque note, ses clients existants et ses concurrents probables.

#### Who is it for?

- 🧑‍💼 **Sales and bid teams** who want a short, ranked list instead of a firehose of notices.
- 🧾 **Tender consultants** preparing a weekly selection for each client: one run per client SIRET.
- 🔎 **Analysts** comparing where a company wins and where it could win next.

### How the matching works

1. **Company identity** from the official register (API Recherche d'entreprises): name, activity code (NAF), department.
2. **Track record** from BOAMP award notices, recognised by SIRET or by name. Notices in the national format do not fill the official "winner" field, so the Actor reads the winner in the text of the notice. This finds many more past contracts than tools relying on that field alone.
3. **Profile**: the purchase categories (CPV codes) it wins, its public clients, its departments, its usual contract size.
4. **Scoring of open tenders** in its departments:

| Signal | Points |
|---|---|
| Same type of purchase (CPV class) as contracts already won | 45 |
| Same CPV family / requested CPV / keyword | 30–35 |
| Buyer is an existing client | +30 |
| Company's department, or a department where it already won | +8 to +10 |
| Estimated value in its usual range | +10 |
| Deadline in less than 7 days | −10 |

No track record yet? The Actor falls back on the company's trade (NAF code mapped to precise CPV classes: a heating engineer gets heating and ventilation tenders, not every building site).

### Example output

Real result for SPIE CityNetworks (SIRET 434 085 395 00508), October 2026:

```json
{
  "matchScore": 83,
  "title": "Modifications de la signalisation pour l'extension du remisage Poudrette",
  "buyer": "SYTRAL Mobilités - TRANSPORT",
  "matchReasons": [
    "même type d'achat que 59 marché(s) déjà gagné(s) (CPV 4523)",
    "client existant (2 marché(s) déjà gagné(s) chez cet acheteur)",
    "dans un département où l'entreprise a déjà gagné"
  ],
  "deadline": "2026-10-16T14:00:00+00:00",
  "buyerHistory": {
    "awardsLast24Months": 100,
    "likelyCompetitors": [{"name": "Poma", "contracts": 2}, {"name": "COLAS RAIL", "contracts": 2}]
  },
  "url": "https://www.boamp.fr/pages/avis/?q=idweb:26-89456"
}
```

The full company profile (contracts won, CPV codes, clients, departments, value range, recent wins) is saved in the run's key-value store as `PROFILE`.

### How to use

1. Enter a **SIRET or SIREN** and click **Start**. Everything else is optional.
2. Read the ranked table: score, reasons, deadline, link to the tender documents.
3. Schedule it **weekly** for each company you follow and send the results to e-mail, Slack, Google Sheets or your CRM through Apify integrations.

### How much does it cost?

You pay per result returned (see the Pricing tab). A run returns 30 tenders by default, ranked best first, so you control the cost with **Max results** and **Minimum score**.

### FAQ

**Is the data official?** Yes: BOAMP (DILA) and the French company register API, both open data under Licence Ouverte Etalab 2.0.

**Does it work for a company that never won a public contract?** Yes, through its activity code. Add keywords or CPV codes to sharpen the results.

**Why did a tender get a low score?** Each result lists its reasons. Lower **Minimum score** to see more, or add **Keywords**.

**Other Actors by ZK Robotics** that work well with this one: *France Public Tenders (BOAMP)* for raw tender alerts, *France Contract Awards* to follow competitors, *France Companies Leads* and *France Town Halls Contacts* for prospecting.

**Missing something?** Open an issue on the Actor page.

### Source and licence

BOAMP - DILA and API Recherche d'entreprises (INSEE, INPI, DINUM), Licence Ouverte Etalab 2.0. Not affiliated with the French administration.

# Actor input Schema

## `companyId` (type: `string`):

9 ou 14 chiffres. Le robot étudie les marchés publics déjà gagnés par cette entreprise.

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

Vide = département de l'entreprise et départements où elle a déjà gagné des marchés (5 au plus).

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

Bonus pour les avis dont le titre ou la description contient l'un de ces mots.

## `extraCpvPrefixes` (type: `array`):

Pour viser un nouveau marché, ex. 4533 (chauffage, ventilation).

## `publishedSinceDays` (type: `integer`):

Seuls les appels d'offres encore ouverts sont examinés.

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

45 = même type d'achat que des marchés déjà gagnés ; +30 si client existant.

## `includeCompetitors` (type: `boolean`):

Pour chaque avis : fournisseurs habituels de l'acheteur pour ce type d'achat.

## `historyMonths` (type: `integer`):

Période des marchés gagnés pris en compte pour le profil.

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

Les meilleures notes d'abord.

## Actor input object example

```json
{
  "companyId": "43408539500508",
  "publishedSinceDays": 30,
  "minScore": 30,
  "includeCompetitors": true,
  "historyMonths": 36,
  "maxItems": 30
}
```

# Actor output Schema

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

No description

## `profile` (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 = {
    "companyId": "43408539500508"
};

// Run the Actor and wait for it to finish
const run = await client.actor("zkrobotics/tender-matcher").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 = { "companyId": "43408539500508" }

# Run the Actor and wait for it to finish
run = client.actor("zkrobotics/tender-matcher").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 '{
  "companyId": "43408539500508"
}' |
apify call zkrobotics/tender-matcher --silent --output-dataset

```

## MCP server setup

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

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/hAfBfdhvWb3tVK1vK/builds/fuDj6pHUOBlyI3lyu/openapi.json
