oneapi
Sign in
Financiar v1 / CursVamal

The customs rate for a month

The rate for determining customs value in a month (?luna=YYYY-MM), for every currency or only the ones requested. Without luna, the current month. Coverage starts in May 2016, when Art. 146 of Implementing Regulation (EU) 2015/2447 came into force. It is not the day's rate: it is the NBR quote from the second-to-last Wednesday of the previous month, fixed for the whole month.

GET
https://oneapi.ro/api/financiar/v1/curs-vamal

Query parameters

NameTypeDescriptionAccepted values
lunaoptional string | null Optional: the month, YYYY-MM, from 2016-05. Without it, the current month. e.g. 2024-06
valutalistoptional text Optional filter: ?valuta=EUR,USD. e.g. EURe.g. EUR,USD

How it behaves

  • The rate that applies for determining customs value in a month (?luna=YYYY-MM); without it, the current month.
  • This is not the daily rate. It is the NBR quote from the second-to-last Wednesday of the PREVIOUS month, fixed for the whole month of application (art. 146 of Commission Implementing Regulation (EU) 2015/2447). Using the daily rate on a customs declaration shifts the taxable base by a small difference that is hard to notice.
  • The response carries cotatie_din and penultima_miercuri, so the rule is verifiable: request the same day from /curs/{valuta}?data= and compare. meta.verificare even contains the path.
  • Five currencies are published per 100 units; valoare_unitara is already divided by the multiplier.
  • Coverage starts in May 2016. The figures were checked against the official tables of the Romanian Customs Authority, recovered from the web archive: 1,149 of 1,149 values identical to the fourth decimal.
  • Coverage starts in May 2016, when art. 146 of Reg. (EU) 2015/2447 entered into force. Earlier months are refused with an explanation: until then art. 171 of Reg. 2454/93 applied, which carried a 5% clause — if a Wednesday's quote diverged by at least 5% from the one in use, it replaced it from the following Wednesday, iteratively. That rule broke periods mid-month, and a monthly grid cannot express it. Hence the period is absent from the data rather than approximated.

What it is for

  • Converting customs value on an import declaration.
  • Checking the rate used by a declarant.
  • Computing customs value for a declaration from a past month.
  • Checking a customs declaration filed earlier.
  • Correctly recomputing an import, using that month's rate rather than today's.

Response structure

FieldTypeDescription
data.luna string The month the data refers to.
data.aplicabil_de_la string First day of the month of application.
data.aplicabil_pana_la string Last day of the month of application.
data.moneda_baza string The currency the rates are quoted against.
data.cotatie_din string The day the NBR quote used comes from.
data.penultima_miercuri string The second-to-last Wednesday of the previous month — the art. 146 rule.
data.baza_legala string The legal basis applicable to that month.
data.cotatii[].valuta string ISO 4217 currency code.
data.cotatii[].valoare string The value published by the source for the combination above.
data.cotatii[].multiplicator integer Factor the value is multiplied by to reach the base unit.
data.cotatii[].valoare_unitara string The value per single unit.
meta.sursa string The official source the data comes from, with its licence where one is required.
meta.cotatii integer How many quotations the response covers.
meta.regula string The rule by which the value was computed or chosen.
meta.verificare string Which check was run on the values in the response.
meta.nota string A note on how to read the response — a pitfall, a convention or a limit of the source.
meta.fara_date data is null and this says why. No customs rates in the database.
meta.fara_date_cod 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/curs-vamal?valuta=EUR
{
    "data": {
        "luna": "2026-09",
        "aplicabil_de_la": "2026-09-01",
        "aplicabil_pana_la": "2026-09-30",
        "moneda_baza": "RON",
        "cotatie_din": "2026-08-19",
        "penultima_miercuri": "2026-08-19",
        "baza_legala": "art. 146 Reg. (UE) 2015/2447",
        "cotatii": [
            {
                "valuta": "EUR",
                "valoare": "5.2452",
                "multiplicator": 1,
                "valoare_unitara": "5.2452"
            }
        ]
    },
    "meta": {
        "sursa": "derivat din cursul de referinţă BNR.",
        "cotatii": 1,
        "regula": "Cotaţia BNR din penultima zi de miercuri a lunii anterioare, fixă pe toată luna de aplicare.",
        "verificare": "Cotaţia se poate confrunta cerând /financiar/v1/curs/EUR?data=2026-08-19 (la fel pentru orice valută din grilă).",
        "nota": "Nu e cursul zilei. Folosirea cursului zilnic la o declaraţie vamală schimbă baza de impozitare cu o diferenţă mică, greu de observat."
    }
}

Error codes

CodeSlugWhen it occurs
401neautentificatToken missing, invalid, expired or revoked.
403feature_indisponibilThe current plan does not include the feature the route depends on.
404negasitThe month has no data.
422validareA month written other than YYYY-MM or before 2016-05 (Art. 146 of Reg. (EU) 2015/2447 applies from 1 May 2016).
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": "A month written other than YYYY-MM or before 2016-05 (Art. 146 of Reg. (EU) 2015/2447 applies from 1 May 2016).",
        "detalii": {
            "luna": [
                "The value sent does not satisfy the parameter rule."
            ]
        }
    }
}