Trouver des marchés avec la TED Search API

Qu’est-ce que la TED Search API ?

TED (Tenders Electronic Daily) est le journal officiel de l’UE pour les marchés publics, où est publié chaque avis de marché au-dessus des seuils des 27 États membres. La TED Search API expose ces avis au format JSON via un point de terminaison unique :

POST https://api.ted.europa.eu/v3/notices/search

Vous pouvez l’appeler sans aucune authentification, elle est donc ouverte à tout réutilisateur. La référence complète des requêtes et des réponses se trouve dans la documentation Swagger.

Avez-vous besoin d’une clé API ?

Pas pour la recherche. La Search API est entièrement publique, et une clé augmente seulement vos limites de débit et débloque d’autres points de terminaison, comme la gestion de vos propres avis. Si vous en voulez tout de même une, cela prend trois étapes :

  1. Rendez-vous sur le TED Developer Portal.
  2. Connectez-vous avec vos identifiants EU Login.
  3. Générez votre clé dans Manage API Keys.

Rechercher des marchés avec Python

Chaque requête comporte trois éléments : une query, les fields que vous souhaitez récupérer et un limit. La query utilise la syntaxe de recherche experte de TED, écrite sous la forme field operator value et combinée avec AND, OR et NOT. Voici les champs que vous utiliserez le plus souvent :

ChampExempleSignification
classification-cpvclassification-cpv=38000000Code CPV (secteur)
buyer-countrybuyer-country=FRAPays de l’acheteur, ISO à 3 lettres
publication-datepublication-date>=20260420Publié à une date ou après
estimated-value-procestimated-value-proc>=50000Valeur estimée du marché

Plutôt que de mémoriser la syntaxe, construisez votre requête visuellement dans la recherche experte de TED et copiez la chaîne obtenue dans votre code. Si vous ne savez pas quel code CPV correspond à votre secteur, recherchez-le avec notre recherche de codes CPV.

L’exemple ci-dessous trouve des marchés d’équipement de laboratoire (CPV 38000000) publiés depuis le début de l’année, d’une valeur estimée entre 50 000 et 500 000 EUR, auprès d’acheteurs en France. Comme une seule page contient au plus 250 avis, il parcourt les résultats en mode itération, en récupérant cinq pages de 100, soit jusqu’à 500 avis en une seule exécution :

import requests
import time

URL = "https://api.ted.europa.eu/v3/notices/search"

query = " AND ".join([
    "classification-cpv=38000000",     # Équipement de laboratoire
    "buyer-country=FRA",               # France
    "publication-date>=20260101",
    "estimated-value-proc>=50000",
    "estimated-value-proc<=500000",
])

payload = {
    "query": query,
    "fields": [
        "publication-number",
        "notice-title",
        "classification-cpv",
        "estimated-value-proc",
        "estimated-value-cur-proc",
    ],
    "limit": 100,
    "scope": "ACTIVE",
    "paginationMode": "ITERATION",
}

notices = []
for _ in range(5):  # Récupérer cinq pages.
    data = requests.post(URL, json=payload).json()
    notices.extend(data["notices"])

    # Utiliser le jeton d'itération pour paginer efficacement.
    token = data.get("iterationNextToken")
    if not token or len(data["notices"]) < payload["limit"]:
        break
    payload["iterationNextToken"] = token

    time.sleep(1)

for notice in notices:
    number = notice["publication-number"]
    title = notice["notice-title"]["fra"]
    cpv = ", ".join(notice["classification-cpv"])
    value = notice.get("estimated-value-proc", "n/a")
    currency = notice.get("estimated-value-cur-proc", "")

    print(f"{number} | {title} | {value} {currency} | {cpv}")

Quelques détails sur la réponse méritent d’être connus. notice-title est indexé par code de langue, donc notice-title["fra"] renvoie le titre en français, tandis que classification-cpv arrive sous forme de liste de codes. En mode itération, chaque page vous fournit un iterationNextToken que vous renvoyez à la requête suivante, et la boucle s’arrête dès qu’une page revient plus petite que votre limite. À partir de là, vous pouvez remplacer FRA par n’importe quel code pays, ou 38000000 par le secteur sur lequel vous soumissionnez.

Limites et bonnes pratiques

La Search API est généreuse, mais quelques limites encadrent son utilisation :

  • Taille de page. Une requête renvoie au plus 250 avis ; tout ce qui dépasse nécessite paginationMode: "ITERATION" et la boucle à jeton montrée ci-dessus.
  • Taille de requête. Une seule requête peut contenir jusqu’à 2 000 clauses. Lorsque vous visez de nombreux codes CPV, regroupez-les avec IN (...) au lieu d’enchaîner une longue série de conditions OR.
  • Limites de débit. Les appels anonymes sont limités ; enregistrez une clé API avant d’exécuter des tâches lourdes ou planifiées.
  • Forme des champs. De nombreux champs sont multilingues ou reviennent sous forme de listes, c’est pourquoi l’exemple les lit de manière défensive avec .get() et une clé de langue.
  • Soyez fair-play. Mettez en cache ce que vous récupérez et évitez de télécharger deux fois les mêmes avis. TED se met à jour tout au long de la journée, une synchronisation horaire ou quotidienne suffit donc généralement.

Voilà toute la boucle : construire une requête, l’envoyer en POST, lire le JSON et paginer. À partir de là, vous pouvez stocker les avis dans une base de données, envoyer des alertes à votre équipe ou les intégrer directement dans votre propre produit.