Sooner or later, any codebase that deals with Romanian customers or suppliers has to answer questions about a Romanian company. Does it actually exist? Is it VAT-registered? Does it show up in RO e-Factura? What was its turnover last year?
All of this is public information. What is missing is an API. The data is spread across four institutions, each holding it in a different shape, and each one hides a quirk that will burn an afternoon of your time.
We needed it ourselves at factureaza.ro, the invoicing service we have been running since 2007, so we built apifirme.dev: one REST API and a remote MCP server on top of the official registers. This post is mostly about the data. The product comes at the end, and you can stop reading before it.
Where the data lives
| Source | What it has | How you get it |
|---|---|---|
| Trade register (ONRC) | Companies, legal form, registered office, statuses, authorised activities | No public API. Open data files on data.gov.ro, about monthly, CC BY 4.0 |
| Tax administration (ANAF) | Fiscal status, VAT, VAT on collection, inactivity, RO e-Factura, main activity code | A free web service by fiscal code: no key, 1 request a second, up to 100 codes a request, no search by name |
| Ministry of Finance | Annual financial statements since 2008, each taxpayer's fiscal obligations | Files on data.gov.ro, once a year, with updates |
| National Bank (BNR) | Reference exchange rates since 2005 | Daily |
The CUI (also called CIF), the fiscal code, is what everything joins on. The VAT number is the same digits with RO in front.
Validate the CUI before you call anything
Because a CUI ends in a check digit, most typos die before they cost you a request:
// The last digit of a CUI is a check digit over the others,
// right-aligned against the key 753217532.
function isValidCui(input) {
const digits = String(input).toUpperCase().replace(/\s+/g, '').replace(/^RO/, '');
if (!/^\d{2,10}$/.test(digits)) return false;
const body = digits.slice(0, -1).padStart(9, '0');
const key = [7, 5, 3, 2, 1, 7, 5, 3, 2];
const sum = [...body].reduce((acc, d, i) => acc + Number(d) * key[i], 0);
return (sum * 10) % 11 % 10 === Number(digits.slice(-1));
}
isValidCui('RO13548146'); // true
isValidCui('13548145'); // false
Six traps
1. Two registration dates. data_inmatriculare is the date a company entered the trade register; data_inregistrare is its fiscal registration at ANAF, which lands a few days later. Two reports that count these without saying which will disagree with each other.
2. Branch offices with their own CUI. Some secondary seats get a fiscal code of their own from ANAF, with nothing linking them to the parent company. A naive count of new fiscal codes picks them up too. In January and February 2026 they were enough to triple it.
3. The activity codes changed in 2025. CAEN, Romania's version of NACE, moved to Rev. 3. New companies get Rev. 3 codes since January 2025; existing ones had until 25 September 2026 to update. Programming went from 6201 to 6210, and taxis and ride-hailing now share 4933. Older cohorts carry a mix of both versions, so year-on-year comparisons by activity only work from 2025 on. And on its first day, about a quarter of new companies has no activity code at all yet.
4. Sole traders live in the same registers. PFA (an authorised natural person) and II and IF (individual and family enterprises) are people, not companies, but the registers publish them side by side. Keep them apart in your model, and keep personal ID numbers (CNP) out of your database.
5. Names come in capitals, with the wrong diacritics. The registers write CUBUS ARTS SRL, and often ş and ţ with a cedilla instead of ș and ț with the comma below. Normalise both sides before you compare names, or "Timișoara" will not match "TIMIŞOARA".
6. null is not "no". Debts to the state budget, for example, are not published as a dataset (the one on data.gov.ro is from 2016). A company missing from a list you do not have tells you nothing.
What 3.8 million companies say about 2026
The registers hold about 3.8 million legal entities, 1.9 million of them in operation, plus 14.5 million annual financial statements going back to 2008. Counting new trade-register entries by their registration date paints a clear picture of this year:
| Jan–Sep 2025 | Jan–Sep 2026 | Change | |
|---|---|---|---|
| Companies (SRL, SA ...) | 74,214 | 56,095 | −24 % |
| Sole traders (PFA, II, IF) | 36,984 | 45,100 | +22 % |
| Total | 111,198 | 101,195 | −9 % |
In 2024, one new entry in four was a sole trader. In 2026 it is almost one in two. Over the last twelve months the total barely moved: 143,621 against 145,524. Romanians did not stop starting businesses. They stopped starting them as companies.
The cause is three tax changes stacked up in a single year. Dividend tax rose from 10 % to 16 % for dividends paid from 1 January 2026. The micro-company regime, taxed on turnover, now stops at €100,000 instead of €250,000. And since 18 December 2025, a new SRL needs at least 500 lei of share capital. A PFA pays 10 % on net income, with capped contributions. For someone who invoices alone, the company stopped making sense.
The most registered "business" of 2026 is driving for a ride-hailing app: 11,653 new entries under CAEN 4933 in nine months, 85 % of them sole traders. The peak came in October 2025, right after the tax administration suspended Uber and Bolt payouts to roughly 100 fleet companies. The drivers did not stop driving. They registered as PFA.
And AI? There is no activity code for it, so we counted names: AI, GPT, LLM, "artificial intelligence" and their Romanian forms. Early 2023: 9 per 10,000 new SRLs. Third quarter of 2026: 51. That is only 72 companies, and they include accounting firms, marketing agencies and beauty salons.
The real signal is somewhere else. Companies founded to sell their own software product (CAEN 5821, 5829 and 6391: software publishing and web portals) grew 73 %, from 337 to 582, in a year when the total shrank. Our reading, not a proof: with today's tools, a product that once needed a team now takes two or three people.
One check before you take any of this at face value: for January to September 2026 the trade register's own statistics report 100,975 registrations, while we count 101,195. The full analysis, in Romanian and with more charts, is on our blog.
Getting the data without the afternoon
apifirme puts all four sources into one database and answers by CUI, by name or by trade register number. A new company typically shows up the day after registration. Every answer states which register each field came from, and when.
The check every invoicing program needs, in one request:
curl https://api.apifirme.dev/rest/v1/invoice-check/13548146 \
-H "Authorization: Bearer $APIFIRME_KEY"
{
"cui": 13548146,
"denumire": "Cubus Arts SRL",
"exists": true,
"valid_for_invoicing": true,
"vat_registered": true,
"vat_number": "RO13548146",
"vat_on_collection": true,
"inactive": false,
"struck_off": false,
"stare": "FUNCTIUNE",
"checked_on": "2026-10-29"
}
(Trimmed. That company is us.)
New registrations, filtered by activity and county. How many software companies registered in Cluj over the past 30 days:
curl "https://api.apifirme.dev/rest/v1/registrations/count?days=30&caen_prefix=62&judet=CJ" \
-H "Authorization: Bearer $APIFIRME_KEY"
# {"count": 41, ...}
The same data also powers tools for an AI assistant. Add https://api.apifirme.dev/mcp as a custom connector in Claude, ChatGPT, Le Chat, Cursor or any other MCP client, sign in, then ask "Can I invoice CUI 13548146 with VAT?" or "How many software companies were founded in Cluj this month?". Nothing to install, no key to copy: OAuth takes care of the sign-in. The steps for each assistant.
The free plan covers 100 requests a month, no card required. Paid plans begin at 35 lei (about €6.50) plus VAT monthly. The API docs list every request, and the OpenAPI 3.1 description is at https://api.apifirme.dev/openapi.json?lang=en.
If Romanian company data is part of your work and you have run into a quirk missing from this list, I would like to hear it in the comments.


Top comments (0)