Salary net to gross
The gross that produces a given net, with the same breakdown.
⚠️ It cannot be solved algebraically. Every component is rounded to the leu, so the gross → net function is constant over small intervals: several gross figures can give the same net, and some nets are not reachable from any whole gross. The route searches for the gross that gives EXACTLY the net requested, returns the smallest when there are several — and says in the response that there are several — and when there is none, refuses explicitly rather than rounding.
⚠️ When inverting, we do not know the gross until we have found it, so we do not know which allowance band it falls in either. We do not assume one: the engine is given a resolver and asks, for every candidate gross it tries, what allowance that gross carries. That keeps the inversion exact across the whole scale, not just above the threshold at which the allowance is zero.
Request body
Sent as JSON in the request body (Content-Type: application/json) — not in the query string.
YYYY-MM-DD; defaults to today.
intreaga (default) or partiala. On part-time, contributions are computed against the minimum wage, not the actual gross.
intreagapartiala
brut-la-net.
{
"net": 3000
}
{
"net": 5000
}
{
"net": 4000,
"persoane_intretinere": 1
}
{
"net": 10000,
"facilitate": "constructii",
"la_data": "2023-06-15"
}
Query parameters
How it behaves
- The gross that yields a given net, with the same breakdown as
brut-la-net. - ⚠️ It cannot be solved algebraically. Every component is rounded to the leu, so the gross → net function is constant over small intervals: several grosses can yield the same net, and some nets are reached by no whole gross at all. The route searches for the gross that yields exactly the requested net; where several do, it returns the smallest and lists them all in the response; where none does, it refuses with
net_imposibilrather than rounding and appearing to have succeeded. - ⚠️ On inversion we do not know the gross before finding it, so we do not know which deduction bracket applies either. We do not assume one: the engine is handed a resolver and asks, for every candidate gross it tries, what deduction that gross carries. The inversion therefore stays exact across the whole grid, not only above the threshold where the deduction is zero. Example: a net of 2,695 lei on 1 March 2025 gives exactly 4,500 lei.
- ⚠️ POST and zero retention, as with
brut-la-net.
What it is for
- Negotiating a salary from the net, with the corresponding gross cost.
- Checking a payslip in reverse.
Response structure
meta.total_e_limita_de_jos is the word to switch on in code.
brut is null.
data is null and this says why. neacoperit, facilitate_inactiva.
fara_date is prose and may be rephrased, this is not.
Response examples
body: {"net": 3000}
{
"data": {
"net": 3000,
"brut": 5036,
"la_data": "2026-10-07",
"facilitate": null,
"componente": [
{
"cod": "cas",
"denumire": "Contribuţia de asigurări sociale",
"baza_de_calcul": 5036,
"cota": "25%",
"valoare": 1259,
"act_normativ": "Codul Fiscal art.138",
"de_verificat": false
}
]
},
"meta": {
"sursa": "Cotele vin din registrul comun `business_indicatori_fiscali`; facilităţile şi grila deducerii, din `Modules/Financiar/resources/fiscal`, cu act normativ pe fiecare valoare.",
"retentie": "Zero. Intrarea nu se scrie nicăieri — nici în bază, nici în cache, nici în log.",
"nota_acoperire": "Ce e acoperit şi ce nu: /financiar/v1/fiscal/acoperire."
}
}
body: {"net": 5000}
{
"data": {
"net": 5000,
"brut": 8548,
"la_data": "2026-10-07",
"facilitate": null,
"componente": [
{
"cod": "cas",
"denumire": "Contribuţia de asigurări sociale",
"baza_de_calcul": 8548,
"cota": "25%",
"valoare": 2137,
"act_normativ": "Codul Fiscal art.138",
"de_verificat": false
}
]
},
"meta": {
"sursa": "Cotele vin din registrul comun `business_indicatori_fiscali`; facilităţile şi grila deducerii, din `Modules/Financiar/resources/fiscal`, cu act normativ pe fiecare valoare.",
"retentie": "Zero. Intrarea nu se scrie nicăieri — nici în bază, nici în cache, nici în log.",
"nota_acoperire": "Ce e acoperit şi ce nu: /financiar/v1/fiscal/acoperire."
}
}
body: {"net": 4000, "persoane_intretinere": 1}
{
"data": {
"net": 4000,
"brut": 6837,
"la_data": "2026-10-07",
"facilitate": null,
"componente": [
{
"cod": "cas",
"denumire": "Contribuţia de asigurări sociale",
"baza_de_calcul": 6837,
"cota": "25%",
"valoare": 1709,
"act_normativ": "Codul Fiscal art.138",
"de_verificat": false
}
]
},
"meta": {
"sursa": "Cotele vin din registrul comun `business_indicatori_fiscali`; facilităţile şi grila deducerii, din `Modules/Financiar/resources/fiscal`, cu act normativ pe fiecare valoare.",
"retentie": "Zero. Intrarea nu se scrie nicăieri — nici în bază, nici în cache, nici în log.",
"avertismente": [
"Mai multe brute dau acelaşi net (6837, 6838, 6839 lei), fiindcă fiecare componentă se rotunjeşte la leu. Îl întoarcem pe cel mai mic."
],
"nota_acoperire": "Ce e acoperit şi ce nu: /financiar/v1/fiscal/acoperire."
}
}
body: {"net": 10000, "facilitate": "constructii", "la_data": "2023-06-15"}
{
"data": {
"net": 10000,
"brut": 13632,
"la_data": "2023-06-15",
"facilitate": {
"sector": "constructii",
"denumire": "Facilităţi pentru sectorul construcţii",
"act_normativ": "OG 16/2022, art. I pct. 26 (modifică art. 60 pct. 5 din Legea 227/2015), aplicabil veniturilor din ianuarie 2023; Legea 411/2004, art. 43",
"de_verificat": false
},
"componente": [
{
"cod": "cas",
"denumire": "Contribuţia de asigurări sociale",
"baza_de_calcul": 13632,
"cota": "21.25%",
"valoare": 3033,
"act_normativ": "OG 16/2022, art. I pct. 26 (modifică art. 60 pct. 5 din Legea 227/2015), aplicabil veniturilor din ianuarie 2023; Legea 411/2004, art. 43",
"de_verificat": false
}
]
},
"meta": {
"sursa": "Cotele vin din registrul comun `business_indicatori_fiscali`; facilităţile şi grila deducerii, din `Modules/Financiar/resources/fiscal`, cu act normativ pe fiecare valoare.",
"retentie": "Zero. Intrarea nu se scrie nicăieri — nici în bază, nici în cache, nici în log.",
"avertismente": [
"Brutul depăşeşte plafonul facilităţii (10000 lei). Partea de deasupra nu beneficiază de nicio facilitate: se impozitează şi poartă cotele generale de CAS şi CASS, în timp ce partea de dedesubt păstrează cotele facilităţii. Baza impozabilă a părţii de deasupra e calculată scăzând contribuţiile aferente ei — interpretare a textului, nu citat din el."
],
"nota_acoperire": "Ce e acoperit şi ce nu: /financiar/v1/fiscal/acoperire."
}
}
Error codes
| Code | Slug | When it occurs |
|---|---|---|
| 401 | neautentificat | Missing or invalid token. |
| 403 | feature_indisponibil | financiar.fiscal_calcul is not in the current plan. |
| 422 | net_imposibil | No whole gross yields this net. deducere_neacoperita — only for a la_data before 2023. net_lipsa. |
| 429 | cota_depasita | The plan's monthly quota has been exceeded (see Retry-After). |
All errors share the same shape. eroare.cod is stable and is the value you should branch on in code — not the text in mesaj, which may change.
{
"eroare": {
"cod": "net_imposibil",
"mesaj": "No whole gross yields this net. deducere_neacoperita — only for a la_data before 2023. net_lipsa."
}
}