Foreign exchange differences
The gain or loss on exchange for an amount in foreign currency, between two dates, at the official NBR rate.
The same rate movement gives opposite results depending on what you hold. On 100,000 EUR, between January 2025 and August 2026, the rate rose by 0.2786 lei — 27,860 lei. On a receivable that is a gain: you collect more lei. On a payable it is a loss: you pay more. The figure is identical, the sign is reversed.
That is why pozitie is required, with no default: a default would silently make half the answers wrong.
The quotations follow the rules of /curs: a day with no publication takes the last previous quotation, flagged with exact: false and zile_inapoi. The same day at both ends gives a zero difference, not an error — anyone running a report over a list of invoices should not have to special-case it.
cont_orientativ gives the account from the general chart (765 favourable, 665 unfavourable). It is indicative: the classification depends on accounting policy and on the nature of the transaction, not on our data.
Query parameters
EUR, USD).
max 3 car.
creanta (you are owed) or datorie (you owe). No default.
creantadatorie
YYYY-MM-DD. The initial date — typically the invoice date.
e.g. 2024-06-15e.g. 2024-01-15
YYYY-MM-DD. The final date — typically collection or payment. May equal de_la.
e.g. 2024-06-15e.g. 2024-06-14
How it behaves
- The exchange gain or loss on a foreign-currency amount, between two dates, at the official NBR rate.
- The same rate movement produces OPPOSITE results depending on what you hold. On EUR 100,000, between January 2025 and August 2026, the rate rose by 0.2786 lei — RON 27,860. On a receivable that is a gain: you collect more lei. On a payable it is a loss: you pay more. The figure is identical, the sign is reversed, and this is where the mistake is most often made.
pozitieis required, with no default. A default would silently make half the answers wrong, and the mistake would not stand out: the figure would be right in magnitude. The same decision astipon/termen/civil, where the absence of a default is deliberate because the choice changes the result.diferenta.valoareis the ACCOUNTING figure, signed according to the position.diferenta.variatie_valoare_leiis the plain change in the lei value, the same regardless of position — both are in the response precisely so the relationship between them is visible.- Quotes follow the
/cursrules: a day without publication receives the last preceding quote, marked withexact: falseandzile_inapoi, separately at each end. Quotes are never invented and the substitution is never hidden. - The same day at both ends gives a zero difference, not an error. Anyone running a report over a list of invoices need not special-case it. The kind is then
neutra, and no account is given. cont_orientativgives the account from the Romanian general chart (Order 1802/2014): 765 for favourable differences, 665 for unfavourable. It is indicative, and marked as such: the classification depends on accounting policy and on the nature of the operation — settlement or revaluation — not on our data.- Partial payments and instalment settlements are not handled: one amount, two dates. A stream of payments is a different question with a different response shape.
- To revalue a BALANCE at period end, the closing rate is used rather than that of an arbitrary day:
/curs-inchidere?luna=YYYY-MM.
What it is for
- The exchange difference on collecting an invoice issued in foreign currency.
- The difference on settling a foreign-currency payable.
- Checking the sign in someone else's calculation.
Response structure
false when the requested day had no publication and an earlier one was used.
favorabila, nefavorabila or neutra.
765 or 665. Indicative — see the note.
data is null and this says why. The quote exists at the NBR, but our import is behind. The requested date is before 2005-01-03, where quotes are in old lei.
fara_date is prose and may be rephrased, this is not.
Response examples
{
"data": {
"suma": "1000",
"valuta": "EUR",
"pozitie": "creanta",
"initial": {
"data_ceruta": "2024-06-15",
"data_cotatiei": "2024-06-14",
"exact": false,
"zile_inapoi": 1,
"curs": "4.9771",
"valoare_lei": "4977.10"
},
"final": {
"data_ceruta": "2024-06-15",
"data_cotatiei": "2024-06-14",
"exact": false,
"zile_inapoi": 1,
"curs": "4.9771",
"valoare_lei": "4977.10"
},
"miscare_curs": {
"lei_pe_unitate": "0",
"procent": "0.00"
},
"diferenta": {
"valoare": "0.00",
"valoare_exacta": "0",
"fel": "neutra",
"variatie_valoare_lei": "0.00",
"cont_orientativ": null
}
},
"meta": {
"sursa": "BNR — cursul de referinţă.",
"nota_pozitie": "Cursul nu s-a mişcat între cele două date: diferenţa e zero, indiferent de poziţie.",
"nota_substituire": "Cel puţin una dintre zile n-a avut publicare; s-a folosit ultima cotaţie anterioară. Vezi `exact` şi `zile_inapoi` la fiecare capăt.",
"reevaluare": "Pentru reevaluarea unui sold la închiderea perioadei se foloseşte cursul de închidere: /financiar/v1/curs-inchidere?luna=AAAA-LL."
}
}
{
"data": {
"suma": "2500.75",
"valuta": "EUR",
"pozitie": "creanta",
"initial": {
"data_ceruta": "2024-06-15",
"data_cotatiei": "2024-06-14",
"exact": false,
"zile_inapoi": 1,
"curs": "4.9771",
"valoare_lei": "12446.48"
},
"final": {
"data_ceruta": "2024-06-15",
"data_cotatiei": "2024-06-14",
"exact": false,
"zile_inapoi": 1,
"curs": "4.9771",
"valoare_lei": "12446.48"
},
"miscare_curs": {
"lei_pe_unitate": "0",
"procent": "0.00"
},
"diferenta": {
"valoare": "0.00",
"valoare_exacta": "0",
"fel": "neutra",
"variatie_valoare_lei": "0.00",
"cont_orientativ": null
}
},
"meta": {
"sursa": "BNR — cursul de referinţă.",
"nota_pozitie": "Cursul nu s-a mişcat între cele două date: diferenţa e zero, indiferent de poziţie.",
"nota_substituire": "Cel puţin una dintre zile n-a avut publicare; s-a folosit ultima cotaţie anterioară. Vezi `exact` şi `zile_inapoi` la fiecare capăt.",
"reevaluare": "Pentru reevaluarea unui sold la închiderea perioadei se foloseşte cursul de închidere: /financiar/v1/curs-inchidere?luna=AAAA-LL."
}
}
{
"data": {
"suma": "10000",
"valuta": "USD",
"pozitie": "datorie",
"initial": {
"data_ceruta": "2024-01-15",
"data_cotatiei": "2024-01-15",
"exact": true,
"zile_inapoi": 0,
"curs": "4.5481",
"valoare_lei": "45481.00"
},
"final": {
"data_ceruta": "2024-06-14",
"data_cotatiei": "2024-06-14",
"exact": true,
"zile_inapoi": 0,
"curs": "4.6576",
"valoare_lei": "46576.00"
},
"miscare_curs": {
"lei_pe_unitate": "0.1095",
"procent": "2.41"
},
"diferenta": {
"valoare": "-1095.00",
"valoare_exacta": "-1095",
"fel": "nefavorabila",
"variatie_valoare_lei": "1095.00",
"cont_orientativ": "665"
}
},
"meta": {
"sursa": "BNR — cursul de referinţă.",
"nota_pozitie": "Rezultatul depinde de `pozitie`: aceeaşi mişcare de curs e pierdere la datorie şi câştig la creanţă.",
"nota_cont": "Contul 665 e ORIENTATIV (plan general OMFP 1802/2014). Încadrarea ţine de politica contabilă şi de natura operaţiunii — decontare sau reevaluare — nu de datele noastre.",
"reevaluare": "Pentru reevaluarea unui sold la închiderea perioadei se foloseşte cursul de închidere: /financiar/v1/curs-inchidere?luna=AAAA-LL."
}
}
Error codes
| Code | Slug | When it occurs |
|---|---|---|
| 401 | neautentificat | Token missing, invalid, expired or revoked. |
| 403 | feature_indisponibil | The current plan does not include the feature the route depends on. |
| 404 | negasit | The currency was never quoted; delistata — no longer quoted, with the last day. |
| 422 | validare | Missing or invalid pozitie; malformed amount, currency or dates; future date; pana_la before de_la. |
| 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": "validare",
"mesaj": "Missing or invalid pozitie; malformed amount, currency or dates; future date; pana_la before de_la.",
"detalii": {
"suma": [
"The value sent does not satisfy the parameter rule."
]
}
}
}