oneapi
Sign in
Business v1 / Firme

Search companies

Searches companies by name (fuzzy, word_similarity) and/or by filters: county, locality (SIRUTA code or name), main NACE code, legal form, status, VAT registration. The location filters use the RESOLVED registered office. The result is paginated (?pagina=&per_pagina=), sorted by relevance (when q is given) and then by name.

GET
https://oneapi.ro/api/business/v1/firme/cauta

Query parameters

NameTypeDescriptionAccepted values
caenoptional string | null A CAEN code at any level — section (J), division (62), group (620), class (6201) — returning the companies under it. A code that does not exist is a 404, not an empty list. What was searched is in meta.caen. e.g. 62e.g. 4932e.g. 6210
caen_versiuneoptional string | null The revision of the caen code (1, 2, 3), when its form is ambiguous: 4932 is taxi operation in Rev.2 and occasional passenger transport in Rev.3. Without it, the code is looked up in Rev.3 first, then Rev.2 and Rev.1. 123
sortareoptional string | null The order: relevanta (the default when searching by name), denumire (the default without q), cifra_afaceri, profit, salariati (descending, on the latest filed balance sheet), data_inmatriculare (newest first). relevantadenumirecifra_afaceriprofitsalariatidata_inmatriculare
salariati_minoptional integer | null At least this many employees (the average from the latest balance sheet). Companies without a balance sheet do not pass the filter. 0
salariati_maxoptional integer | null At most this many employees. 0
ca_minoptional number | null The minimum turnover, in lei, from the latest balance sheet. 0
ca_maxoptional number | null The maximum turnover, in lei. 0
an_infiintare_minoptional integer | null Registered no earlier than this year. 1800 – 2100
an_infiintare_maxoptional integer | null Registered no later than this year. 1800 – 2100
are_registruoptional boolean | null With 1, only companies that appear in at least one public register (permits, licences, sanctions — /firme/{cui}/registre); with 0, those that do not. e.g. 1
are_achizitiioptional boolean | null With 1, only companies that have won at least one public contract; with 0, those that have won none. e.g. 1
are_fondurioptional boolean | null With 1, only EU-funds beneficiaries; with 0, the others. e.g. 1
categorieoptional string | null A service category from /caen/categorii (instalatori, stomatologi, service-auto…) instead of a CAEN code. Not combined with caen. ⚠️ The total is a lower bound, not the size of the trade. A category declares its codes in CAEN Rev.3, while the code a company carries comes from ANAF without saying which edition it belongs to; from the older editions we take only the codes that lead EXCLUSIVELY into the category, never the catch-all classes (taking all of "4399 — specialised construction n.e.c." would inflate the figure with companies doing something else). That is why categorie=X returns less than caen=<its code>, which is permissive — across the trades with a single code the median is about three quarters. The response says so: meta.total_e_limita_de_jos, meta.coduri_cautate and meta.nota_acoperire. constructii-cladiriinstalatorielectricienizugravifinisajefaiantari-parchetaritamplariizolatiiacoperisurizidariterasamente-demolariarhitectiproiectare-ingineriedesign-interiormobilacurateniedezinsectie-deratizaregradinarireparatii-electrocasnicereparatii-calculatoare-telefoaneservice-autoservice-motopiese-autodealeri-autoinchirieri-autobenzinariitransport-marfamutaricurierattaxitransport-persoanelogistica-depozitarerestaurantefood-truckcateringbaruri-cafenelehoteluripensiuni-cazarecampingbrutarii-cofetariimedici-familieclinici-medicalestomatologilaboratoare-analizepsihologikinetoterapiefarmaciispitaleingrijire-varstniciveterinarifrizerii-coafuricosmeticaspa-masajspalatorii-curatatoriipompe-funebrefitnesssportevenimenteartisti-spectacolecontabilitateavocati-notariconsultanta-managementpublicitate-marketingdesign-graficfotografitraducatoriresurse-umanepaza-protectieservicii-birouasigurariagentii-imobiliaredezvoltatori-imobiliariinchirieri-imobiliareagentii-turismdezvoltare-softwareconsultanta-ithosting-webtelecomunicatiigradinite-cresescolicursuri-meditatiiscoli-sofericursuri-arte-sportmagazine-alimentaremagazine-constructiimagazine-hainemagazine-electronicemagazine-mobilaflorariibijuteriicultura-plantelorzootehnieservicii-agricolesilviculturaenergie-regenerabilafurnizori-energiedeseuri-reciclare
formaoptional string | null Legal form (SRL, SA, PFA…), as listed in the trade register nomenclature. e.g. SRL
judetoptional string | null Filter on the county of the resolved headquarters. e.g. CJe.g. IS
localitateoptional integer | null The locality of the head office resolved through Locations — name or SIRUTA code. 1
qoptional string | null The text searched in the name (fuzzy matching). e.g. digital
stareoptional string | null Filters by status. Accepts TWO vocabularies: the raw ONRC name (funcţiune, perioadă de suspendare activitate expirată…) or one of the 7 categories — activa, suspendata, dizolvata, lichidare, radiata, insolventa, alta. A category matches every status inside it. e.g. funcțiune
tvaoptional boolean | null With 1 returns only VAT payers, with 0 only non-payers. e.g. true
uatoptional integer | null The LAU of the head office resolved through Locations — name or SIRUTA code. Narrower than judet, wider than localitate. 1

