PhynanxPhynanx

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

KeyContent
idIdentifier of the step within its module.
moduleIdModule that produced it (fr_tva_standard_2025…), linked to its register of mechanisms.
descriptionFrWhat the step does, in French.
formulaThe formula applied, in readable form.
inputsThe values read, by name (amounts as decimal strings).
outputThe value produced.
citationsThe 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…).