oneapi
Sign in
Financiar v1 / Calcul

Late-payment interest at the contractual rate

Late-payment penalties computed at a rate set by CONTRACT — typically „0.05% per day" — not at the statutory interest rate.

A separate route from the statutory penalties, because the rate does not come from our series. There the rate comes from our data and the period is sliced at NBR decisions or at half-years; here the rate is constant and comes from the client, so penalties are sliced at year boundaries, for the 365/366 basis — and, when the statutory ceiling is checked, also at every change of the NBR reference rate.

A check against the legal ceiling. With neprofesional=1, each slice compares the contractual rate against the ceiling in art. 5(1) of Government Ordinance 13/2011 — the statutory rate plus 50%. The customary 0.05%/day clause means 18.25%/year, and the ceiling at the 2026 level is 12.60%/year: exceeded. No verdict of nullity is given — art. 5(2) provides the sanction, but applying it is a matter for a court. The figures are shown and the legal basis is cited.

Between professionals there is no numeric ceiling. Law 72/2013 art. 15 declares „manifestly abusive" clauses abusive, but the assessment is judicial, with no threshold — so nothing is checked, rather than a number being invented.

Capping at the principal (plafon=debit) is a common contractual clause, not a rule of law. When it bites, the response says from which day, and what the figure would have been without it.

GET
https://oneapi.ro/api/financiar/v1/calcul/penalitati/contractuale

Query parameters

NameTypeDescriptionAccepted values
sumarequired string Required. The unpaid debt. e.g. 10000
scadentarequired string Required, YYYY-MM-DD. Interest runs from the following day. e.g. 2024-03-31e.g. 2022-01-31e.g. 2023-06-01
pana_laoptional string | null Optional, defaults to today. e.g. 2024-06-30
procent_zioptional string | null The contractual rate, per day (e.g. 0.05). Excludes procent_an. e.g. 0.05e.g. 0.1
procent_anoptional string | null The contractual rate, per year. Excludes procent_zi. e.g. 18.25e.g. 36.50
plafonoptional string | null debit — penalties do not exceed the debt value. A contractual clause, optional. debit
neprofesionaloptional boolean | null With 1, the art. 5 GO 13/2011 ceiling is checked. e.g. true

How it behaves

  • ⚠️ A due date falling on a non-working day is postponed. Article 2554 of the Civil Code: a term expiring on a non-working day is deemed to expire at the end of the first working day that follows. A due date of 25 December 2024 therefore moves to 27 December, and interest runs from the 28th, not the 26th. When it applied, the response carries scadenta_prorogata; otherwise the field is absent.
  • Late-payment interest computed at a rate set by CONTRACT — typically "0.05% per day of delay" — rather than at the statutory rate.
  • A separate route from the statutory penalties, because the rate does not come from our series. There the rate comes from our data (the NBR reference plus the statutory margin) and the period is sliced at NBR decisions or half-years. Here the rate is constant and supplied by the client, so penalties are sliced at year boundaries — for the 365/366 basis. With neprofesional=1 the period is also cut at every change of the NBR reference rate, because that is when the statutory ceiling changes.
  • The rate is given per day OR per year, and the conversion is not symmetric. A rate given per YEAR is divided by the days of each slice's year: "18.25% per annum" produces RON 304.17 in a leap year, not 305.00 — otherwise an increase nobody wrote into the contract would appear. A rate given per DAY is final and applies directly. perioade[].baza_folosita states which was used.
  • Checking against the statutory ceiling. With neprofesional=1, each slice compares the contractual rate against the ceiling in art. 5(1) of Government Ordinance 13/2011: the statutory rate plus 50%. The usual 0.05%/day clause means 18.25% per annum, while the ceiling at the start of 2024 was 13.20% — exceeded by more than five points. The ceiling follows the statutory rate, so it is re-read at every NBR decision: from 08.07.2024 it fell to 12.90%, from 08.08.2024 to 12.60%.
  • No verdict of nullity is given. Art. 5(2) provides the sanction, but applying it is a matter for a court: the qualification of the legal relationship matters, not just the arithmetic. The response shows the figures and cites the basis.
  • Between professionals there is no numeric ceiling. Law 72/2013 art. 15 declares "manifestly abusive" clauses abusive, but the assessment is judicial, with no threshold. Nothing is checked here — an invented threshold would look official and would not be.
  • Capping at the debt value (plafon=debit) is a common contractual clause, not a statutory rule. When enabled and reached, the response says from which day and what the figure would have been without it. The day is computed exactly, accumulating the daily rate of each slice (a yearly rate gives a different daily rate in leap years): at 0.05%/day, penalties reach the debt after 2,000 days, whatever the amount.
  • The conventions remain those of the statutory penalties: calendar days from the day AFTER the due date, simple interest without compounding, rounding once at the end.