How it behaves

  • Search by name with fuzzy matching (word similarity), plus combinable filters: judet, localitate, uat, caen, forma, stare, tva. Results are offset-paginated (pagina, per_pagina).
  • The geographic filters (judet, localitate, uat) apply to the resolved headquarters through Locations, not to the raw text — so they also catch companies whose headquarters was written inconsistently at ONRC.
  • Search is not meant to replace an exact lookup by tax ID: use /firme/{cui} for that. It is built for discovery — "transport companies in Cluj that are VAT payers".
  • caen is hierarchical and crosses revisions. caen=62 catches 6201, 6202…, and companies still carrying Rev.1 codes or already on Rev.3 are caught through the official INS correspondence. The ANAF file mixes revisions, so a filter on the exact code would have missed companies on another revision.
  • The size filters (salariati_*, ca_*) read the company's latest filed balance sheet: a company without one does not pass them, because we do not know its size — we cannot call it "between 10 and 49 employees".
  • With sortare=cifra_afaceri, profit or salariati, the list becomes a ranking on each company's latest filed balance sheet (the year is in financiar.an, so it may differ between companies) and covers only companies that have one — meta.paginare.total drops accordingly. For a ranking on a single year: /firme/top.
  • Companies still on Rev.2 join a category only when their old code clearly leads there: all its Rev.3 correspondents are in the category, or it was merely renumbered into at most 3 codes (5610 restaurants → 5611 + 5612; 4120 → 4100; 4532 car parts → 4782), or it keeps its number (6820 → 6820). Catch-all codes are left out: 4399 "other specialised construction" splits into ten Rev.3 codes, so "instalatori" no longer picks up scaffolding or foundation firms. The cost: activities that in Rev.2 lived only in catch-all codes (masonry, in 4399) appear only as companies move, as they must, to Rev.3.

What it is for

  • A search field with autocomplete for companies.
  • Market segmentation: how many active companies in a CAEN, in a county.
  • Finding a company whose tax ID you do not know, starting from the name.

Response structure

