Series compared
Two to five series from any family, over the same interval, aligned on period. It is the only place in the module where the data mixes freely: ROBOR next to a credit risk aggregate, the exchange rate next to inflation.
The alignment is declared, not assumed — that is the very reason for the route. The catalogue holds 2,492 monthly series, 1,806 quarterly, 1,359 annual and 177 daily, and each family is anchored to the start of its period. A quarterly series naively placed next to a daily one appears as four points a year, all in January, April, July and October, with gaps between them.
The common denominator is the COARSEST periodicity requested, never the finest: going down would require inventing the missing values — repeating a quarterly figure across ninety days as if it had been measured on each. Going up requires only an aggregation function, and the function is declared: the same data aggregated with medie or with ultima gives different charts. serii[].agregata says exactly which series was compressed.
aliniere=brut matches nothing: each series keeps its points exactly as published.
The codes are not guessed. Three-month ROBOR is not ROBOR3M, it is BBZ_BOR3M — a non-existent code gets a 404 with suggestions from the catalogue, searched both in the code and in the name.
Register descriptors are refused explicitly: 45 „series" carry the periodicity necunoscut and have 11 values in total — they are register fields (REMO_STARE, RFSO_ADR), not time series. Requested here, they would produce an empty column that looks like missing data.
In the aligned table, null means „the series did not publish in this period", not zero.
Query parameters
YYYY-MM-DD.
e.g. 2024-01-01
YYYY-MM-DD.
e.g. 2024-03-31
perioada (default) or brut.
perioadabrut
medie. Others: min, max, ultima. Only matters for series finer than the common denominator.
medieminmaxultima
/financiar/v1/serii), not names.
e.g. BBZ_BOR3M,BBZ_BID3M
How it behaves
- Two to five series from any family, over the same interval, aligned on period. It is the one place in this module where the data mixes freely: ROBOR next to a credit-risk aggregate, exchange rates next to inflation.
- Alignment is declared, not assumed — that is the whole point of the route. The catalogue holds 2,492 monthly series, 1,806 quarterly, 1,359 annual and 177 daily, and each family is anchored to the start of its own period. A quarterly series naively placed beside a daily one shows up as four points a year, all in January, April, July and October, with gaps between them.
- The common denominator is the COARSEST periodicity requested, never the finest: going down would require inventing the missing values — repeating a quarterly figure across ninety days as if it had been measured on each. Going up only needs an aggregation function.
- The function matters, so it is declared. ROBOR 3M in January 2026 gives 5.978333 under
medieand 5.87 underultima— same data, different chart.serii[].agregatasays exactly which series was compressed, and from how many points. aliniere=brutmatches nothing up: every series keeps its points exactly as published, with their original anchoring. The response then has noranduri, butserii[].valori.- Codes are not guessable. Three-month ROBOR is not
ROBOR3M, it isBBZ_BOR3M. A code that does not exist gets a 404 with suggestions searched in both the code and the name —ROBOR3Mreturns all eight ROBOR series. - Register descriptors are refused explicitly: 45 "series" carry the periodicity
necunoscutand hold 11 values in total — they are register fields (REMO_STARE,RFSO_ADR), not time series. Requested here, they would produce an empty column that looks like missing data. - In the aligned table,
nullmeans "the series published nothing in that period", not zero. - The table is capped at 1,000 rows: two daily series over six years would give 1,666, and the response would stop being read and start being downloaded.
What it is for
- A chart with series from different families, already aligned.
- Checking a correlation between an interest-rate index and a monetary aggregate.
- Pulling a report-ready table without aligning it by hand.
Response structure
aliniere=perioada.
true when the series was compressed to the common denominator.
2026-01-15, 2026-01, 2026-T1, 2026-S1 or 2026.
null = the series published nothing in that period.
aliniere=brut.
aliniere=brut.
Response examples
{
"data": {
"de_la": "2024-01-01",
"pana_la": "2024-03-31",
"aliniere": "perioada",
"periodicitate": "zilnic",
"agregare": "medie",
"serii": [
{
"cod": "BBZ_BOR3M",
"nume": "ROBOR 3 luni",
"clasa": "ROBID - ROBOR - serii zilnice",
"unitate": "% p.a.",
"periodicitate": "zilnic",
"puncte_sursa": 62,
"agregata": false,
"acoperire": {
"de_la": "1995-08-01",
"pana_la": "2026-09-21"
}
}
],
"randuri": [
{
"perioada": "2024-01-03",
"valori": {
"BBZ_BOR3M": "6.21",
"BBZ_BID3M": "5.92"
}
}
]
},
"meta": {
"sursa": "BNR — baza de date interactivă.",
"randuri": 62,
"puncte_sursa": 124,
"nota_aliniere": "Numitorul comun e cea mai GROSIERĂ periodicitate cerută. Coborârea către cea mai fină ar cere inventarea valorilor lipsă, deci nu se face. `serii[].agregata` spune care serie a fost comprimată.",
"nota_agregare": "Funcţia contează: aceleaşi date agregate cu `medie` sau cu `ultima` dau grafice diferite. De aceea e declarată, nu implicită tăcut.",
"nota_null": "În `randuri`, `null` înseamnă „seria n-a publicat în perioada asta\", nu zero.",
"nota_ancorare": "Fiecare familie e ancorată la începutul perioadei ei: anualele pe 1 ianuarie, trimestrialele pe prima zi a trimestrului, lunarele pe întâi.",
"catalog": "/financiar/v1/serii"
}
}
{
"data": {
"de_la": "2024-01-01",
"pana_la": "2024-03-31",
"aliniere": "perioada",
"periodicitate": "zilnic",
"agregare": "medie",
"serii": [
{
"cod": "BBZ_BOR3M",
"nume": "ROBOR 3 luni",
"clasa": "ROBID - ROBOR - serii zilnice",
"unitate": "% p.a.",
"periodicitate": "zilnic",
"puncte_sursa": 62,
"agregata": false,
"acoperire": {
"de_la": "1995-08-01",
"pana_la": "2026-09-21"
}
}
],
"randuri": [
{
"perioada": "2024-01-03",
"valori": {
"BBZ_BOR3M": "6.21",
"BBZ_BID3M": "5.92"
}
}
]
},
"meta": {
"sursa": "BNR — baza de date interactivă.",
"randuri": 62,
"puncte_sursa": 124,
"nota_aliniere": "Numitorul comun e cea mai GROSIERĂ periodicitate cerută. Coborârea către cea mai fină ar cere inventarea valorilor lipsă, deci nu se face. `serii[].agregata` spune care serie a fost comprimată.",
"nota_agregare": "Funcţia contează: aceleaşi date agregate cu `medie` sau cu `ultima` dau grafice diferite. De aceea e declarată, nu implicită tăcut.",
"nota_null": "În `randuri`, `null` înseamnă „seria n-a publicat în perioada asta\", nu zero.",
"nota_ancorare": "Fiecare familie e ancorată la începutul perioadei ei: anualele pe 1 ianuarie, trimestrialele pe prima zi a trimestrului, lunarele pe întâi.",
"catalog": "/financiar/v1/serii"
}
}
{
"data": {
"de_la": "2024-01-01",
"pana_la": "2024-03-31",
"aliniere": "perioada",
"periodicitate": "zilnic",
"agregare": "max",
"serii": [
{
"cod": "BBZ_BOR3M",
"nume": "ROBOR 3 luni",
"clasa": "ROBID - ROBOR - serii zilnice",
"unitate": "% p.a.",
"periodicitate": "zilnic",
"puncte_sursa": 62,
"agregata": false,
"acoperire": {
"de_la": "1995-08-01",
"pana_la": "2026-09-21"
}
}
],
"randuri": [
{
"perioada": "2024-01-03",
"valori": {
"BBZ_BOR3M": "6.21",
"BBZ_BID3M": "5.92"
}
}
]
},
"meta": {
"sursa": "BNR — baza de date interactivă.",
"randuri": 62,
"puncte_sursa": 124,
"nota_aliniere": "Numitorul comun e cea mai GROSIERĂ periodicitate cerută. Coborârea către cea mai fină ar cere inventarea valorilor lipsă, deci nu se face. `serii[].agregata` spune care serie a fost comprimată.",
"nota_agregare": "Funcţia contează: aceleaşi date agregate cu `medie` sau cu `ultima` dau grafice diferite. De aceea e declarată, nu implicită tăcut.",
"nota_null": "În `randuri`, `null` înseamnă „seria n-a publicat în perioada asta\", nu zero.",
"nota_ancorare": "Fiecare familie e ancorată la începutul perioadei ei: anualele pe 1 ianuarie, trimestrialele pe prima zi a trimestrului, lunarele pe întâi.",
"catalog": "/financiar/v1/serii"
}
}
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 | nu_e_serie_temporala | The code exists but is a register field; its records are at /registre. |
| 422 | nu_e_serie_de_timp | The code is a register descriptor. prea_multe_randuri — the table would exceed 1,000 rows. Fewer than two series, more than five, or parameters outside the lists. serie_inexistenta — one of the codes is not in the catalogue; the response offers suggestions. |
| 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": "nu_e_serie_de_timp",
"mesaj": "The code is a register descriptor. prea_multe_randuri — the table would exceed 1,000 rows. Fewer than two series, more than five, or parameters outside the lists. serie_inexistenta — one of the codes is not in the catalogue; the response offers suggestions.",
"detalii": {
"de_la": [
"The value sent does not satisfy the parameter rule."
]
}
}
}