Surveillance des marchés
Livraison automatique des nouveaux marchés selon vos filtres — région, tags sectoriels, mots-clés, plage de valeurs. API Pull + digest e-mail + webhook.
Concepts
Quatre notions que vous rencontrerez dans tous les endpoints :
- Tender — un appel d'offres spécifique issu d'un portail (NEN, VVZ, E-ZAK, TenderArena, etc.). Identifié par un ID numérique.
- Filter — un ensemble de critères enregistrés (région, secteur, mots-clés, valeur). Lorsqu'un nouvel appel d'offres satisfait ces critères, une correspondance est créée.
- Match — un nouvel appel d'offres correspondant à votre filtre. Représente la liaison (tender × filtre) + timestamp + votre statut (suivi / masqué / lu).
- Taxonomy — référentiels de régions (NUTS), de secteurs (tags sectoriels) et de codes CPV selon lesquels nous classifions les marchés publics.
Démarrage rapide
Les filtres peuvent être configurés de deux manières — le résultat est identique et le filtre peut être modifié à tout moment par l'une ou l'autre méthode.
curl -H "X-Api-Key: mrw_live_…" \ "https://veritra.io/api/v2/leads/tenders/search?qText=rekonstrukce%20mostu&limit=5"
La barre supérieure permet une recherche ad hoc. Pour un monitoring continu (nouveaux appels d'offres correspondant à vos critères), utilisez les filtres + webhook/email digest — voir ci-dessous.
Recherche d'appels d'offres (ad hoc)
Pour une recherche ponctuelle d'appels d'offres parmi tous les marchés actifs. N'utilise pas de filtre enregistré ; les paramètres sont passés directement dans la chaîne de requête.
/api/v2/leads/tenders/searchParamètres de requête
| Paramètre | Type | Description |
|---|---|---|
| qText* | string | Texte recherché (recherche plein texte dans le titre + la description). |
| regions | string | CSV de codes feuilles NUTS (CZ010,CZ020). |
| cpvPrefixes | string | CSV de préfixes CPV (45,452). |
| industryTags | string | CSV d'identifiants de tags sectoriels (con_buildings,it_development). |
| minValue | number | Valeur estimée minimale (CZK). Les appels d'offres sans valeur sont acceptés. |
| maxValue | number | Valeur estimée maximale (CZK). Les appels d'offres sans valeur sont acceptés. |
| deadlineFrom | string (YYYY-MM-DD) | Date limite de dépôt >= AAAA-MM-JJ. |
| deadlineTo | string (YYYY-MM-DD) | Date limite de dépôt <= AAAA-MM-JJ. |
| sort | "newest" | "deadline" | "value" | Tri : newest (par défaut), deadline (croissant), value (décroissant). |
| limit | number | Nombre de résultats, max 1000 (défaut : 50). Pour >1k, utilisez la pagination nextCursor ou /matches/export. |
| cursor | string | Curseur keyset de la page précédente (pagination.nextCursor). |
Exemple
curl -H "X-Api-Key: mrw_live_…" \ "https://veritra.io/api/v2/leads/tenders/search?qText=rekonstrukce®ions=CZ010,CZ020&minValue=500000&limit=10"
/api/v2/leads/tenders/:idRéponse : objet data avec les champs id, title, description, estimatedValue, deadlineAt, contractingAuthority, documents[], starred, excluded.
/api/v2/leads/tenders/:id/emailLe corps peut contenir recipientEmail pour transférer vers une autre adresse e-mail. Par défaut : user.email.
/api/v2/leads/documents/previewQuery : ?url=:original&kind=docx|xlsx. Liste blanche des hôtes : NEN, E-ZAK, Tender Arena, Gemin, ProfilZadavatele.
GET /api/v2/leads/documents/preview?url=https://nen.nipez.cz/…/Vyzva.docx&kind=docx → 302 Location: https://rwx-storage…/Tendero/doc-cache-v8/<hash>.html (signed, TTL 10 min)
Catalogue & autocomplétion (public, aucune clé requise)
Pour les menus déroulants de l'interface et la création de filtres. Cache côté serveur : 1 h. Public, aucune authentification requise.
/api/v2/leads/zadavatele?q=praha/api/v2/leads/countries/api/v2/leads/regions?country=CZ/api/v2/leads/regions/catalog?country=CZ&locale=cs/api/v2/leads/taxonomy/industry/api/v2/leads/taxonomy/cpvÉléments filtrables et valeurs autorisées
Le filtre est composé des champs ci-dessous. Tous sont optionnels sauf `name`. Un champ vide = aucune restriction sur cette dimension.
regions string[]
Régions NUTS pour le pays donné (?country=CZ) avec libellés par locale.
CZČeská republikaSKSlovenskoPLPolskoDENěmeckoATRakouskoFRFrancieESŠpanělskoITItálieNLNizozemskoBEBelgiePTPortugalskoSEŠvédskoFIFinskoDKDánskoNONorskoIEIrskoGRŘeckoRORumunskoBGBulharskoHUMaďarskoHRChorvatskoSISlovinskoLTLitvaLVLotyšskoEEEstonskoLULucemburskoCYKyprMTMaltaCHŠvýcarskoISIslandMKSeverní MakedoniePour obtenir l'arborescence NUTS complète d'un pays donné, utilisez :
GET /api/v2/leads/regions/catalog?country=CZ&locale=cs GET /api/v2/leads/regions/catalog?country=DE&locale=de GET /api/v2/leads/regions/catalog?country=FR&locale=en
Exemple : codes NUTS-3 pour CZ (régions) — développer ▸
CZ010Hlavní město PrahaCZ020Středočeský krajCZ031Jihočeský krajCZ032Plzeňský krajCZ041Karlovarský krajCZ042Ústecký krajCZ051Liberecký krajCZ052Královéhradecký krajCZ053Pardubický krajCZ063Kraj VysočinaCZ064Jihomoravský krajCZ071Olomoucký krajCZ072Zlínský krajCZ080Moravskoslezský krajindustryTags string[] Recommandé
Classification sectorielle multi-tags. Un appel d'offres peut avoir plusieurs tags (ex. : « stav_pozemni » + « stav_remesla » pour une rénovation). Le filtre correspond à un appel d'offres s'il possède au moins un des tags indiqués (JSON_OVERLAPS).
Pourquoi préférer les industryTags au CPV : Nos industryTags sont générés par la combinaison de la classification LLM du titre/description de l'appel d'offres + du mapping CPV + d'indices regex — ils capturent les marchés pertinents même chez les acheteurs qui attribuent les CPV de façon négligente. Le filtre CPV est précis, mais dépend de la rigueur de l'acheteur, qui est faible en République tchèque.
con_buildingsBuilding construction and renovationcon_civilCivil engineering (roads, bridges, water)con_tradesConstruction trades and subworkscon_energy_efficiencyEnergy savings & renewablescon_materialsConstruction materialsdes_documentationDesign documentation and studiesdes_supervision_ohsSite supervision and OHSdes_surveyingSurveying and land consolidationit_developmentSoftware development and integrationit_licensingSoftware licences and subscriptionsit_hardwareHardware and infrastructureit_cybersecurityCybersecurityit_data_aiData, analytics, AI/MLtelecom_internetTelecom, internet, mobileprof_marketingMarketing, PR, advertisingprof_legalLegal servicesprof_accountingAccounting, grants, auditprof_hrHR, recruitmentprof_translationTranslation and interpretingprof_insuranceInsurance and financeops_cleaningCleaning servicesops_securitySecurity and receptionops_maintenanceEquipment maintenance and serviceops_wasteWaste managementops_facilityProperty managementcat_cateringCatering servicescat_accommodationAccommodation and conferencescat_foodFood and beveragestrans_transportPassenger and freight transporttrans_vehiclesVehicles, parts, leasinghealth_pharmaPharmaceuticalshealth_devicesMedical devices and supplieshealth_careHealth and social caregoods_furnitureFurniture and interiorsgoods_clothingClothing, PPE, uniformsgoods_electricalElectrical materialgoods_machineryIndustrial machineryenergy_fuelsFuelsenergy_power_heatElectricity and heatenergy_waterWater utilitiesnat_forestryForestrynat_greeneryGreenery maintenance and gardeningnat_agricultureAgriculturedefense_safetyFire, military, defencesci_labLab and measurement equipmentsci_researchResearch and developmentedu_trainingEducation and trainingculture_mediaCulture, books, mediacategories string[] Moins précis
Préfixes CPV (Common Procurement Vocabulary) de longueur quelconque — correspondance via `LIKE 'prefix%'`. Ainsi, « 45 » capture toutes les divisions de travaux, « 4523 » uniquement les travaux de génie civil, « 45316110 » uniquement l'éclairage public.
03Agriculture, sylviculture, pêche09Combustibles et énergie15Produits alimentaires et boissons18Vêtements, chaussures, équipements de protection individuelle22Imprimés, livres30Machines de bureau, équipements informatiques31Machines électriques, câbles, éclairage32Radio, télévision, télécommunications33Équipements médicaux, médicaments34Véhicules, transport35Sécurité, matériel de pompiers et militaire38Instruments de laboratoire et de mesure39Mobilier, aménagement intérieur42Machines industrielles44Matériaux et structures de construction45Travaux de construction48Logiciels et licences50Réparations et maintenance55Restauration, hébergement60Transport (acheminement)64Services postaux, télécommunications65Services publics (électricité, eau)66Services financiers et d'assurance70Services immobiliers et gestion de bâtiments71Services d'architecture, de conception et d'ingénierie72Services informatiques (développement, intégration, support)73Recherche et développement75Administration publique, défense77Services agricoles, forestiers et horticoles79Services aux entreprises (juridique, comptabilité, RH, marketing)80Éducation, formation85Soins de santé et services sociaux90Déchets, environnement, nettoyage92Culture, sport, loisirs98Autres services à la populationLe catalogue complet (9 454 codes) est disponible sur /docs/leads/cpv — consultable et regroupé par divisions.
keywords string[]
Correspondance LIKE sur le titre et la description du marché. Non sensible à la casse. Opérateur OR entre les éléments. Utile comme filet de sécurité si les industryTags/CPV ne capturent pas tout (ex. : type de marché spécifique mentionné dans le texte).
"keywords": ["rekonstrukce", "VO", "osvětlení", "MŠ"]
minValue / maxValue number | null
Plage de la valeur estimée du marché en CZK. Il est possible de renseigner uniquement minValue, uniquement maxValue, ou les deux.
emailDigest boolean
Si true, vous recevez 1× par jour (05:00 UTC) un e-mail récapitulatif des nouveaux résultats correspondant à ce filtre. Valeur par défaut : true. Désactivable en modifiant le filtre. Le webhook se configure séparément, au niveau du compte (voir la section ci-dessous).
name string · active boolean
`name` — 120 caractères max, obligatoire. `active` — si false, le filtre ne s'exécute pas dans le cron (aucun nouveau résultat, digest ou webhook). Permet de mettre en pause sans supprimer.
Logique de filtrage
Les champs se combinent comme suit :
MATCH = (acheteur.NUTS3 ∈ expand(regions))
AND (minValue ≤ estimatedValue ≤ maxValue OU estimatedValue est null ou 0)
AND (industry_or_cpv OU keyword_match)
# expand(regions) : les codes NUTS sont développés jusqu'aux feuilles NUTS 3
# (CZ → 14 régions, CZ01 → CZ010, CZ010 → CZ010).
industry_or_cpv :
si industryTags renseignés → JSON_OVERLAPS(industryTags, tender.industryTags)
sinon categories renseignées → tender.cpvCode LIKE ANY (categories + "%")
sinon → false (aucun filtre industry appliqué)
keyword_match :
si keywords renseignés → tender.title ou description LIKE ANY (%kw%)
sinon → false
# Si vous ne renseignez aucun industryTags / categories / keywords,
# tous les appels d'offres satisfaisant regions et la plage de valeur sont retournés.industryTags a la priorité sur categories — si vous renseignez les deux, seul industryTags est utilisé (categories est ignoré). keywords fonctionne indépendamment (il se trouve dans la branche OR avec industry_or_cpv).
Points de terminaison pour la gestion des filtres
Pour gérer les filtres, utilisez la clé de gestion (mrw_live_…). Elle dispose de limites de débit (rate limits) indépendantes et ne consomme pas de crédits LEADS, de sorte que la gestion des filtres n'affecte pas votre collecte quotidienne de marchés.
/api/v2/leads/filters/api/v2/leads/filters/api/v2/leads/filters/:id/api/v2/leads/filters/:id/api/v2/leads/filters/:id/api/v2/leads/filters/:id/matches/export?format=csv|xlsx|json&view=all|starred|excludedParamètres body (POST / PUT) — communs
| Paramètre | Type | Description |
|---|---|---|
| name* | string | Nom du filtre (120 caractères max) |
| regions | string[] | Codes NUTS (ex. `CZ010`). Il est possible de mélanger n'importe quel niveau. Tableau vide = toutes les régions. |
| industryTags | string[] | Approche recommandée. Identifiants de tags issus de notre taxonomie (ex. 'stav_pozemni', 'it_vyvoj'). Multi-tag — OR entre les éléments. |
| categories | string[] | Préfixes CPV de longueur quelconque (ex. '45', '4523', '45316110'). Moins précis qu'industryTags. |
| keywords | string[] | Mots-clés — correspondance LIKE dans le titre et la description du marché (OR entre les éléments). |
| minValue | number | null | Valeur estimée minimale (CZK). Les appels d'offres sans valeur sont acceptés. |
| maxValue | number | null | Valeur estimée maximale (CZK). Les appels d'offres sans valeur sont acceptés. |
| emailDigest | boolean | Digest e-mail quotidien (par défaut true) |
| active | boolean | Filtre actif (par défaut true) |
Le webhook ne se configure plus au niveau du filtre — voir la section Webhook ci-dessous (points de terminaison au niveau du compte). Le champ webhookUrl est refusé pour des raisons de sécurité avec HTTP 410.
Exemples
Travaux à Prague supérieurs à 500 000 CZK
curl -X POST -H "X-Api-Key: mrw_live_…" \
-H "Content-Type: application/json" \
-d '{
"name": "Travaux Prague 500k+",
"regions": ["CZ010"],
"industryTags": ["con_buildings", "con_trades"],
"minValue": 500000
}' \
https://veritra.io/api/v2/leads/filtersDéveloppement IT et licences logicielles (toutes les régions)
curl -X POST -H "X-Api-Key: mrw_live_…" \
-H "Content-Type: application/json" \
-d '{
"name": "Dév. IT + licences SW",
"industryTags": ["it_development", "it_licensing", "it_data_ai"],
"keywords": ["système d'information", "module"]
}' \
https://veritra.io/api/v2/leads/filtersÉclairage public (CZ) — combinaison de tags + mots-clés
curl -X POST -H "X-Api-Key: mrw_live_…" \
-H "Content-Type: application/json" \
-d '{
"name": "Éclairage public (CZ)",
"industryTags": ["goods_electrical", "con_civil"],
"keywords": ["éclairage", "EP ", "éclairage public", "lampadaires"],
"minValue": 200000
}' \
https://veritra.io/api/v2/leads/filtersDésactiver le filtre
curl -X PATCH -H "X-Api-Key: mrw_live_…" \
-H "Content-Type: application/json" \
-d '{"active": false}' \
https://veritra.io/api/v2/leads/filters/<id>Distribution — webhook vs polling
Deux façons de recevoir les nouveaux marchés dans votre ERP. La plupart des intégrateurs combinent les deux.
Webhook (push)
Veritra envoie un POST à votre endpoint en ~2 secondes après le match. Événement leads.match.created avec le payload complet du marché.
Avantages : temps réel, aucun overhead de polling, contrôle côté serveur.
Inconvénients : nécessite un endpoint publicly accessible (HTTPS), vérification HMAC, gestion de l'idempotence.
Polling (pull)
Votre ERP appelle GET /api/v2/leads/matches?since=… périodiquement (par ex. toutes les 5 min). Retourne les correspondances depuis le timestamp indiqué.
Avantages : aucun endpoint public requis, implémentation simple, compatible redémarrage.
Inconvénients : latence de 5 à 10 min, contrainte de rate-limit (60 req/min API de gestion), réponses vides superflues.
Récupération des correspondances
/api/v2/leads/matchesParamètres de requête
| Paramètre | Type | Description |
|---|---|---|
| filterId | string | Filtrer selon un filtre spécifique |
| qText | string | Texte recherché (recherche plein texte dans le titre + la description). |
| since | string (ISO 8601 datetime) | Uniquement les correspondances à partir de cette date (datetime ISO) |
| delivered | boolean | false = non livrées uniquement, true = livrées uniquement |
| view | "starred" | "excluded" | Vue spéciale : starred (favoris) | excluded (masqués). |
| sort | "newest" | "deadline" | "value" | Tri : newest (par défaut), deadline (croissant), value (décroissant). |
| limit | number | Nombre de résultats, max 1000 (défaut : 50). Pour >1k, utilisez la pagination nextCursor ou /matches/export. |
| cursor | string | Curseur keyset de la page précédente (pagination.nextCursor). |
Les correspondances retournées sont automatiquement marquées comme delivered=true. Chaque requête consomme 1 crédit.
Formats de matchId
Le matchId se présente sous deux formats selon l'origine :
cm…(préfixe cuid) — retourné depuis la table LeadMatch pré-calculée (tâche cron qui apparie les marchés chaque jour). Stable d'un appel à l'autre, utilisable pour mark-as-viewed.live-12345Préfixe synthetic pour un match détecté en direct via le mode recherche / navigation (paramètre qText, view=starred/excluded). Absent de la table LeadMatch → mark-as-viewed est sans effet. tenderId est le suffixe après le tiret.
Exemple
curl -H "X-Api-Key: mrw_leads_…" \ "https://veritra.io/api/v2/leads/matches?delivered=false&limit=10"
Réponse
{
"data": [
{
"matchId": "cm…",
"filterId": "cm…",
"filterName": "Stavby Praha",
"matchedAt": "2026-04-03T06:00:00.000Z",
"viewedAt": null,
"delivered": true,
"tender": {
"id": 12345,
"title": "Reconstruction du pont réf. 123",
"estimatedValue": 12500000,
"deadlineAt": "2026-05-15T22:00:00.000Z",
"publishedAt": "2026-04-01T08:00:00.000Z",
"firstSeenAt": "2026-04-01T08:30:00.000Z",
"url": "https://nen.nipez.cz/...",
"portalType": "NEN",
"cpvCode": "45000000",
"tenderType": "OFFERS",
"contractingAuthority": {
"ico": "12345678",
"name": "Město Praha",
"region": "Praha",
"district": "Praha 1"
},
"documents": [
{ "name": "Výzva.pdf", "url": "https://nen.nipez.cz/…", "fileType": "pdf", "fileSizeBytes": 320000 }
],
"starred": false,
"excluded": false
}
}
],
"pagination": { "nextCursor": "eyJmaXJzdFNlZW5BdC…", "totalCount": 42 }
}Pour la page suivante, envoyez pagination.nextCursor en tant que paramètre ?cursor=.
Actions sur les matchs
Star (favori), exclude (masquer) et view (marquer comme lu) sont des préférences par appel d'offres stockées dans UserTenderPreference.
/api/v2/leads/matches/:matchIdRéponse : même structure que l'élément de la liste des matchs.
/api/v2/leads/matches/:matchId/star{ "starred": true }/api/v2/leads/matches/:matchId/exclude{ "excluded": true }/api/v2/leads/matches/:matchId/viewPour les matchs live-:id synthétiques, il s'agit d'une opération sans effet (no-op) (aucune ligne à marquer).
/api/v2/leads/preferences{
"data": {
"starred": [12345, 67890],
"excluded": [54321]
}
}Taxonomie
Catalogues de référence statiques pour les valeurs de filtre. Libellés adaptés à la locale.
/api/v2/leads/taxonomy/industry?locale=cs{
"data": {
"locale": "cs",
"areas": [{ "id": "construction", "icon": "🏗️", "label": "Stavebnictví" }, …],
"tags": [
{ "id": "con_buildings", "area": "construction", "label": "Pozemní stavby", "cpvPrefixes": ["452"] },
…
]
}
}/api/v2/leads/taxonomy/cpv?locale=csRéponse : structure arborescente divisions → groupes → classes → catégories → sous-catégories.
Webhook
Les endpoints Webhook (CRUD, rotation du secret) sont au niveau du compte — documentés une seule fois dans API Compte → Webhooks. Seul le payload d'événement spécifique aux leads (leads.match.created) et la vérification HMAC sont décrits ici.
Livraison des événements
Lors d'un nouveau match, nous envoyons un événement de type leads.match.created avec une signature HMAC-SHA256 dans l'en-tête X-Signature-256, la clé d'idempotence dans X-Idempotency-Key et le type dans X-Event-Type. En cas d'échec, nouvelle tentative avec backoff exponentiel jusqu'à ~33 heures.
Politique de retry
Si votre endpoint retourne un code non-2xx (ou ne répond pas dans les 10 s), Veritra effectue des retries avec backoff exponentiel : 1 min, 5 min, 30 min, 2 h, 12 h, 24 h. Après 6 échecs, le webhook est marqué comme failed et une alerte s'affiche dans le tableau de bord. L'Idempotency-key reste identique pour chaque tentative — votre endpoint DOIT dédupliquer les requêtes (sans quoi la même correspondance sera traitée 6 fois).
Gestion des endpoints via l'API
Vous pouvez gérer les endpoints webhook sans passer par le tableau de bord. Limite de 5 endpoints par compte.
/api/v2/account/webhooks/api/v2/account/webhooks/api/v2/account/webhooks/:id/api/v2/account/webhooks/:id/api/v2/account/webhooks/:id/api/v2/account/webhooks/:id/rotate-secret/api/v2/account/webhooks/:id/test/api/v2/account/webhooks/:id/deliveries/api/v2/account/webhooks/:id/deliveries/:deliveryId/replayVérification de signature HMAC
Le serveur signe le payload avec HMAC-SHA256(secret, raw_body) et l'envoie dans l'en-tête X-Signature-256 au format sha256=hex. Vérifiez en comparaison en temps constant, sans quoi l'intégration est vulnérable à une attaque par timing.
// Node.js (Express)
import crypto from "node:crypto";
const WEBHOOK_SECRET = process.env.MRICKWOOD_WEBHOOK_SECRET!;
function verify(rawBody: string, sig: string | undefined): boolean {
if (!sig) return false;
const expected = "sha256=" + crypto
.createHmac("sha256", WEBHOOK_SECRET)
.update(rawBody)
.digest("hex");
// Constant-time comparison (timing-safe)
const a = Buffer.from(sig);
const b = Buffer.from(expected);
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
app.post("/webhooks/veritra",
express.raw({ type: "application/json" }),
async (req, res) => {
const raw = req.body.toString("utf8");
if (!verify(raw, req.header("X-Signature-256"))) {
return res.status(401).send("Invalid signature");
}
const idempKey = req.header("X-Idempotency-Key")!;
const evt = JSON.parse(raw);
// Idempotency: store idempKey, skip if already processed
if (await alreadyProcessed(idempKey)) return res.status(200).send("ok");
await processEvent(evt);
await markProcessed(idempKey);
res.status(200).send("ok"); // Must be 2xx within 10s
},
);# Python (Flask)
import hmac, hashlib, os
from flask import Flask, request, abort
WEBHOOK_SECRET = os.environ["MRICKWOOD_WEBHOOK_SECRET"]
def verify(raw: bytes, sig: str | None) -> bool:
if not sig: return False
expected = "sha256=" + hmac.new(
WEBHOOK_SECRET.encode(), raw, hashlib.sha256
).hexdigest()
return hmac.compare_digest(sig, expected)
@app.post("/webhooks/mrickwood")
def webhook():
raw = request.get_data()
if not verify(raw, request.headers.get("X-Signature-256")):
abort(401)
# ... idempotency check + process
return "ok", 200{
"id": "evt_…",
"type": "leads.match.created",
"createdAt": "2026-04-03T06:00:00.000Z",
"data": {
"filterId": "cm…",
"filterName": "Stavby Praha",
"matchId": "cm…",
"tender": { "id": "12345", "title": "…", "estimatedValue": 12500000 }
}
}Digest e-mail
Avec emailDigest: true, vous recevrez un e-mail quotidien récapitulant les nouveaux appels d'offres. Le digest est envoyé le matin (5h00 UTC) à l'adresse e-mail de votre compte. Il peut être désactivé en modifiant le filtre.
Limites
| Paramètre | Type | Description |
|---|---|---|
| Essai | 500 req/mois | 1 jour gratuit. Sans carte / profil de facturation. ApiKey.requestsLimit par défaut. |
| Plan payant | illimité | La limite mensuelle est désactivée. Seule la limite technique de 100/h/clé s'applique. |
| Filtres | 20 | Nombre maximum de filtres actifs par compte. |
| Endpoints Webhook | 5 | Nombre maximum d'URL webhook actives par compte. |
En cas de dépassement de la limite mensuelle, l'API renvoie 429 avec l'en-tête Retry-After. La limite se réinitialise le 1er du mois.