oneapi
Sign in
Financiar v1 / RiscCredit

Balance of payments

The BPM6 balance of payments — 208 positions, monthly since January 2005 and quarterly, with exactly the same codes at both frequencies. The current account balance in May 2026: −2,711.0 million euro.

The structure is flow × position. Six flows — credit, debit, balance, net assets, net liabilities, net — over a tree up to five levels deep: „CURRENT ACCOUNT; Goods; Merchanting — net exports; Merchanting — goods…". 94 positions sit at level four and 57 at level five, which is why nivel_max exists, so you can ask for the upper structure only.

The identity balance = credit − debit closes on every pair, but only with a tolerance of ±1 million — and the tolerance is not chosen out of caution, it is measured. On the current account, the deviation is exactly 0 or exactly 1, never anything else — meta.nota_identitate gives the count over the whole series: the independent rounding of three figures expressed in millions. With a tolerance of 0.51 the identity would have appeared to fail in a quarter of the months. identitati.toleranta declares it, so that „every pair closes" does not sound louder than it is.

The identity check is run on every position, not on the ones returned: a filter on flux=sold must not be allowed to make the guarantee disappear.

The hierarchy comes from the name, which carries the full path. The code prefix gives the same parent in all 192 cases today, but that is a coincidence of construction, so parinte is taken from the path, without assumptions.

The positions with no value across the whole series sit at different depths — down to level four — so they are recognised by the absence of values over the WHOLE series, not by the length of the code. este_antet marks them.

Merchanting changed its sign convention: until 2012 1BM = 1BMV − 1BMA, with purchases positive; from 2013 1BM = 1BMA + 1BMV, with purchases negative. 1Z ("Goods and services") is a sibling of 1B and 1S, not their parent: summing the current account's children counts them twice.

Periods are written YYYY-MM at both frequencies; for the quarterly one, the quarter's first month.

GET
https://oneapi.ro/api/financiar/v1/balanta-plati

Query parameters

NameTypeDescriptionAccepted values
frecventaoptional string | null Optional, defaults to lunar. Or trimestrial — the same 208 positions. lunartrimestrial
de_laoptional string | null Optional, YYYY-MM. Without it, the last published period. e.g. 2024-06-15
pana_laoptional string | null Optional, YYYY-MM. At most 120 periods. e.g. 2024-06-15
fluxoptional string | null Optional: credit, debit, sold, active_nete, pasive_nete, net. creditdebitsoldactive_netepasive_netenet
nivel_maxoptional integer | null Optional, 1–5. Limits the depth of the tree. 1 – 5

How it behaves

  • The balance of payments under the BPM6 methodology — 208 positions, monthly since January 2005 and quarterly. The current account balance in May 2026: −2,711.0 million euro (credit 13,161, debit 15,872).
  • Both frequencies carry EXACTLY the same codes — verified, zero differences in either direction. It is the same structure at a different granularity, so one route with a parameter rather than two that would drift apart at the first correction.
  • The structure is flow × position. Six flows — credit, debit, balance, net acquisition of assets, net incurrence of liabilities, net — over a tree up to five levels deep: "CURRENT ACCOUNT; Goods; Merchanting - net exports; Merchanting - goods...". 94 positions sit at level four and 57 at level five, which is why nivel_max exists.
  • The identity balance = credit − debit closes across every pair, but only within ±1 million — and the tolerance is MEASURED, not chosen out of caution. On the current account, the deviation is exactly 0 or exactly 1, never anything else — meta.nota_identitate gives the count over the whole series: the independent rounding of three figures expressed in millions. With a tolerance of 0.51 the identity would have looked like it failed in a quarter of the months. identitati.toleranta declares it, so "every pair closes" does not sound stronger than it is.
  • The identity is checked over ALL positions, not the returned ones. A filter of flux=sold returns two positions, yet the identity still reports its 32 verified pairs: it is the guarantee that the figures tie together, and it must not vanish with a filter.
  • The hierarchy comes from the name, which carries the full path. The code prefix gives the same parent in all 192 cases today, but that is a coincidence of construction, not a declared rule — so parinte is resolved from cale, without assumptions. Verified: zero unresolved parents.
  • Six positions have no value across the whole series and sit at different depths — down to level four: merchanting and reserve-asset income on the debit side, reserve assets on the liabilities side and so on, where BPM6 records nothing. They cannot be recognised by code length, only by the absence of values over the WHOLE series — not over the requested window, where a series starting later would look empty. este_antet flags them.
  • Merchanting changed its sign convention. Until 2012 1BM = 1BMV − 1BMA, with purchases (1BMA) positive; from 2013 1BM = 1BMA + 1BMV, with purchases negative. A single formula does not close both periods.
  • 1Z ("Goods and services") is a sibling of 1B and 1S, not their parent: 1Z = 1B + 1S in every month. Do not add up all the children of the current account — goods and services would be counted twice.
  • Periods are written YYYY-MM at both frequencies; for quarterly, the first month of the quarter. At most 120 periods.