FieldTypeDescription
data[].cui integer The tax ID.
data[].denumire string | null The name.
data[].cod_inmatriculare string | null The trade register order number (J…).
data[].forma_juridica string | null Legal form (SRL, SA, PFA…).
data[].stare string | null The company status, as an object: denumire is the raw ONRC text (107 distinct values in use), categorie is our classification into 7 buckets — activa, suspendata, dizolvata, lichidare, radiata, insolventa, alta — which is what you filter or group by. cod is the ONRC code of the status.
data[].data_inmatriculare string | null The trade register incorporation date.
data[].radiere.vazut_la string
data[].radiere.dupa string | null
data[].sediu.judet string The county of the registered office.opțional
data[].sediu.localitate string The locality of the registered office.opțional
data[].sediu.cod_siruta integer The locality SIRUTA code — chainable to /api/locations/v1.opțional
data[].caen_principal.cod string The primary CAEN code.
data[].caen_principal.denumire string | null The name of the primary activity.
data[].fiscal.tva boolean VAT-registered.
data[].fiscal.inactiv boolean Declared fiscally inactive.
data[].fiscal.e_factura boolean Enrolled in e-Invoicing.
data[].financiar object The latest filed balance sheet (year, turnover, net profit, employees); null for companies without one — sole traders, new companies —, not zero.
data[].financiar.an integer The balance-sheet year.
data[].financiar.cifra_afaceri number | null Net turnover, in lei.
data[].financiar.profit_net number | null Net profit, in lei; negative = loss.
data[].financiar.salariati integer | null The average number of employees.
meta.paginare.pagina integer Pagina curentă.
meta.paginare.per_pagina integer Rezultate pe pagină.
meta.paginare.total integer Total rezultate.
meta.paginare.pagini integer Număr de pagini.
meta.caen object How the caen parameter was understood: the requested code, the revision it was read in and the code the route used. For a list of codes, one object per code.
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 string[] The raw classes actually searched, when there are at most 20. So the total can be checked rather than taken on trust.

Response examples

GEThttps://oneapi.ro/api/business/v1/firme/cauta?q=digital
{
    "data": [
        {
            "cui": 32917762,
            "denumire": "DIGITAL 1 VENTURES DEVELOPMENT SRL",
            "cod_inmatriculare": "J12/957/2014",
            "forma_juridica": "SRL",
            "stare": {
                "cod": "1084",
                "denumire": "radiată",
                "categorie": "radiata"
            },
            "data_inmatriculare": "2014-03-13",
            "sediu": {
                "judet": "Cluj",
                "localitate": "Cluj-Napoca",
                "cod_siruta": 54984
            },
            "caen_principal": {
                "cod": "6201",
                "denumire": "Activități de realizare a soft-ului la comandă (software orientat client)"
            },
            "fiscal": {
                "tva": true,
                "inactiv": false,
                "e_factura": false
            },
            "financiar": {
                "an": 2025,
                "cifra_afaceri": 83990,
                "profit_net": 3947,
                "salariati": 1
            }
        }
    ],
    "meta": {
        "paginare": {
            "pagina": 1,
            "per_pagina": 20,
            "total": 6105,
            "pagini": 306
        }
    }
}

Error codes

CodeSlugWhen it occurs
200categorie_nerezolvabiladata: null plus the reason in meta.fara_date: the category cannot be resolved into the codes companies actually carry, because its code means different things in different CAEN editions (meta.clase_ambigue names them). This is NOT "there are no such companies" — which is exactly why it is not an empty list.
401neautentificatToken missing, invalid, expired or revoked.
403feature_indisponibilThe current plan does not include the feature the route depends on.
422validareAn undeclared parameter or a value that fails validation (an_infiintare_, are_, ca_, caen, caen_versiune, categorie, forma, judet, localitate, q, salariati_, sortare, stare, tva, uat); a maximum below its minimum or categorie together with caen also land here. The offending field is in detalii.
422q_scurtThe search term must have at least 3 characters.
422fara_criteriuGive q or at least one filter.
422filtru_necunoscutA filter that matches no entity (a misspelt county, locality, administrative unit, legal form, status or CATEGORY) — not an empty list; detalii.camp says which.
422caen_inexistentThe code in caen exists in no CAEN revision. ⚠️ 422, not 404, since 6 Oct 2026: here caen is a FILTER value, and on a listing a 404 would mean "the resource does not exist" — indistinguishable, at the client, from a section with no data. The short code stays caen_inexistent rather than becoming filtru_necunoscut: "the CAEN code does not exist" and "the county does not exist" remain two different things. On routes carrying the code in the PATH (/caen/{cod}/…, /sector/{caen}/…) it stays 404, because there the code IS the resource.
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": "An undeclared parameter or a value that fails validation (an_infiintare_*, are_*, ca_*, caen, caen_versiune, categorie, forma, judet, localitate, q, salariati_*, sortare, stare, tva, uat); a maximum below its minimum or categorie together with caen also land here. The offending field is in detalii.",
        "detalii": {
            "caen": [
                "The value sent does not satisfy the parameter rule."
            ]
        }
    }
}