API documentation
The API is REST and answers in JSON. The full description, in OpenAPI 3.1 format, is at https://api.apifirme.dev/openapi.json?lang=en; this page is generated from it. Field names and values are those of the Romanian registries (denumire is the name, judet the county, stare the status).
Authentication
Every request, except the validation ones, needs an API key in the Authorization header:
curl https://api.apifirme.dev/rest/v1/companies/13548146 \
-H "Authorization: Bearer af_live_..."
Limits
Every response says how much is left of the limits: x-ratelimit-limit, x-ratelimit-remaining and x-ratelimit-reset for the requests per minute, x-quota-limit and x-quota-remaining for those of the month. A request over the limit gets 429 with a Retry-After header and is not counted. Beyond the plan's monthly number of requests another 5 % are allowed, at no cost; only after those are requests refused.
Conditional requests
Every 200 response has an ETag header. A request that sends it back in If-None-Match gets 304 without a body if the response has not changed; it counts as a request too.
Errors
Errors follow RFC 7807: the content type is application/problem+json, and the body has type, title, status and detail. type identifies the kind of error, for example https://apifirme.dev/problems/invalid-cui.
For AI assistants
The same data is available as tools through the Model Context Protocol, at https://api.apifirme.dev/mcp (Streamable HTTP transport): lookup_company, check_invoice, get_financials, get_company_events, get_fx_rate, count_new_companies and list_new_companies. An assistant sends its user to sign in (OAuth 2.1); a program can send the same API key in the Authorization header. Only tool calls are counted, each as one request; connecting and listing the tools are not. The steps for each assistant are at https://apifirme.dev/en/ai.
Sources
Every company and every financial statement has a sources field: which registry the information comes from, which dataset, and when it was first and last retrieved.
Companies
A company's data, by its CUI (the Romanian unique registration code).
GET /rest/v1/companies/{cui}
A company's data. Returns the company with this CUI. If the company is not in the database yet, it is looked up at ANAF (the Romanian tax administration) right away: the answer comes in the same request or, if the source is slow, as 202 with a Retry-After header. For a natural person (a sole trader: PFA, individual or family enterprise) the answer is 404.
| Parameter | Where | Description |
|---|---|---|
cui | in the path, required | The unique registration code (CUI), with or without the RO prefix, for example 13548146. |
curl https://api.apifirme.dev/rest/v1/companies/13548146 \
-H "Authorization: Bearer af_live_..."
Responses:
| Code | What it means |
|---|---|
200 | The company. |
202 | The company is being looked up at ANAF and did not arrive in time. Repeat the request after the number of seconds in Retry-After. Does not count as a request. |
400 | A parameter is missing or not valid; detail says which. |
401 | The API key is missing or not valid. |
404 | Does not exist: an unregistered CUI, a natural person, or no data for the day or year requested. |
429 | The limit per minute or the month's number of requests has been exceeded. Does not count as a request. |
503 | The company is not in the database and ANAF could not be asked right now. Does not count as a request. |
The 200 response is a Company object:
| Field | Type | Description |
|---|---|---|
cui | integer | The unique registration code (CUI). |
denumire | string or null | The name. |
nr_reg_com | string or null | The registration number in the trade register. |
euid | string or null | The European unique identifier (source: ONRC, the trade register). |
sediu_secundar | boolean | Whether it is the secondary seat of a company, registered at ANAF with a CUI of its own. |
forma_juridica | string or null | The legal form as ANAF writes it. |
forma_juridica_cod | string or null | The legal form from the trade register: SRL, SA, ... |
stare | string or null | The status, in one word: FUNCTIUNE (in operation), SUSPENDARE (suspended), REORGANIZARE JUDICIARA (judicial reorganisation), INSOLVENTA (insolvency), DIZOLVARE (dissolution), LICHIDARE (liquidation), FALIMENT (bankruptcy), RADIERE (struck off). |
stari_registru | array | All statuses and remarks from the trade register, each with cod (code) and denumire (name). |
caen | integer or null | The CAEN code of the main activity (source: ANAF). CAEN is the Romanian classification of economic activities, aligned with NACE. |
caen_denumire | string or null | The name of the CAEN code, in the classification in force. |
caen_autorizate | array or null | The activities the company is authorised for, from the trade register's open data: each with cod (code), versiune (the version of the CAEN classification it was declared in: 3 is the one of 2025, 2 the one of 2008, 1 the one of 2003, 0 the one of 1998) and denumire (name), the newest classification first. The register also keeps what was declared in the old classifications, so the same activity can appear with codes of several versions. null when they are not known (the company is not in the register's dataset), which does not mean that it has none. |
data_inregistrare | date or null | The date of fiscal registration (source: ANAF). |
data_inmatriculare | date or null | The date of entry in the trade register (source: ONRC). |
web | string or null | The web address declared to the trade register. |
judet | string or null | The county code of the registered office: SB, B, ... |
localitate | string or null | The locality of the registered office. |
adresa_completa | string or null | The address of the registered office, as one text. |
cod_postal | string or null | The postal code. |
telefon | string or null | The telephone number declared to ANAF. |
scp_tva | boolean | Whether it is registered for VAT. |
data_inceput_tva | date or null | Since when it has been registered for VAT. |
data_sfarsit_tva | date or null | Until when it was registered, if it no longer is. |
tva_incasare | boolean | Whether it applies VAT on collection. |
split_tva | boolean | Whether it applies split VAT payment. |
status_inactiv | boolean | Whether it is declared fiscally inactive. |
data_inactivare | date or null | Since when it has been inactive. |
e_factura | boolean | Whether it is in the RO e-Factura register. |
updated_at | date-time or null | When something in the company's data last changed. |
checked_at | date-time or null | When ANAF was last asked about the company; null if not yet. |
sources | array of Source | Which sources the company's data comes from, and since when. |
POST /rest/v1/companies/batch
Several companies in one request. Up to 100 CUIs in a single request, answered from what is already in the database. It costs as many requests as the CUIs it answers for: one for each company returned and for each CUI we serve no data about, and one at least. A CUI that is not in the database yet appears in not_stored, costs nothing and can be asked for by itself, with GET /rest/v1/companies/{cui}, which looks it up at ANAF right away. For the limit per minute, a request for several companies is one request.
The request body is a BatchRequest object:
| Field | Type | Description |
|---|---|---|
cuis | array | Between 1 and 100 CUIs, as text or as numbers, with or without the RO prefix. |
curl -X POST https://api.apifirme.dev/rest/v1/companies/batch \
-H "Authorization: Bearer af_live_..." \
-H "Content-Type: application/json" \
-d '{"cuis": ["13548146", "RO4221306"]}'
Responses:
| Code | What it means |
|---|---|
200 | The companies found, and what became of the other CUIs. |
400 | A parameter is missing or not valid; detail says which. |
401 | The API key is missing or not valid. |
429 | The limit per minute or the month's number of requests has been exceeded. Does not count as a request. |
The 200 response is a BatchResult object:
| Field | Type | Description |
|---|---|---|
data | array of Company | The companies found, in the order in which they were asked for. |
withheld | array | The CUIs under which there is an entry we serve no data about: a natural person, or one not classified yet. |
not_stored | array | The valid CUIs that are not in the database yet. They cost nothing; asked for by themselves, they are looked up at ANAF. |
invalid | array | What is not a valid CUI, as it was received. |
GET /rest/v1/companies/search
Find a company without its CUI. Finds a company by its name or by its trade register number, for whoever does not know its CUI. Exactly one of denumire and nr_reg_com is given. By name, the companies called exactly that come first, with or without the legal form (“dedeman” finds “DEDEMAN SRL”), then those whose name begins with it, then those that contain all its words, in any order. Diacritics and capital letters do not matter, and companies in operation come before the others. The answer has at most 10 companies, each with a few fields, and no next page: more says that others match as well, and then the county or a more exact name helps. A company's full data is requested with its CUI. Natural persons and secondary seats are not among the results. A search costs one request and has a limit per minute of its own, by plan; beyond it the answer is 429 with searches-limited.
| Parameter | Where | Description |
|---|---|---|
denumire | in the query | The company's name or a part of it: at least one word of three letters or digits, beside the legal form. |
nr_reg_com | in the query | The trade register number, in the old form (J32/508/2000) or the new one (J2000000508324), whichever way we store it. Numbers that begin with F belong to natural persons, about whom no data is served. |
judet | in the query | With denumire only: one county's code, as on number plates (SB, B for Bucharest). |
curl https://api.apifirme.dev/rest/v1/companies/search \
-H "Authorization: Bearer af_live_..."
Responses:
| Code | What it means |
|---|---|
200 | The companies found. |
400 | A parameter is missing or not valid; detail says which. |
401 | The API key is missing or not valid. |
429 | The limit per minute or the month's number of requests has been exceeded. Does not count as a request. |
The 200 response is a SearchResult object:
| Field | Type | Description |
|---|---|---|
data | array of CompanyFound | The companies found, the closest first: at most 10. |
more | boolean | true if other companies match beside those returned. |
GET /rest/v1/companies/{cui}/events
What changed at a company. The changes observed at the company since we have been following it, the most recent first (200 at most): registration for VAT or removal from it, VAT on collection, split VAT payment, being declared inactive and being reactivated, being struck off, a change of status, name, address or CAEN code, RO e-Factura. A change is noted when ANAF's answer about the company differs from its previous answer; what was before our first answer from ANAF does not appear, and the list is empty if nothing has been observed. That a company is new is not an event here: that is what registrations is for.
| Parameter | Where | Description |
|---|---|---|
cui | in the path, required | The unique registration code (CUI), with or without the RO prefix, for example 13548146. |
curl https://api.apifirme.dev/rest/v1/companies/13548146/events \
-H "Authorization: Bearer af_live_..."
Responses:
| Code | What it means |
|---|---|
200 | The changes observed at the company. |
400 | A parameter is missing or not valid; detail says which. |
401 | The API key is missing or not valid. |
404 | Does not exist: an unregistered CUI, a natural person, or no data for the day or year requested. |
429 | The limit per minute or the month's number of requests has been exceeded. Does not count as a request. |
The 200 response is a EventsList object:
| Field | Type | Description |
|---|---|---|
cui | integer | The company's CUI. |
events | array of Event | The changes observed, the most recent first. |
GET /rest/v1/invoice-check/{cui}
Check before invoicing. Answers, in a single request, what an invoicing program wants to know about a customer: whether it exists, is registered for VAT, applies VAT on collection, is fiscally inactive, is in the RO e-Factura register. If ANAF's last answer about the company is more than 24 hours old, the company is asked about again right away; checked_at says how old the data is. A valid CUI that ANAF does not know gets 200 with exists: false.
| Parameter | Where | Description |
|---|---|---|
cui | in the path, required | The unique registration code (CUI), with or without the RO prefix, for example 13548146. |
curl https://api.apifirme.dev/rest/v1/invoice-check/13548146 \
-H "Authorization: Bearer af_live_..."
Responses:
| Code | What it means |
|---|---|
200 | The result of the check. |
202 | The company is being looked up at ANAF and did not arrive in time. Repeat the request after the number of seconds in Retry-After. Does not count as a request. |
400 | A parameter is missing or not valid; detail says which. |
401 | The API key is missing or not valid. |
404 | Does not exist: an unregistered CUI, a natural person, or no data for the day or year requested. |
429 | The limit per minute or the month's number of requests has been exceeded. Does not count as a request. |
503 | The company is not in the database and ANAF could not be asked right now. Does not count as a request. |
The 200 response is a InvoiceCheck object:
| Field | Type | Description |
|---|---|---|
cui | integer | The unique registration code (CUI). |
exists | boolean | Whether ANAF knows a taxpayer with this CUI. |
denumire | string or null | The name. |
valid_for_invoicing | boolean | Whether the company exists, is not struck off and is not fiscally inactive. |
vat_registered | boolean | Whether it is registered for VAT. |
vat_number | string or null | The VAT number (RO followed by the CUI), if it is registered for VAT. |
vat_on_collection | boolean | Whether it applies VAT on collection. |
split_vat | boolean | Whether it applies split VAT payment. |
inactive | boolean | Whether it is declared fiscally inactive. |
struck_off | boolean | Whether it is struck off. |
efactura_registered | boolean | Whether it is in the RO e-Factura register. |
stare | string or null | The status, in one word, as in the company's data. |
checked_at | date-time or null | When ANAF last answered about the company. |
Financial statements
The annual financial statements published by the Ministry of Finance.
GET /rest/v1/companies/{cui}/financials
A company's financial statements. All annual financial statements of the company, the most recent year first. The list is empty if there are none.
| Parameter | Where | Description |
|---|---|---|
cui | in the path, required | The unique registration code (CUI), with or without the RO prefix, for example 13548146. |
curl https://api.apifirme.dev/rest/v1/companies/13548146/financials \
-H "Authorization: Bearer af_live_..."
Responses:
| Code | What it means |
|---|---|
200 | The company's financial statements. |
400 | A parameter is missing or not valid; detail says which. |
401 | The API key is missing or not valid. |
404 | Does not exist: an unregistered CUI, a natural person, or no data for the day or year requested. |
429 | The limit per minute or the month's number of requests has been exceeded. Does not count as a request. |
The 200 response is a FinancialsList object:
| Field | Type | Description |
|---|---|---|
cui | integer | The company's CUI. |
financials | array of Statement | The financial statements, the most recent year first. |
GET /rest/v1/companies/{cui}/financials/{year}
The financial statement of one year.
| Parameter | Where | Description |
|---|---|---|
cui | in the path, required | The unique registration code (CUI), with or without the RO prefix, for example 13548146. |
year | in the path, required | The year of the financial statement, for example 2025. |
curl https://api.apifirme.dev/rest/v1/companies/13548146/financials/2025 \
-H "Authorization: Bearer af_live_..."
Responses:
| Code | What it means |
|---|---|
200 | The financial statement of that year. |
400 | A parameter is missing or not valid; detail says which. |
401 | The API key is missing or not valid. |
404 | Does not exist: an unregistered CUI, a natural person, or no data for the day or year requested. |
429 | The limit per minute or the month's number of requests has been exceeded. Does not count as a request. |
The 200 response is a Statement object:
| Field | Type | Description |
|---|---|---|
cui | integer | The company's CUI. |
an | integer | The year of the financial statement. |
tip_raportare | string | The Ministry of Finance's reporting type: UU (abbreviated balance sheet), BL_BS_SL, IR (IFRS), ONG (non-profit organisations), ... |
tip_raportare_descriere | string or null | What kind of taxpayers file this type. |
caen | integer or null | The CAEN code from the financial statement. |
caen_denumire | string or null | The name of the code, in the classification in force in that year. |
active_imobilizate | integer or null | Fixed assets, total. In whole lei; null if the ministry does not publish the value. |
active_circulante | integer or null | Current assets, total. In whole lei; null if the ministry does not publish the value. |
stocuri | integer or null | Inventories. In whole lei; null if the ministry does not publish the value. |
creante | integer or null | Receivables. In whole lei; null if the ministry does not publish the value. |
casa_banca | integer or null | Cash and bank accounts. In whole lei; null if the ministry does not publish the value. |
cheltuieli_avans | integer or null | Prepaid expenses. In whole lei; null if the ministry does not publish the value. |
datorii | integer or null | Liabilities. In whole lei; null if the ministry does not publish the value. |
venituri_avans | integer or null | Deferred income. In whole lei; null if the ministry does not publish the value. |
provizioane | integer or null | Provisions. In whole lei; null if the ministry does not publish the value. |
capitaluri_total | integer or null | Equity, total. In whole lei; null if the ministry does not publish the value. |
capital_social | integer or null | Subscribed and paid-up share capital. In whole lei; null if the ministry does not publish the value. |
patrimoniul_regiei | integer or null | Patrimony of the autonomous state enterprise (regie). In whole lei; null if the ministry does not publish the value. |
cifra_afaceri | integer or null | Net turnover. In whole lei; null if the ministry does not publish the value. |
venituri_totale | integer or null | Total income. In whole lei; null if the ministry does not publish the value. |
cheltuieli_totale | integer or null | Total expenses. In whole lei; null if the ministry does not publish the value. |
profit_brut | integer or null | Gross profit. In whole lei; null if the ministry does not publish the value. |
pierdere_bruta | integer or null | Gross loss. In whole lei; null if the ministry does not publish the value. |
profit_net | integer or null | Net profit. In whole lei; null if the ministry does not publish the value. |
pierdere_neta | integer or null | Net loss. In whole lei; null if the ministry does not publish the value. |
nr_mediu_salariati | integer or null | Average number of employees. In whole lei; null if the ministry does not publish the value. |
alti_indicatori | array | The indicators this reporting type has in addition, each with cod (code), denumire (name) and valoare (value). |
updated_at | date-time | When the statement last changed in our database. |
sources | array of Source | The dataset the statement comes from, when the ministry published it and when we retrieved it. |
New companies
Newly registered companies, for those who want to learn every day which companies have appeared.
GET /rest/v1/registrations
Newly registered companies. The legal persons registered in the requested period, in the order in which they were indexed, paginated by cursor. The period is limited by the plan; a longer period is refused with 400, not silently shortened. Whoever asks daily must continue from next_cursor or, after the last page, send as discovered_after the discovered_at value of the last company received (not the time of their own clock and not the registration date): a company registered on a Monday may be indexed on the Friday, and companies become visible strictly in the order of discovered_at, so none is missed this way. A company can appear a second time, with a new discovered_at: when its CAEN code, county or legal form becomes known after it was indexed (a quarter of the new companies have no CAEN code yet on their first day). That way those who filter by these receive it too; it is recognised by its cui. Secondary seats and natural persons do not appear. Plans that do not include the list get 403.
| Parameter | Where | Description |
|---|---|---|
days | in the query | The companies registered in the last so many days. Not together with registered_after. |
registered_after | in the query | The companies registered on or after this day. |
discovered_after | in the query | Only the companies we indexed after this moment (2026-10-01T08:00:00Z) or this day. |
caen | in the query | One or more four-digit CAEN codes, separated by commas. |
caen_prefix | in the query | The first two digits (the division) or three (the group) of the CAEN code. |
judet | in the query | One or more county codes (SB, B), separated by commas. |
forma_juridica | in the query | One or more legal forms, by the trade register's codes (SRL, SA), separated by commas. |
limit | in the query | How many companies per page, between 1 and 500. 100 by default. |
cursor | in the query | The next_cursor value from the previous answer. |
curl https://api.apifirme.dev/rest/v1/registrations?days=7&judet=SB \
-H "Authorization: Bearer af_live_..."
Responses:
| Code | What it means |
|---|---|
200 | A page of new companies. |
400 | A parameter is missing or not valid; detail says which. |
401 | The API key is missing or not valid. |
403 | The plan does not include this request; upgrade_url leads to the plans. |
429 | The limit per minute or the month's number of requests has been exceeded. Does not count as a request. |
The 200 response is a RegistrationsPage object:
| Field | Type | Description |
|---|---|---|
data | array of Registration | The companies, in the order in which they were indexed. |
next_cursor | string or null | To be sent as cursor for the next page; null on the last page. |
filter | object | The filter applied, with the resulting period. |
GET /rest/v1/registrations/count
The number of newly registered companies. How many companies match the filter. Included in every plan, over at most the longest period any plan offers. Without days or registered_after the last 30 days are counted.
| Parameter | Where | Description |
|---|---|---|
days | in the query | The companies registered in the last so many days. Not together with registered_after. |
registered_after | in the query | The companies registered on or after this day. |
discovered_after | in the query | Only the companies we indexed after this moment (2026-10-01T08:00:00Z) or this day. |
caen | in the query | One or more four-digit CAEN codes, separated by commas. |
caen_prefix | in the query | The first two digits (the division) or three (the group) of the CAEN code. |
judet | in the query | One or more county codes (SB, B), separated by commas. |
forma_juridica | in the query | One or more legal forms, by the trade register's codes (SRL, SA), separated by commas. |
curl https://api.apifirme.dev/rest/v1/registrations/count?days=30&caen_prefix=62 \
-H "Authorization: Bearer af_live_..."
Responses:
| Code | What it means |
|---|---|
200 | The number of companies. |
400 | A parameter is missing or not valid; detail says which. |
401 | The API key is missing or not valid. |
429 | The limit per minute or the month's number of requests has been exceeded. Does not count as a request. |
The 200 response is a RegistrationsCount object:
| Field | Type | Description |
|---|---|---|
count | integer | The number of companies that match the filter. |
filter | object | The filter applied, with the resulting period. |
upgrade_required_for_records | boolean | Whether the list of these companies needs a higher plan than the key's. |
BNR exchange rates
The reference exchange rate of the National Bank of Romania (BNR), since 2005.
GET /rest/v1/fx/latest
The latest published rate.
curl https://api.apifirme.dev/rest/v1/fx/latest \
-H "Authorization: Bearer af_live_..."
Responses:
| Code | What it means |
|---|---|
200 | The rates of the last banking day. |
401 | The API key is missing or not valid. |
404 | Does not exist: an unregistered CUI, a natural person, or no data for the day or year requested. |
429 | The limit per minute or the month's number of requests has been exceeded. Does not count as a request. |
The 200 response is a FxDay object:
| Field | Type | Description |
|---|---|---|
date | date | The requested day. |
effective_date | date | The banking day for which the rate was published. |
base | string | The currency the rates are expressed in: RON. |
rates | object | For each currency: rate, in lei for multiplier units of the currency. |
source | object | The source of the rate and when it was retrieved. |
GET /rest/v1/fx/{date}
The rate of one day. For a day on which BNR does not publish (a weekend, a public holiday) the rate of the last banking day before it is returned; effective_date says which day that is.
| Parameter | Where | Description |
|---|---|---|
date | in the path, required | The day, for example 2026-10-02. |
curl https://api.apifirme.dev/rest/v1/fx/2026-10-02 \
-H "Authorization: Bearer af_live_..."
Responses:
| Code | What it means |
|---|---|
200 | The rates valid on that day. |
400 | A parameter is missing or not valid; detail says which. |
401 | The API key is missing or not valid. |
404 | Does not exist: an unregistered CUI, a natural person, or no data for the day or year requested. |
429 | The limit per minute or the month's number of requests has been exceeded. Does not count as a request. |
The 200 response is a FxDay object:
| Field | Type | Description |
|---|---|---|
date | date | The requested day. |
effective_date | date | The banking day for which the rate was published. |
base | string | The currency the rates are expressed in: RON. |
rates | object | For each currency: rate, in lei for multiplier units of the currency. |
source | object | The source of the rate and when it was retrieved. |
GET /rest/v1/fx/series
A currency's rate over a period.
| Parameter | Where | Description |
|---|---|---|
currency | in the query, required | The currency code, for example EUR. |
from | in the query, required | The first day. |
to | in the query, required | The last day. |
curl https://api.apifirme.dev/rest/v1/fx/series?currency=EUR&from=2026-09-01&to=2026-09-30 \
-H "Authorization: Bearer af_live_..."
Responses:
| Code | What it means |
|---|---|
200 | The rate of every banking day of the period. |
400 | A parameter is missing or not valid; detail says which. |
401 | The API key is missing or not valid. |
429 | The limit per minute or the month's number of requests has been exceeded. Does not count as a request. |
The 200 response is a FxSeries object:
| Field | Type | Description |
|---|---|---|
currency | string | The currency. |
base | string | RON. |
from | date | The first day of the period. |
to | date | The last day of the period. |
series | array | For each banking day: date, rate and multiplier. |
GET /rest/v1/fx/convert
Conversion between two currencies.
| Parameter | Where | Description |
|---|---|---|
from | in the query, required | The currency of the amount, for example EUR. |
to | in the query, required | The currency of the result, for example RON. |
amount | in the query, required | The amount. |
date | in the query | The day of the rate. Today by default. |
curl https://api.apifirme.dev/rest/v1/fx/convert?from=EUR&to=RON&amount=100 \
-H "Authorization: Bearer af_live_..."
Responses:
| Code | What it means |
|---|---|
200 | The amount converted at BNR's rate. |
400 | A parameter is missing or not valid; detail says which. |
401 | The API key is missing or not valid. |
404 | Does not exist: an unregistered CUI, a natural person, or no data for the day or year requested. |
429 | The limit per minute or the month's number of requests has been exceeded. Does not count as a request. |
The 200 response is a FxConversion object:
| Field | Type | Description |
|---|---|---|
from | string | The currency of the amount. |
to | string | The currency of the result. |
amount | number | The amount. |
result | number | The converted amount. |
rate | number | The rate used, from from to to. |
date | date | The requested day. |
effective_date | date | The banking day of the rate used. |
Validation
Checks that need no key.
GET /rest/v1/validate/cui/{cui}
Check a CUI. Checks the form and the check digit. Does not say whether a company with this CUI exists. No key, free of charge.
Needs no key.
| Parameter | Where | Description |
|---|---|---|
cui | in the path, required | The unique registration code (CUI), with or without the RO prefix, for example 13548146. |
curl https://api.apifirme.dev/rest/v1/validate/cui/13548146
Responses:
| Code | What it means |
|---|---|
200 | The result of the check. |
The 200 response is a CuiValidation object:
| Field | Type | Description |
|---|---|---|
cui | integer or string | The CUI as a number, if it is valid; otherwise the text received. |
valid | boolean | Whether the form and the check digit are correct. |
Webhooks
Plans that include the list of new companies can receive every new company at an address of their own, without asking. The address (https only) and the filters are registered in the account, where the secret the messages are signed with is shown, once. The account also shows the latest deliveries, with how each one ended.
POST company.registered
Sent to the address registered in the account, a few minutes after a new company that matches the webhook's filters has entered our database. The X-Apifirme-Signature header has the form t=<Unix time>,v1=<signature>; the signature is HMAC-SHA256, in hexadecimal, over <t>.<request body>, with the webhook's secret as the key. Any 2xx answer within ten seconds confirms receipt; otherwise the delivery is retried up to eight times, with ever longer pauses, for almost a day. The same company always has the same id, so a repeated delivery can be recognised, and each webhook receives a company only once: the first time it matches its filters. After five deliveries in a row have been given up on, the webhook is switched off and can be switched on again in the account. A test message (test: true) can be sent from the account at any time.
The body is a RegistrationEvent object. Verifying the signature, for example in a shell:
printf '%s.%s' "$t" "$body" | openssl dgst -sha256 -hmac "$secret"
The result must be equal to v1 from the header; a t older than a few minutes can be rejected.
Structures
The objects the responses above refer to.
Company
| Field | Type | Description |
|---|---|---|
cui | integer | The unique registration code (CUI). |
denumire | string or null | The name. |
nr_reg_com | string or null | The registration number in the trade register. |
euid | string or null | The European unique identifier (source: ONRC, the trade register). |
sediu_secundar | boolean | Whether it is the secondary seat of a company, registered at ANAF with a CUI of its own. |
forma_juridica | string or null | The legal form as ANAF writes it. |
forma_juridica_cod | string or null | The legal form from the trade register: SRL, SA, ... |
stare | string or null | The status, in one word: FUNCTIUNE (in operation), SUSPENDARE (suspended), REORGANIZARE JUDICIARA (judicial reorganisation), INSOLVENTA (insolvency), DIZOLVARE (dissolution), LICHIDARE (liquidation), FALIMENT (bankruptcy), RADIERE (struck off). |
stari_registru | array | All statuses and remarks from the trade register, each with cod (code) and denumire (name). |
caen | integer or null | The CAEN code of the main activity (source: ANAF). CAEN is the Romanian classification of economic activities, aligned with NACE. |
caen_denumire | string or null | The name of the CAEN code, in the classification in force. |
caen_autorizate | array or null | The activities the company is authorised for, from the trade register's open data: each with cod (code), versiune (the version of the CAEN classification it was declared in: 3 is the one of 2025, 2 the one of 2008, 1 the one of 2003, 0 the one of 1998) and denumire (name), the newest classification first. The register also keeps what was declared in the old classifications, so the same activity can appear with codes of several versions. null when they are not known (the company is not in the register's dataset), which does not mean that it has none. |
data_inregistrare | date or null | The date of fiscal registration (source: ANAF). |
data_inmatriculare | date or null | The date of entry in the trade register (source: ONRC). |
web | string or null | The web address declared to the trade register. |
judet | string or null | The county code of the registered office: SB, B, ... |
localitate | string or null | The locality of the registered office. |
adresa_completa | string or null | The address of the registered office, as one text. |
cod_postal | string or null | The postal code. |
telefon | string or null | The telephone number declared to ANAF. |
scp_tva | boolean | Whether it is registered for VAT. |
data_inceput_tva | date or null | Since when it has been registered for VAT. |
data_sfarsit_tva | date or null | Until when it was registered, if it no longer is. |
tva_incasare | boolean | Whether it applies VAT on collection. |
split_tva | boolean | Whether it applies split VAT payment. |
status_inactiv | boolean | Whether it is declared fiscally inactive. |
data_inactivare | date or null | Since when it has been inactive. |
e_factura | boolean | Whether it is in the RO e-Factura register. |
updated_at | date-time or null | When something in the company's data last changed. |
checked_at | date-time or null | When ANAF was last asked about the company; null if not yet. |
sources | array of Source | Which sources the company's data comes from, and since when. |
Source
| Field | Type | Description |
|---|---|---|
source | string | The source's key: anaf_ws, onrc_bulk, mf_financials. |
name | string | The source's name. |
publisher | string | The institution that publishes the data. |
url | string | The source's address. |
licence | string or null | The licence under which the data is published, where one is stated. |
dataset | string or null | The dataset the information was last taken from, for the sources that publish files. |
dataset_url | string or null | The dataset's page (for financial statements). |
published_at | date-time or null | When the institution published the file (for financial statements). |
first_retrieved_at | date-time or null | When the source first supplied the information. |
last_retrieved_at | date-time or null | When it last supplied it. |
import_run_id | integer or null | The import run that brought the information. |
Event
| Field | Type | Description |
|---|---|---|
type | string | The kind of change: vat_registered, vat_deregistered, vat_on_collection_started, vat_on_collection_ended, split_vat_started, split_vat_ended, inactivated, reactivated, efactura_registered, efactura_deregistered, struck_off, status_changed, name_changed, address_changed, caen_changed. |
old | object or null | The value before, under the name of the field that changed (denumire, adresa_completa, stare, caen); null when the event is a beginning or an end. |
new | object or null | The value after, likewise. |
occurred_on | date or null | The day the source gives for the change, where it gives one (for example the beginning of the VAT period). |
detected_at | date-time | When we observed the change. |
source | string | The key of the source in whose answer the change appeared: anaf_ws. |
Statement
| Field | Type | Description |
|---|---|---|
cui | integer | The company's CUI. |
an | integer | The year of the financial statement. |
tip_raportare | string | The Ministry of Finance's reporting type: UU (abbreviated balance sheet), BL_BS_SL, IR (IFRS), ONG (non-profit organisations), ... |
tip_raportare_descriere | string or null | What kind of taxpayers file this type. |
caen | integer or null | The CAEN code from the financial statement. |
caen_denumire | string or null | The name of the code, in the classification in force in that year. |
active_imobilizate | integer or null | Fixed assets, total. In whole lei; null if the ministry does not publish the value. |
active_circulante | integer or null | Current assets, total. In whole lei; null if the ministry does not publish the value. |
stocuri | integer or null | Inventories. In whole lei; null if the ministry does not publish the value. |
creante | integer or null | Receivables. In whole lei; null if the ministry does not publish the value. |
casa_banca | integer or null | Cash and bank accounts. In whole lei; null if the ministry does not publish the value. |
cheltuieli_avans | integer or null | Prepaid expenses. In whole lei; null if the ministry does not publish the value. |
datorii | integer or null | Liabilities. In whole lei; null if the ministry does not publish the value. |
venituri_avans | integer or null | Deferred income. In whole lei; null if the ministry does not publish the value. |
provizioane | integer or null | Provisions. In whole lei; null if the ministry does not publish the value. |
capitaluri_total | integer or null | Equity, total. In whole lei; null if the ministry does not publish the value. |
capital_social | integer or null | Subscribed and paid-up share capital. In whole lei; null if the ministry does not publish the value. |
patrimoniul_regiei | integer or null | Patrimony of the autonomous state enterprise (regie). In whole lei; null if the ministry does not publish the value. |
cifra_afaceri | integer or null | Net turnover. In whole lei; null if the ministry does not publish the value. |
venituri_totale | integer or null | Total income. In whole lei; null if the ministry does not publish the value. |
cheltuieli_totale | integer or null | Total expenses. In whole lei; null if the ministry does not publish the value. |
profit_brut | integer or null | Gross profit. In whole lei; null if the ministry does not publish the value. |
pierdere_bruta | integer or null | Gross loss. In whole lei; null if the ministry does not publish the value. |
profit_net | integer or null | Net profit. In whole lei; null if the ministry does not publish the value. |
pierdere_neta | integer or null | Net loss. In whole lei; null if the ministry does not publish the value. |
nr_mediu_salariati | integer or null | Average number of employees. In whole lei; null if the ministry does not publish the value. |
alti_indicatori | array | The indicators this reporting type has in addition, each with cod (code), denumire (name) and valoare (value). |
updated_at | date-time | When the statement last changed in our database. |
sources | array of Source | The dataset the statement comes from, when the ministry published it and when we retrieved it. |
Registration
| Field | Type | Description |
|---|---|---|
cui | integer | The unique registration code (CUI). |
denumire | string or null | The name. |
nr_reg_com | string or null | The registration number in the trade register. |
euid | string or null | The European unique identifier (source: ONRC, the trade register). |
sediu_secundar | boolean | Whether it is the secondary seat of a company, registered at ANAF with a CUI of its own. |
forma_juridica | string or null | The legal form as ANAF writes it. |
forma_juridica_cod | string or null | The legal form from the trade register: SRL, SA, ... |
stare | string or null | The status, in one word: FUNCTIUNE (in operation), SUSPENDARE (suspended), REORGANIZARE JUDICIARA (judicial reorganisation), INSOLVENTA (insolvency), DIZOLVARE (dissolution), LICHIDARE (liquidation), FALIMENT (bankruptcy), RADIERE (struck off). |
stari_registru | array | All statuses and remarks from the trade register, each with cod (code) and denumire (name). |
caen | integer or null | The CAEN code of the main activity (source: ANAF). CAEN is the Romanian classification of economic activities, aligned with NACE. |
caen_denumire | string or null | The name of the CAEN code, in the classification in force. |
caen_autorizate | array or null | The activities the company is authorised for, from the trade register's open data: each with cod (code), versiune (the version of the CAEN classification it was declared in: 3 is the one of 2025, 2 the one of 2008, 1 the one of 2003, 0 the one of 1998) and denumire (name), the newest classification first. The register also keeps what was declared in the old classifications, so the same activity can appear with codes of several versions. null when they are not known (the company is not in the register's dataset), which does not mean that it has none. |
data_inregistrare | date or null | The date of fiscal registration (source: ANAF). |
data_inmatriculare | date or null | The date of entry in the trade register (source: ONRC). |
web | string or null | The web address declared to the trade register. |
judet | string or null | The county code of the registered office: SB, B, ... |
localitate | string or null | The locality of the registered office. |
adresa_completa | string or null | The address of the registered office, as one text. |
cod_postal | string or null | The postal code. |
telefon | string or null | The telephone number declared to ANAF. |
scp_tva | boolean | Whether it is registered for VAT. |
data_inceput_tva | date or null | Since when it has been registered for VAT. |
data_sfarsit_tva | date or null | Until when it was registered, if it no longer is. |
tva_incasare | boolean | Whether it applies VAT on collection. |
split_tva | boolean | Whether it applies split VAT payment. |
status_inactiv | boolean | Whether it is declared fiscally inactive. |
data_inactivare | date or null | Since when it has been inactive. |
e_factura | boolean | Whether it is in the RO e-Factura register. |
updated_at | date-time or null | When something in the company's data last changed. |
checked_at | date-time or null | When ANAF was last asked about the company; null if not yet. |
sources | array of Source | Which sources the company's data comes from, and since when. |
registered_on | date or null | The registration date: the entry in the trade register where it is known, otherwise the fiscal registration at ANAF. |
discovered_at | date-time | The company's place in the order of discovery: the moment it entered our database or, if its CAEN code, county or legal form became known later, that moment. |
RegistrationEvent
| Field | Type | Description |
|---|---|---|
id | string | Identifies the event: company.registered: followed by the CUI. The same on every retry. |
type | string | The kind of event: company.registered. |
test | boolean | true for a test message requested from the account: it has the form of a real one, with some company, and an id that starts with test:. |
created_at | date-time | When the event was created. |
data | Registration | The company, exactly as GET /rest/v1/registrations returns it. |
Problem
| Field | Type | Description |
|---|---|---|
type | string | The address that identifies the kind of error. |
title | string | The error, in short. |
status | integer | The HTTP status code. |
detail | string | What exactly went wrong. |