Matching
Règles d'éligibilité
Un petit langage fermé pour les conditions d’une mesure, évalué selon trois valeurs : pass, fail et unknown.
Le champ eligibility.rules d’une mesure est une liste de nœuds de règles qui doivent tous être satisfaits. Le moteur de matching les évalue au regard des informations d’une requête de matching ; l’enregistrement complet les sert tels quels, pour que vous puissiez les afficher ou les évaluer vous-même. Les thèmes en sont volontairement séparés : un thème est une raison d’afficher une mesure, une règle est une condition à remplir.
Nœuds
| Nœud | Forme | Résultat |
|---|---|---|
| condition | { id, field, op, value, label?, provenance } | Compare une information à une valeur : pass, fail, ou unknown si l’information manque. |
| all | { "all": [nodes] } | Fail si un enfant échoue ; sinon unknown si l’un d’eux est unknown ; sinon pass. |
| any | { "any": [nodes] } | Pass si un enfant est satisfait ; sinon unknown si l’un d’eux est unknown (ou si la liste est vide) ; sinon fail. |
| not | { "not": node } | Pass et fail s’inversent ; unknown reste unknown. |
Les nœuds se distinguent par leurs clés. La liste de premier niveau est un all implicite. L’id d’une condition est stable au sein de sa mesure (region, size, applicant_type, nace, age_max), ce qui permet au flux de modifications d’indiquer quelle règle a changé : eligibility.rules[age_max].
Voici les règles du tax shelter fédéral pour les start-ups : le critère des petites sociétés du Code des sociétés et des associations (au moins deux critères sur trois) sous forme d’un any de trois paires, suivi d’une limite d’âge. La provenance est abrégée dans les six premières.
[
{
"any": [
{
"all": [
{
"id": "size",
"field": "company.employees",
"op": "lte",
"value": 50,
"provenance": "…"
},
{
"id": "size_turnover_a",
"field": "company.turnover_eur",
"op": "lte",
"value": 11250000,
"provenance": "…"
}
]
},
{
"all": [
{
"id": "size_employees_b",
"field": "company.employees",
"op": "lte",
"value": 50,
"provenance": "…"
},
{
"id": "size_balance_b",
"field": "company.balance_sheet_eur",
"op": "lte",
"value": 6000000,
"provenance": "…"
}
]
},
{
"all": [
{
"id": "size_turnover_c",
"field": "company.turnover_eur",
"op": "lte",
"value": 11250000,
"provenance": "…"
},
{
"id": "size_balance_c",
"field": "company.balance_sheet_eur",
"op": "lte",
"value": 6000000,
"provenance": "…"
}
]
}
]
},
{
"id": "age_max",
"field": "company.age_years",
"op": "lt",
"value": 4,
"label": {
"nl": "In de eerste vier jaar na de oprichting",
"fr": "Dans les quatre premières années après la constitution",
"en": "Within the first four years after incorporation",
"de": null
},
"provenance": {
"method": "curated",
"source_url": "https://financien.belgium.be/nl/ondernemingen/tax-shelter-kleine-ondernemingen/startende-start-up",
"source_section": null,
"review_status": "verified",
"reviewed_at": "2026-09-27",
"note": "Completed years: the fifth year after incorporation belongs to the scale-up regime."
}
}
]Trois valeurs
Une information que l’appelant n’a pas donnée est inconnue, jamais supposée. Il en va de même d’une information dont l’opérateur ne peut pas comparer la forme, et d’une règle dont la valeur est mal formée : une règle défectueuse n’est jamais satisfaite par accident. Le résultat de l’arbre entier est l’une des trois valeurs, et il détermine le statut du résultat. Les informations inconnues qui pourraient changer le résultat sont renvoyées dans unknowns ; dès qu’un arbre est tranché (un échec dans un all, une réussite dans un any), ses inconnues sont abandonnées, puisqu’il n’y a plus rien à demander.
Champs
Une liste fermée : une règle portant sur une information que le moteur ne peut pas recevoir resterait toujours inconnue. request_path est la propriété de la requête de matching qui fournit l’information, et c’est vers elle que renvoient unknowns et missing_information.
| field | Type | request_path | Signification |
|---|---|---|---|
| company.regions | liste de régions | company.region | Régions où l’entreprise a un établissement (son siège ou une unité d’établissement). |
| company.province | province | company.province | La province où elle est établie. |
| company.size | catégorie de taille | company.size | micro, small, medium ou large. |
| company.employees | nombre | company.employees | Effectif (ETP). |
| company.turnover_eur | nombre | company.turnover_eur | Chiffre d’affaires annuel. |
| company.balance_sheet_eur | nombre | company.balance_sheet_eur | Total du bilan. |
| company.nace | liste de codes | company.nace | Codes NACE-BEL, sans les points. |
| company.legal_form | forme juridique | company.legal_form | bv, nv, cv, vzw, eenmanszaak, ... |
| company.applicant_type | type de demandeur | company.applicant_type | company, self_employed, non_profit, ... |
| company.age_years | nombre | company.founded_on | Années révolues depuis la fondation. |
| company.has_legal_personality | booléen | company.has_legal_personality | Si elle a la personnalité juridique. |
| company.de_minimis_received_eur | nombre | company.de_minimis_received_eur | Aides de minimis des trois dernières années. |
| company.in_difficulty | booléen | company.in_difficulty | Une entreprise en difficulté. |
| project.topics | liste de thèmes | project.topics | L’objet du projet. |
| project.budget_eur | nombre | project.budget_eur | Le coût du projet. |
| project.started | booléen | project.started | S’il a déjà commencé (l’effet incitatif). |
| project.region | région | project.region | Où le projet a lieu. |
| project.cost_types | liste de types de coûts | project.cost_types | Les coûts à financer. |
| project.duration_months | nombre | project.duration_months | Sa durée. |
| project.partners | nombre | project.partners | Partenaires indépendants, demandeur compris. |
GET /v1/taxonomy renvoie la même liste sous rule_fields, chaque champ avec la question à poser en néerlandais, en français et en anglais.
Opérateurs
Les chaînes sont comparées sans tenir compte de la casse. Les nombres peuvent être donnés comme nombres JSON ou comme chaînes numériques.
| op | value | Satisfait quand |
|---|---|---|
| eq, in | chaîne ou liste | L’information est l’une des valeurs. Pour une information de type liste (plusieurs codes NACE), chaque élément doit être l’une des valeurs. Compare aussi l’égalité de deux booléens, ou de deux nombres simples. |
| ne, not_in | chaîne ou liste | Aucun élément de l’information ne fait partie des valeurs. |
| contains_any | liste | Une information de type liste a au moins un élément en commun avec la valeur. |
| contains_all | liste | Chaque élément de la valeur figure dans l’information. |
| contains_none | liste | L’information n’a aucun élément en commun avec la valeur. |
| gte, gt, lte, lt | nombre | La comparaison numérique est vérifiée. |
| between | [min, max] | min ≤ information ≤ max. Tout ce qui n’est pas exactement deux bornes donne unknown. |
| is_true, is_false | ignorée | L’information booléenne vaut true, ou false. |
| nace_any | liste de codes | Au moins un des codes de l’entreprise relève de l’un des codes de la valeur : un préfixe numérique (62 couvre 62010) ou une lettre de section NACE (J couvre 62010). |
| nace_none | liste de codes | Aucun des codes de l’entreprise ne relève des codes de la valeur. Une liste vide de codes d’entreprise donne unknown pour les deux opérateurs NACE. |
Libellés
Une règle peut avoir son propre label ({ nl, fr, en, de }), en général les termes de la page officielle ; à défaut, le champ est absent de l’enregistrement. Un libellé est alors généré à partir du champ, de l’opérateur et de la valeur, dans chaque langue du service : Project cost at least €25,000, Projectkost minstens € 25.000, Coût du projet au moins 25 000 €. Les reasons d’un résultat portent le libellé dans la langue demandée.
Provenance et statut de vérification
Chaque condition indique d’où elle vient :
| Champ | Signification |
|---|---|
| method | structuredhtml_sectiontext_patternsource_categorykeywordscuratedderived |
| source_url | La page d’où la règle a été lue. |
| source_section | Le titre de la section d’où elle a été lue (« Wie komt in aanmerking? », « Art. 1:24 WVV »). |
| review_status | auto : produite à partir d’un champ structuré. unreviewed : extraite du texte par un motif. verified : vérifiée d’après la page officielle, à la date reviewed_at. |
| reviewed_at | YYYY-MM-DD, pour les règles vérifiées. |
| note | Ce que la règle ne peut pas voir, ou pourquoi elle est écrite ainsi. |
D’où viennent les règles
- À partir de champs structurés : une mesure régionale reçoit une règle
region(contains_anysurcompany.regions), une restriction de taille une règlesize, une liste de types de demandeurs une règleapplicant_type, des listes de secteurs des règlesnaceetnace_excluded. Leurreview_statusestauto. - À partir de motifs dans le texte (un âge maximal ou minimal de l’entreprise, par exemple) :
methodvauttext_pattern,review_statusvautunreviewed. - Rédigées d’après la page officielle :
methodvautcurated,review_statusvautverified. Une telle règle remplace la règle automatique de même id.
Le rules_basis de la mesure résume cela (none, derived, extracted, curated), et sa confidence indique dans quelle mesure les règles couvrent ce qui détermine l’éligibilité : 0,9 pour les règles rédigées à la main sauf indication contraire, 0,6 pour les règles extraites, 0,45 pour les règles déduites. Seules des règles curated ou extracted à 0,7 ou plus peuvent rendre un résultat likely_eligible.
Ce que les règles ne voient pas
