oneapi
Sign in
Financiar v1 / Conversie

Conversion at the official NBR rate

Converts an amount between the leu and a currency, in either direction, at the NBR reference rate of a date (the current day by default). The result comes rounded to 2 decimals and exact.

For conversion between two foreign currencies, which passes through the leu and is not an official rate, use /conversie/incrucisata.

GET
https://oneapi.ro/api/financiar/v1/conversie

Query parameters

NameTypeDescriptionAccepted values
sumarequired string Required. Decimal point, at most 6 decimals, no thousands separators and no scientific notation (1000, 1234.56). e.g. 1000e.g. 500
dinrequired string Source currency: a three-letter code or RON. max 3 car.
inrequired string Target currency: a three-letter code or RON. max 3 car.
dataoptional string | null Optional, YYYY-MM-DD. Defaults to the current day. If the day has no publication, the last preceding quote is used. e.g. 2024-06-15e.g. 2024-02-01

How it behaves

  • Converts an amount at the NBR rate of a given date (the current day by default). The result comes in two forms: suma_convertita rounded to 2 decimals and suma_convertita_exacta unrounded.
  • Use the exact form if the result feeds another calculation, and round once, at the end. Rounding at every step of a chain accumulates error in proportion to the size of the amounts.
  • curs.factor is the number the amount was multiplied by, in either direction: suma × factor = suma_convertita_exacta, digit for digit. That makes the result verifiable without reproducing the logic, whether it is currency → leu, leu → currency, or currency → currency. The factor carries up to 12 decimals, and the exact result follows from it without truncation.
  • The route covers ONLY conversions in which the leu appears, in one direction or the other. For two foreign currencies the parity is not published by NBR and is computed through the leu — a different algorithm and a different legal status, hence a different route: /conversie/incrucisata. A request with two foreign currencies here returns 422 and points to the right route.
  • Both quotes must come from the same day. If they do not, the request is refused with 409 rather than producing a cross rate between two market days — a plausible wrong result is worse than an error.
  • When din and in are the same currency, the amount passes through unchanged, with factor: "1" and no date: no quote was used. It is not an error, so a client converting a list need not handle the case separately.
  • Negative amounts and zero are allowed — credit notes are negative. Half-way rounding goes away from zero: −0.005 → −0.01.
  • The whole calculation is in exact decimal arithmetic, not floating point, and amounts travel as strings: a float in JSON means rounding errors in someone's money.

What it is for

  • Converting a foreign-currency invoice at the rate of the invoice date.
  • Displaying a price in another currency.

Response structure

FieldTypeDescription
data.suma string Sum of the values, in the unit indicated alongside.
data.din string
data.in string
data.suma_convertita string The result rounded to 2 decimals, half up. The form to print.
data.suma_convertita_exacta string The unrounded result. The form to use in further calculations.
data.curs.factor string The number the amount was multiplied by. suma × factor = suma_convertita_exacta.
data.curs.componente[] array The NBR quotes used, with the published value and the multiplier. Empty when the currencies are identical.
data.curs.componente[].valuta string ISO 4217 currency code.
data.curs.componente[].valoare string The value published by the source for the combination above.
data.curs.componente[].multiplicator integer Factor the value is multiplied by to reach the base unit.
data.curs.componente[].valoare_unitara string The value per single unit.
data.curs.data string The day the quote comes from. null when the currencies are identical.
data.curs.data_ceruta string The date the client asked for, before alignment to a day that has data.
data.curs.exact boolean true if the quote is from the requested day.
data.curs.zile_inapoi integer
meta.sursa string The official source the data comes from, with its licence where one is required.
meta.curs string
meta.rotunjire string
meta.nota string A note on how to read the response — a pitfall, a convention or a limit of the source.
meta.fara_date string data is null and this says why. The requested date is before 2005-01-03.
meta.fara_date_cod string The short, STABLE word for the reason, for clients that branch on it in code: fara_date is prose and may be rephrased, this is not.

Response examples

GEThttps://oneapi.ro/api/financiar/v1/conversie?suma=1000&din=EUR&in=RON&data=2024-06-15
{
    "data": {
        "suma": "1000",
        "din": "EUR",
        "in": "RON",
        "suma_convertita": "4977.10",
        "suma_convertita_exacta": "4977.1",
        "curs": {
            "factor": "4.9771",
            "componente": [
                {
                    "valuta": "EUR",
                    "valoare": "4.9771",
                    "multiplicator": 1,
                    "valoare_unitara": "4.9771"
                }
            ],
            "data": "2024-06-14",
            "data_ceruta": "2024-06-15",
            "exact": false,
            "zile_inapoi": 1
        }
    },
    "meta": {
        "sursa": "Banca Naţională a României",
        "curs": "oficial",
        "rotunjire": "2 zecimale, jumătate în sus. `suma_convertita_exacta` e nerotunjită — foloseşte-o dacă rezultatul intră într-un alt calcul.",
        "nota": "Ziua cerută nu are publicare; s-a folosit ultima cotaţie anterioară."
    }
}

Error codes

CodeSlugWhen it occurs
401neautentificatToken missing, invalid, expired or revoked.
403feature_indisponibilThe current plan does not include the feature the route depends on.
404negasitnegasit = unknown currency; delistata = the currency is no longer quoted.
422validarenu_e_curs_oficial = both currencies are foreign, use /conversie/incrucisata. Or: malformed amount, invalid currency code, future date.
429cota_depasitaThe 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": "nu_e_curs_oficial = both currencies are foreign, use /conversie/incrucisata. Or: malformed amount, invalid currency code, future date.",
        "detalii": {
            "suma": [
                "The value sent does not satisfy the parameter rule."
            ]
        }
    }
}