oneapi
Sign in
Business v1 / Statistici

Sector benchmark

The distribution of a CAEN sector's balance sheets in a year: turnover and net-profit quartiles, median headcount, overall and by size class.

GET
https://oneapi.ro/api/business/v1/caen/{cod}/benchmark

Path parameters

NameTypeDescriptionExample
codrequired string NACE Rev. 2 (CAEN) code, four digits (e.g. 6201).

Query parameters

NameTypeDescriptionAccepted values
caen_versiuneoptional string | null The revision of the code (1, 2, 3), when its form is ambiguous. 123
anoptional integer | null The balance-sheet year. By default, the newest year with most balance sheets filed. e.g. 2025
judetoptional string | null The registered-office county: licence-plate code (CJ) or name. e.g. CJ
clasa_marimeoptional string | null micro, mica, mijlocie or mare. With it, the response has only that class's total. micromicamijlociemare
de_laoptional integer | null The first year of the series, four digits. ⚠️ Not sent together with an: either a single year or an interval. e.g. 2024-01-01
pana_laoptional integer | null The last year of the series, four digits. ⚠️ Not sent together with an. e.g. 2024-12-31

How it behaves

  • The distribution of a sector's balance sheets in a year: turnover and net-profit quartiles, median employees, overall and by size class. The code in the path may be at any level (G, 62, 4711).
  • The sector is the CAEN code declared in that year's balance sheet (as the Ministry of Finance classifies it), not today's ANAF code: the 2021 benchmark compares the companies that were in the sector then.
  • The size class follows the average number of employees, on the thresholds of Law 346/2004 (0–9, 10–49, 50–249, 250+); turnover is not part of the classification.
  • Groups below 5 companies are not published — the percentiles would describe identifiable companies. If the total is below the threshold, the route returns 200 with data: null and meta.fara_date; classes below it are missing from pe_clasa_marime.
  • Mean turnover is pulled up by a few large companies (in food retail the mean is 17 times the median). For "the typical company", use the median.
  • Covers every balance-sheet form (micro-enterprises included). A given company's place in its sector: /firme/{cui}/benchmark.
  • Impossible values written in the form (a turnover of 300,000 billion lei, 62,355 employees at a company with 275,000 lei in turnover) become null and stay out of rankings and averages. Insurers' forms have no turnover line, so they have cifra_afaceri: null.

What it is for

  • "Where does my company stand?" — a company's turnover against its sector's median, in its county.
  • Sizing a market: how many companies, what summed turnover, how many employees a sector has.
  • Realistic thresholds for credit or risk scoring, by sector and size class.

Response structure

FieldTypeDescription
data.total.firme integer How many companies with a balance sheet fall in the group.
data.total.cifra_afaceri.p25 number The turnover below which a quarter of companies sit, in lei.
data.total.cifra_afaceri.mediana integer The median turnover.
data.total.cifra_afaceri.p75 number The turnover above which a quarter of companies sit.
data.total.cifra_afaceri.medie number The mean — pulled up by large companies; the median describes the typical one.
data.total.cifra_afaceri.total integer Summed turnover.
data.total.profit_net.p25 integer The first quartile of net profit (negative = loss).
data.total.profit_net.mediana integer The median net profit.
data.total.profit_net.p75 number The third quartile of net profit.
data.total.profit_net.firme_profitabile integer How many companies have a positive net profit.
data.total.salariati.mediana integer The median number of employees.
data.total.salariati.medie number The mean number of employees per company.
data.total.salariati.total integer Summed employees.
data.pe_clasa_marime[].clasa_marime string The size class: micro (0–9 employees), mica (10–49), mijlocie (50–249), mare (250+).
data.pe_clasa_marime[].firme integer How many companies with a balance sheet fall in the group.
data.pe_clasa_marime[].cifra_afaceri.p25 integer The turnover below which a quarter of companies sit, in lei.
data.pe_clasa_marime[].cifra_afaceri.mediana integer The median turnover.
data.pe_clasa_marime[].cifra_afaceri.p75 integer The turnover above which a quarter of companies sit.
data.pe_clasa_marime[].cifra_afaceri.medie number The mean — pulled up by large companies; the median describes the typical one.
data.pe_clasa_marime[].cifra_afaceri.total integer Summed turnover.
data.pe_clasa_marime[].profit_net.p25 integer The first quartile of net profit (negative = loss).
data.pe_clasa_marime[].profit_net.mediana integer The median net profit.
data.pe_clasa_marime[].profit_net.p75 integer The third quartile of net profit.
data.pe_clasa_marime[].profit_net.firme_profitabile integer How many companies have a positive net profit.
data.pe_clasa_marime[].salariati.mediana integer The median number of employees.
data.pe_clasa_marime[].salariati.medie number The mean number of employees per company.
data.pe_clasa_marime[].salariati.total integer Summed employees.
meta.an integer The balance-sheet year.
meta.caen object How the code in the path was resolved (level, name, how many classes were searched).
meta.caen.cerut string The CAEN code sent, normalised (upper case, no dots).
meta.caen.versiune_cerut string The revision the code sent was read in: the one in caen_versiune, otherwise the first it exists in.
meta.caen.nivel string The level of the code used — on company routes, of the requested code: sectiune, subsectiune, diviziune, grupa, clasa or agregat.
meta.caen.denumire string The name of the code, from the CAEN nomenclature.
meta.caen.clase_cautate integer How many CAEN classes, across all revisions companies carry, fall under the requested code.
meta.caen.clase_altele_decat_cerut integer How many of them are NOT the requested code. The search is permissive (it translates the code into every edition so that companies not yet renumbered are found), and the translation sometimes lands on far broader classes — so the total can be about more than the trade you asked for.
meta.caen.nota_acoperire string Present only when classes other than the requested code were searched; it says what to use instead if you want a figure strictly about the trade you asked for.
meta.caen.clase array The raw classes actually searched, when there are at most 20. So the total can be checked rather than taken on trust.
meta.judet string The requested county, if any.
meta.clasa_marime string The requested size class, if any.