What it is for

  • The current account deficit, month by month, with its components.
  • Exports and imports of services by category — transport, travel, IT.
  • The financial account: direct investment, portfolio investment, reserve assets.

Response structure

FieldTypeDescription
data.frecventa string How often the source publishes the series (daily, monthly, quarterly, yearly).
data.de_la string Start of the interval the response covers.
data.pana_la string End of the interval the response covers, inclusive.
data.unitate string Always milioane EUR.
data.filtre array The filters actually applied, as the route understood them — useful when a value was normalised.
data.perioade array Periods for which values exist.
data.pozitii[].cod string Code from the source code list — the key you filter on.
data.pozitii[].flux string Which of the six flows.
data.pozitii[].eticheta string Display label for the value — the readable version of the code next to it.
data.pozitii[].cale array The hierarchical path, without the flow segment that opens it.
data.pozitii[].nivel integer Depth in the tree, 1–5.
data.pozitii[].parinte null The parent position's code, resolved from the path. null at roots.
data.pozitii[].unitate string Unit of measure of the values. Read it before plotting or summing them.
data.pozitii[].este_antet boolean true for positions with no value across the whole series (not just the window).
data.pozitii[].luni_publicate integer In how many periods of the window the position actually has a value.
data.pozitii[].valori object The values of the series, by period.
data.identitati.identitate string The identity being checked — which sum must equal which total.
data.identitati.perechi_verificate integer How many (balance, credit, debit) triples could be checked — across all positions, not only the returned ones.
data.identitati.perechi_inchise integer How many checked pairs closed within tolerance.
data.identitati.abatere_maxima string Largest deviation found between the sum of components and the total.
data.identitati.toleranta string The rounding tolerance, in millions. Measured from the distribution of deviations.
meta.sursa string The official source the data comes from, with its licence where one is required.
meta.acoperire.de_la string The first period we have data for.
meta.acoperire.pana_la string The last period we have data for.
meta.luni integer Number of months covered.
meta.pozitii_totale integer How many positions match the filters, beyond the current page.
meta.pozitii_returnate integer How many positions this response actually returned.
meta.nota_frecvente string A note on how to read the response: a caveat, a convention or a limit of the source.
meta.nota_identitate string How the identity above is checked and what it means when it does not close.
meta.nota_ierarhie string How to read the classification hierarchy and which levels must not be added together.
meta.nota_antete string A note on how to read the response: a caveat, a convention or a limit of the source.
meta.nota_merchanting string A note on how to read the response: a caveat, a convention or a limit of the source.
meta.nota_1z string A note on how to read the response: a caveat, a convention or a limit of the source.
meta.nota_null string Why some values are missing: the source did not publish, did not compute, or suppressed them.
data.identitati.unde The position and period with the largest deviation. Present only when a pair exceeds the tolerance.
meta.fara_date data is null and this says why. No values for the requested frequency. The interval falls entirely outside the coverage. It overlaps the coverage but holds no values.
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/balanta-plati
{
    "data": {
        "frecventa": "lunar",
        "de_la": "2026-07",
        "pana_la": "2026-07",
        "unitate": "milioane EUR",
        "filtre": [],
        "perioade": [
            "2026-07"
        ],
        "pozitii": [
            {
                "cod": "BOP6L_N_4",
                "flux": "net",
                "eticheta": "ERORI ȘI OMISIUNI",
                "cale": [
                    "ERORI ȘI OMISIUNI"
                ],
                "nivel": 1,
                "parinte": null,
                "unitate": "milioane EUR",
                "este_antet": false,
                "luni_publicate": 1,
                "valori": {
                    "2026-07": "1375.00"
                }
            }
        ],
        "identitati": {
            "identitate": "sold = credit − debit",
            "perechi_verificate": 32,
            "perechi_inchise": 32,
            "abatere_maxima": "1.00",
            "toleranta": "1"
        }
    },
    "meta": {
        "sursa": "BNR — balanţa de plăţi, metodologia BPM6.",
        "acoperire": {
            "de_la": "2005-01",
            "pana_la": "2026-07"
        },
        "luni": 1,
        "pozitii_totale": 202,
        "pozitii_returnate": 202,
        "nota_frecvente": "Lunar şi trimestrial au exact aceleaşi 208 coduri — verificat, zero diferenţe. E aceeaşi structură la altă granularitate.",
        "nota_identitate": "Toleranţa de ±1 milion nu e aleasă din prudenţă, ci măsurată: pe contul curent, pe toată seria, abaterea e exact 0 în 192 perioade şi exact 1 în 67 — rotunjirea a trei cifre exprimate în milioane. Verificarea se face pe toate poziţiile, nu pe cele întoarse de filtre.",
        "nota_ierarhie": "`cale` şi `parinte` vin din denumire, care poartă calea completă. Prefixul codului dă azi acelaşi părinte, dar e o coincidenţă de construcţie, nu o regulă declarată de sursă.",
        "nota_antete": "6 poziţii n-au nicio valoare pe toată seria — BPM6 nu înregistrează nimic acolo (merchanting şi venituri din active de rezervă la debit, active de rezervă la pasive ş.a.) — şi stau la adâncimi diferite. `este_antet` le marchează, socotit pe toată seria, nu pe fereastra cerută.",
        "nota_merchanting": "Merchanting-ul şi-a schimbat convenţia de semn: până în 2012 `1BM = 1BMV − 1BMA`, cu achiziţiile (`1BMA`) pozitive; din 2013 `1BM = 1BMA + 1BMV`, cu achiziţiile negative. Aceeaşi formulă nu închide ambele perioade.",
        "nota_1z": "`1Z` („Bunuri şi servicii\") e frate cu `1B` şi `1S` sub contul curent, nu părintele lor: `1Z = 1B + 1S`. Nu aduna toţi copiii contului curent — bunurile şi serviciile s-ar număra de două ori.",
        "nota_null": "`null` într-o perioadă înseamnă că poziţia n-a fost publicată atunci, nu zero."
    }
}

Error codes

CodeSlugWhen it occurs
401neautentificatToken missing, invalid, expired or revoked.
403feature_indisponibilThe current plan does not include the feature the route depends on.
422validareinterval_prea_lung beyond 120 periods, a flow outside the list, or nivel_max outside 1–5. frecventa_necunoscuta — a value outside the list.
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": "interval_prea_lung beyond 120 periods, a flow outside the list, or nivel_max outside 1–5. frecventa_necunoscuta — a value outside the list.",
        "detalii": {
            "frecventa": [
                "The value sent does not satisfy the parameter rule."
            ]
        }
    }
}