What it is for

  • Interest on an invoice with a contractual 0.05%/day clause.
  • Checking whether a penalty clause exceeds the statutory ceiling in a civil relationship.
  • Computing with a debt cap, where the contract provides one.

Response structure

FieldTypeDescription
data.suma string Sum of the values, in the unit indicated alongside.
data.scadenta string
data.scadenta_prorogata string
data.prima_zi_cu_penalitati string
data.pana_la string End of the interval the response covers, inclusive.
data.rata.procent_zi string
data.rata.procent_an string
data.rata.data_pe string zi or an — how the rate was given. It decides how the conversion is done.
data.rata.data_de_client boolean
data.penalitati string
data.penalitati_exacte string The unrounded value, for chained calculations.
data.total string
data.plafonare.activa boolean
data.perioade[].de_la string Start of the covered interval.
data.perioade[].pana_la string End of the covered interval, inclusive.
data.perioade[].zile integer Number of days covered.
data.perioade[].baza_zile_an integer
data.perioade[].procent_zi string
data.perioade[].baza_folosita string What was applied to that slice: the daily rate directly, or the annual rate divided by the days of the year.
data.perioade[].dobanda string Interest for the slice, rounded.
data.perioade[].dobanda_exacta string
meta.sursa string The official source the data comes from, with its licence where one is required.
meta.conventii string
meta.verificat_plafon_legal boolean
meta.nota_profesionisti string A note on how to read the response: a caveat, a convention or a limit of the source.
meta.legal string
data.perioade[].plafon_legal Present only with neprofesional=1: the statutory level, the ceiling, and whether the contractual rate exceeds it.
data.plafonare.din_ziua null The day penalties reach the debt. null if not reached.
data.plafonare.fara_plafon string What the penalties would have been without the cap.

Response examples

GEThttps://oneapi.ro/api/financiar/v1/calcul/penalitati/contractuale?suma=10000&scadenta=2024-03-31&pana_la=2024-06-30&procent_zi=0.05
{
    "data": {
        "suma": "10000.00",
        "scadenta": "2024-03-31",
        "scadenta_prorogata": "2024-04-01",
        "prima_zi_cu_penalitati": "2024-04-02",
        "pana_la": "2024-06-30",
        "rata": {
            "procent_zi": "0.05",
            "procent_an": "18.25",
            "data_pe": "zi",
            "data_de_client": true
        },
        "penalitati": "450.00",
        "penalitati_exacte": "450",
        "total": "10450.00",
        "plafonare": {
            "activa": false
        },
        "perioade": [
            {
                "de_la": "2024-04-02",
                "pana_la": "2024-06-30",
                "zile": 90,
                "baza_zile_an": 366,
                "procent_zi": "0.05",
                "baza_folosita": "rata zilnică din contract, aplicată direct",
                "dobanda": "450.00",
                "dobanda_exacta": "450"
            }
        ]
    },
    "meta": {
        "sursa": "Calcul propriu; rata e cea din contract, dată de client.",
        "conventii": "Zile calendaristice din ziua următoare scadenţei; bază 365/366 după anul feliei; dobândă simplă, fără capitalizare; rotunjire o singură dată, la final.",
        "verificat_plafon_legal": false,
        "nota_profesionisti": "Plafonul art. 5 OG 13/2011 se verifică doar cu `neprofesional=1`. Între profesionişti nu există prag numeric: Legea 72/2013 art. 15 lasă aprecierea clauzelor „vădit abuzive\" instanţei.",
        "legal": "Pentru penalităţi la dobânda LEGALĂ: /financiar/v1/calcul/penalitati/civile sau /profesionisti."
    }
}

Error codes

CodeSlugWhen it occurs
401neautentificatToken missing, invalid, expired or revoked.
403feature_indisponibilThe current plan does not include the feature the route depends on.
422interval_golpana_la is not after the due date; rate missing or given in both forms; malformed amount or dates; due date in the future.
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": "interval_gol",
        "mesaj": "pana_la is not after the due date; rate missing or given in both forms; malformed amount or dates; due date in the future.",
        "detalii": {
            "suma": [
                "The value sent does not satisfy the parameter rule."
            ]
        }
    }
}