Response examples

GEThttps://oneapi.ro/api/business/v1/caen/4711/benchmark
{
    "data": {
        "total": {
            "firme": 68133,
            "cifra_afaceri": {
                "p25": 55842.5,
                "mediana": 227769,
                "p75": 702919.5,
                "medie": 3889683.49,
                "total": 205029106446
            },
            "profit_net": {
                "p25": -5062,
                "mediana": 0,
                "p75": 21026.5,
                "firme_profitabile": 32509
            },
            "salariati": {
                "mediana": 1,
                "medie": 5.4,
                "total": 199402
            }
        },
        "pe_clasa_marime": [
            {
                "clasa_marime": "micro",
                "firme": 66038,
                "cifra_afaceri": {
                    "p25": 51274,
                    "mediana": 210028,
                    "p75": 582197,
                    "medie": 730610.25,
                    "total": 36981298948
                },
                "profit_net": {
                    "p25": -5413,
                    "mediana": 0,
                    "p75": 17816,
                    "firme_profitabile": 30696
                },
                "salariati": {
                    "mediana": 1,
                    "medie": 1.9,
                    "total": 65638
                }
            }
        ]
    },
    "meta": {
        "an": 2025,
        "caen": {
            "cerut": "4711",
            "versiune_cerut": "Rev.3",
            "nivel": "clasa",
            "denumire": "Comerț cu amănuntul nespecializat, cu vânzare predominantă de produse alimentare, băuturi și tutun",
            "clase_cautate": 8,
            "clase_altele_decat_cerut": 7,
            "nota_acoperire": "Căutarea e permisivă: codul cerut s-a tradus în toate ediţiile CAEN, ca să prindă şi firmele nerenumerotate încă. Totalul cuprinde deci şi 7 clase diferite de [4711], iar unele pot fi mult mai largi decât codul cerut. Pentru o cifră strict despre meseria cerută, foloseşte `categorie=` de la `/caen/categorii`, care refuză clasele-sac.",
            "clase": [
                "4711",
                "4781",
                "4791",
                "4799",
                "5211",
                "5261",
                "5262",
                "5263"
            ]
        }
    }
}

Error codes

CodeSlugWhen it occurs
401neautentificatToken missing, invalid, expired or revoked.
403feature_indisponibilThe current plan does not include the feature the route depends on.
404caen_inexistentThe code [{cod}] does not exist in any CAEN revision (Rev.1, Rev.2, Rev.3).
422caen_invalidThe code [{cod}] is not shaped like a CAEN code.
422filtru_necunoscutThe county in judet does not exist; detalii.camp says which.
422validareAn undeclared parameter or a value that fails validation (an, caen_versiune, clasa_marime, judet). The offending field is in detalii.
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": "caen_invalid",
        "mesaj": "The code [{cod}] is not shaped like a CAEN code.",
        "detalii": {
            "cod": [
                "The value sent does not satisfy the parameter rule."
            ]
        }
    }
}