Aller au contenu

API · Pour les développeurs

Les données d'appels d'offres via une API

Les données que voient les utilisateurs de Tender Radar, dans votre ERP, votre CRM ou votre entrepôt de données : Prozorro, plus d'une centaine de plateformes commerciales et portails d'entreprise, l'UE, le Royaume-Uni et l'ONU. Un seul format pour toutes les plateformes, actualisé toutes les quelques minutes.

Ce que vous apporte l'API

Chaque appel d'offres arrive dans un seul format, quel que soit l'endroit où il a été publié : numéro, titre, acheteur avec son identifiant d'entreprise, CPV, valeur attendue, échéances dans le fuseau horaire de l'acheteur et en UTC, statut et lien vers l'original. Lorsque le même appel d'offres figure sur plusieurs plateformes, vous obtenez un seul enregistrement listant tous les lieux de publication.

Sources

  • Prozorro — les marchés publics d'Ukraine
  • Plateformes commerciales ukrainiennes et portails d'achats d'entreprise
  • Union européenne (TED)
  • Systèmes nationaux de marchés publics d'autres pays, dont le Royaume-Uni
  • Organisations internationales, dont l'ONU

Fraîcheur

Chaque source est interrogée selon son propre calendrier : la plus fréquente toutes les quelques minutes, les autres de toutes les heures à toutes les quelques heures. Le champ updated_at indique quand un enregistrement a changé pour la dernière fois.

Champs d'un appel d'offres

ChampDescription
idIdentifiant permanent de l'enregistrement dans Radar (UUID). Faites vos upserts de lignes dessus.
numberLe numéro de l'appel d'offres à la source, par ex. UA-2026-10-11-000337-a.
title · title_translated · description · languageTitre et description dans la langue d'origine ; une traduction ukrainienne du titre d'un appel d'offres étranger lorsqu'elle existe.
status · status_sourceStatut sur l'échelle commune de Radar, et statut tel que le donne la source.
procedureType de procédure : code et libellé.
buyerAcheteur : nom, EDRPOU ou identifiant national, région, localité.
cpvCode CPV principal avec son nom, plus les codes supplémentaires.
valueValeur attendue, devise et indication de TVA incluse ou non.
published_at · submission_deadline · enquiry_end · auction_atDates et échéances : heure locale de l'acheteur (local) et UTC (utc) ; time_zone est le fuseau horaire de l'acheteur.
source · url · also_onSource, lien vers l'original et autres plateformes qui publient le même appel d'offres.
lots · items · documentsLots, articles et documents, lorsque la source les publie.
radar_url · first_seen_at · updated_atL'appel d'offres dans Radar, la date de première détection et celle du dernier changement de l'enregistrement.

Authentification

