The trace
Each calculation returns, next to its outputs, the ordered list of the steps that lead to them: this is what the
interface displays so that a result can be redone by hand. The trace is served by default; ?trace=false leaves it
out.
A step
| Key | Content |
|---|---|
id | Identifier of the step within its module. |
moduleId | Module that produced it (fr_tva_standard_2025…), linked to its register of mechanisms. |
descriptionFr | What the step does, in French. |
formula | The formula applied, in readable form. |
inputs | The values read, by name (amounts as decimal strings). |
output | The value produced. |
citations | The texts on which the step rests: authority (CGI, BOFiP, CSS, LoiFinances, BOSS, URSSAF…), reference, url (Légifrance when it exists), asOfDate (date of the version cited). |
The authorities are French: the General Tax Code (code général des impôts, CGI), the official tax doctrine (Bulletin officiel des finances publiques, BOFiP), the Social Security Code (code de la sécurité sociale, CSS), the Finance Acts (lois de finances), the official social security bulletin (Bulletin officiel de la Sécurité sociale, BOSS) and the publications of the Urssaf. A citation points to the French text, the only authoritative version: the API serves no translation of a legal text presented as official.
Example run by the engine, with the trace:
curl -s -X POST "http://localhost:3001/v1/calculators/calcul-tva-2025/calculate" \
-H "Content-Type: application/json" \
-d '{"montantHT":"100"}'
Response: status 200.
{
"slug": "calcul-tva-2025",
"version": "1.0.0",
"legalCorrections": [],
"engineExtensions": [],
"result": {
"montantTVA": "20",
"montantTTC": "120"
},
"cotisations": [],
"steps": [
{
"id": "calcul_tva",
"descriptionFr": "Application du taux normal de TVA (20 %)",
"formula": "montantHT × 20 %",
"inputs": {
"montantHT": "100"
},
"output": "20",
"citations": [
{
"authority": "CGI",
"reference": "art. 278",
"url": "https://www.legifrance.gouv.fr/codes/article_lc/LEGIARTI000026950057/",
"asOfDate": "2014-01-01"
}
],
"moduleId": "fr_tva_standard_2025"
},
{
"id": "calcul_ttc",
"descriptionFr": "Calcul du montant TTC",
"formula": "montantHT + montantTVA",
"inputs": {
"montantHT": "100",
"montantTVA": "20"
},
"output": "120",
"citations": [],
"moduleId": "fr_tva_standard_2025"
}
],
"warnings": [],
"rulesVersion": "[email protected]"
}
Contributions
For a payroll calculator, cotisations details each social security contribution: group (salariale for the
employee share or patronale for the employer share), montant, base, taux, its own steps and warnings. It is
empty for the other calculators, and with ?trace=false.
Warnings
warnings lists, in French, the non-blocking remarks of the calculation: rule set aside because a condition is not
met, value not filled in and taken by default.
Differences with the official simulator
The engine follows the text applicable to the income of the year (CGI, enforceable BOFiP doctrine, official form of the campaign). The official simulators are used to check it, without being authoritative. Two lists of the response state it for the input sent:
legalCorrections: the points where the simulator of the tax administration (DGFiP) departs from the text and where the engine follows the text. Each entry names its legal basis (legalBasis), the behaviour of the simulator (dgfipBehaviorFr) and that of the engine (correctionFr).engineExtensions: the real cases that the simulator does not handle and that the engine computes from the text (simulatorBehaviorFr,engineBehaviorFr,legalBasis). The amount there cannot be checked against the simulator.
For a client, an empty list means that the result depends on none of these differences.
Explanation
POST /v1/calculators/{slug}/explain receives the same input and returns the deterministic explanation of the
calculation: mechanisms triggered with their legal basis, pinned texts quoted in French (verbatim), differences with
the simulator, and non-blocking questions (questions). As long as a question remains open, present the result as
provisional.
This route speaks English: ?locale=en returns the explanation in English (titles and explanations of the
mechanisms, differences with the simulator, questions). The legal texts stay quoted verbatim in French, the only
authoritative version. The calculation route itself (/calculate) answers in French only (descriptionFr,
warnings, dgfipBehaviorFr…).