Chaque requête porte la clé de l'organisation dans l'en-tête Authorization: Bearer rdr_live_…. Une clé appartient à la société, pas à une personne : donnez-la à un service ou à une intégration.

  1. 1Les clés sont créées par le propriétaire ou un administrateur de la société dans Tender Radar : Paramètres → « API ».
  2. 2Nous affichons la clé complète une seule fois, juste après sa création. Conservez-la dans un gestionnaire de secrets ou une variable d'environnement.
  3. 3Nous ne stockons qu'un hachage de la clé, nous ne pouvons donc pas la réafficher. Clé perdue ? Révoquez-la et créez-en une nouvelle.
  4. 4Une clé révoquée cesse aussitôt de fonctionner. Donnez à chaque intégration sa propre clé (jusqu'à 10 actives).

URL de base

https://metadani.com/v1/data
Authorization: Bearer rdr_live_…

Première requête

Appels d'offres ouverts de toiture en Ukraine. La clé est lue depuis la variable d'environnement RADAR_API_KEY.

Points d'accès

Chaque réponse est du JSON en UTF-8. Les listes arrivent sous forme d'objet avec un champ data. Les paramètres de liste peuvent être répétés ou séparés par des virgules.

Appels d'offres

GET/v1/data/tenders

Recherche et export des appels d'offres. L'ordre est toujours (updated_at, id) croissant, de sorte que le curseur ne saute jamais une modification.

ParamètreDescription
qTexte libre, formes fléchies comprises. Une expression exacte se met entre guillemets, -mot exclut.
cpvCodes CPV ou préfixes de 2 à 8 chiffres (45 — construction, 4526 — travaux de toiture).
countryPays ISO 3166-1 alpha-2 : UA, PL, GB… ; EU — appels d'offres de l'UE issus de TED.
sourceCodes de source issus de /v1/data/sources.
groupSlugs de groupes de sociétés issus de /v1/data/buyer-groups.
buyerAcheteur : EDRPOU, identifiant national ou identifiant d'acheteur Radar.
statusopen (par défaut) — un fournisseur peut encore répondre et l'échéance n'est pas passée ; any — tous les statuts ; ou des statuts précis : planned, active, enquiry, tendering, auction, qualification, awarded, complete, cancelled, unsuccessful, closed_by_deadline, withdrawn_from_hub, notice, non_competitive.
value_min, value_maxValeur attendue de / à, dans la devise propre à l'appel d'offres.
deadline_from, deadline_toÉchéance de remise des offres de / à, date-heure ISO 8601.
updated_sinceISO 8601 : uniquement les appels d'offres créés ou modifiés à partir de ce moment.
cursorCurseur opaque issu du next_cursor de la réponse précédente.
limitTaille de page, 1–500, 100 par défaut.
langLangue des noms CPV, des libellés de procédure et des noms de source : uk (par défaut), ru, en.
formatjson (par défaut) ou csv.
Exemple de réponse
{
  "data": [
    {
      "id": "0d6f4f7e-1c3b-4a51-9b7e-5b9b1f0c2a11",
      "number": "UA-2026-10-11-000337-a",
      "title": "Капітальний ремонт покрівлі",
      "status": "tendering",
      "source": { "code": "prozorro", "name": "Prozorro" },
      "value": { "amount": 1250000.0, "currency": "UAH", "vat_included": true },
      "submission_deadline": { "local": "2026-10-21T00:00:00+03:00", "utc": "2026-10-20T21:00:00Z" },
      "updated_at": "2026-10-11T19:31:02.123456Z",
      "…": "…"
    }
  ],
  "next_cursor": "eyJ1IjoiMjAyNi0xMC0xMVQxOTozMTowMi4xMjM0NTZaIiwiaSI6IjZmMWMifQ",
  "has_more": true,
  "as_of": "2026-10-11T19:40:00Z"
}

Un appel d'offres

GET/v1/data/tenders/{id}

L'enregistrement complet par id. Identifiant inconnu : 404 tender_not_found.

Aucun paramètre.

Exemple de réponse
{
  "id": "0d6f4f7e-1c3b-4a51-9b7e-5b9b1f0c2a11",
  "number": "UA-2026-10-11-000337-a",
  "title": "Капітальний ремонт покрівлі",
  "title_translated": null,
  "description": "…",
  "language": "uk",
  "status": "tendering",
  "status_source": "active.tendering",
  "procedure": {
    "code": "aboveThreshold",
    "label": "Відкриті торги з особливостями"
  },
  "buyer": {
    "name": "Київська міська рада",
    "edrpou": "22883141",
    "scheme": "UA-EDR",
    "region": "Київ",
    "locality": "Київ"
  },
  "country": "UA",
  "region": "Київ",
  "source": {
    "code": "prozorro",
    "name": "Prozorro"
  },
  "url": "https://prozorro.gov.ua/tender/UA-2026-10-11-000337-a",
  "also_on": [
    {
      "source": "smarttender",
      "url": "https://smarttender.biz/…"
    }
  ],
  "cpv": {
    "main": {
      "code": "45261000",
      "name": "Покрівельні роботи"
    },
    "extra": [
      {
        "code": "45262000",
        "name": "…"
      }
    ]
  },
  "value": {
    "amount": 1250000,
    "currency": "UAH",
    "vat_included": true
  },
  "time_zone": "Europe/Kyiv",
  "published_at": {
    "local": "2026-10-11T10:15:00+03:00",
    "utc": "2026-10-11T07:15:00Z"
  },
  "submission_start": {
    "local": "2026-10-11T10:15:00+03:00",
    "utc": "2026-10-11T07:15:00Z"
  },
  "enquiry_end": null,
  "submission_deadline": {
    "local": "2026-10-21T00:00:00+03:00",
    "utc": "2026-10-20T21:00:00Z"
  },
  "auction_at": null,
  "lots": [],
  "items": [],
  "documents": [],
  "radar_url": "https://platform.aurum-apps.com/uk/app/tenders/0d6f4f7e-1c3b-4a51-9b7e-5b9b1f0c2a11",
  "first_seen_at": "2026-10-11T07:16:40Z",
  "updated_at": "2026-10-11T19:31:02.123456Z"
}

Sources

GET/v1/data/sources

Chaque source : code, pays, segment, calendrier d'interrogation, dernière exécution réussie, statut et nombre d'appels d'offres ouverts. Les codes vont dans le paramètre source.

ParamètreDescription
langLangue des noms CPV, des libellés de procédure et des noms de source : uk (par défaut), ru, en.
Exemple de réponse
{
  "data": [
    {
      "code": "prozorro",
      "name": "Prozorro",
      "country": "UA",
      "segment": "ua_public",
      "kind": "api",
      "schedule_minutes": 5,
      "last_success_at": "2026-10-11T19:35:00Z",
      "status": "ok",
      "open_tenders": 18950
    }
  ]
}

Groupes de sociétés

GET/v1/data/buyer-groups

Groupes d'acheteurs (holdings) avec leurs membres et identifiants d'entreprise. Les slugs vont dans le paramètre group.

ParamètreDescription
langLangue des noms CPV, des libellés de procédure et des noms de source : uk (par défaut), ru, en.
Exemple de réponse
{
  "data": [
    {
      "slug": "metinvest",
      "name": "Метінвест",
      "aliases": [
        "Metinvest"
      ],
      "members": [
        {
          "edrpou": "00191000",
          "name": "ПрАТ «ММК ім. Ілліча»"
        }
      ]
    }
  ]
}

Codes CPV

GET/v1/data/cpv

Recherchez des codes CPV par préfixe de code ou par mots, avec des noms en trois langues.

ParamètreDescription
qPréfixe de code ou mots.
langLangue des noms CPV, des libellés de procédure et des noms de source : uk (par défaut), ru, en.
limitCombien de codes renvoyer.
Exemple de réponse
{
  "data": [
    {
      "code": "45261000",
      "name": "Покрівельні роботи",
      "names": {
        "uk": "Покрівельні роботи",
        "en": "Roofing works",
        "ru": "Кровельные работы"
      }
    }
  ]
}

Utilisation

GET/v1/data/usage

Votre clé, ses limites, le nombre de requêtes et de lignes utilisées aujourd'hui et l'état de votre accès.

Aucun paramètre.

Exemple de réponse
{
  "org": "ТОВ «Альфа»",
  "key": {
    "name": "ERP sync",
    "prefix": "rdr_live_ab12cd"
  },
  "limits": {
    "requests_per_minute": 120,
    "rows_per_day": 100000,
    "max_page": 500
  },
  "today": {
    "requests": 14,
    "rows": 1200,
    "rows_remaining": 98800
  },
  "subscription": {
    "status": "active",
    "plan": "api",
    "trial_until": null
  }
}

Schéma OpenAPI

GET/v1/data/openapi.json

Schéma OpenAPI 3 de l'API de données uniquement ; aucune clé nécessaire. Générez-en un client pour votre langage.

Aucun paramètre.

Synchronisation incrémentale

Comment conserver une copie à jour : tout charger une fois, puis ne récupérer que les changements.

  1. 1Premier chargement : GET /v1/data/tenders?limit=500, puis suivez next_cursor tant que has_more vaut true. Enregistrez le dernier next_cursor.
  2. 2Toutes les 10 minutes : GET /v1/data/tenders?cursor=…&status=any&limit=500, de nouveau tant que has_more. Faites un upsert des lignes par id : un appel d'offres modifié revient avec son nouvel état, par ex. closed_by_deadline. Enregistrez le nouveau next_cursor.
  3. 3status=any pour que les appels d'offres clos et annulés arrivent aussi comme des changements. Les lignes que vous n'avez jamais eues et qui ne sont plus ouvertes peuvent être ignorées.

Ni trous ni doublons : une modification encore en cours d'écriture est retenue jusqu'à sa validation, de sorte que le curseur ne la saute jamais. Si une requête est interrompue, répétez-la avec le même curseur.

Export CSV

Ajoutez format=csv et les mêmes lignes arrivent en CSV : colonnes à plat, séparées par des virgules, une ligne d'en-tête, UTF-8 avec BOM (Excel l'ouvre tel quel). Le curseur arrive dans les en-têtes X-Next-Cursor et X-Has-More, la synchronisation fonctionne donc de la même façon.

Limites

  • 120 requêtes par minute et par clé.
  • 100 000 lignes d'appels d'offres par jour et par organisation (jour UTC).
  • Jusqu'à 500 lignes par page.
  • Les deux limites peuvent être relevées pour votre organisation — écrivez-nous.

En-têtes de limitation de débit

Chaque réponse porte l'état actuel des limites :

En-têteDescription
X-RateLimit-LimitRequêtes par minute pour cette clé.
X-RateLimit-RemainingRequêtes restantes dans la minute en cours.
X-RateLimit-ResetSecondes avant la réinitialisation de la fenêtre d'une minute.
X-RateLimit-Rows-LimitLignes par jour pour l'organisation.
X-RateLimit-Rows-RemainingLignes restantes aujourd'hui.
Retry-AfterUniquement avec un 429 : secondes à attendre avant de réessayer.

Erreurs

Le corps d'une erreur est toujours le même : code pour les programmes, message et detail pour les humains. Une erreur de validation (422) a le corps standard où detail liste les champs.

CodeCe qui s'est passé
401 missing_api_keyPas d'en-tête Authorization: Bearer.
401 invalid_api_keyClé inconnue.
401 api_key_revokedLa clé a été révoquée.
402 api_plan_requiredL'organisation n'a pas d'abonnement API actif.
400 invalid_cursorLe curseur est endommagé ou ne provient pas de cette API.
404 tender_not_foundAucun appel d'offres avec cet identifiant.
422 —Un paramètre est invalide.
429 rate_limitedTrop de requêtes par minute ; réessayez après Retry-After.
429 daily_rows_exceededLa limite quotidienne de lignes est épuisée ; elle se réinitialise à minuit UTC.
{
  "code": "invalid_api_key",
  "message": "Unknown API key",
  "detail": "Check the Authorization header"
}

L'API est incluse dans un abonnement

Envoyez une demande : nous convenons du volume et du prix, activons l'abonnement pour votre organisation, et le propriétaire ou un administrateur crée aussitôt une clé.

Vous avez déjà l'accès ? Les clés se créent dans Paramètres → « API ». Ouvrir les paramètres

Obtenir une clé / Demander l'accès