Czech Company Data — ARES Search, VAT & Directors
Pricing
from $3.00 / 1,000 results
Czech Company Data — ARES Search, VAT & Directors
Search Czech companies by name/IČO, or DISCOVER them by industry (NACE) + city + legal form, from the official ARES registry. Returns identity, VAT (DIČ), NACE, address, founding date, plus optional directors & share capital. Open data, no key.
Pricing
from $3.00 / 1,000 results
Rating
0.0
(0)
Developer
Berkan Kaplan
Maintained by CommunityActor stats
0
Bookmarked
7
Total users
1
Monthly active users
17 days ago
Last modified
Categories
Share
Czech Company Data — ARES Registry 🇨🇿
foXLabs European company-registry series: UK · France · Estonia · Latvia · Poland · Slovakia · Slovenia · Denmark · Norway · Finland
🎉 Turn the Czech ARES registry into clean, structured company data — no login, no API key, one row per company, with the IČO, tax ID, legal form, NACE codes, address and, on request, the people in its statutory body and its registered capital. Built for KYB / compliance, B2B sales research and market-research teams.
🔍 What is Czech Company Data — and when should you use it?
Give this Actor IČO numbers, a company name, or a NACE code + city + legal form, and it returns the matching companies from ARES, the Czech Ministry of Finance's register of economic subjects, read through its public API. With one switch it adds each company's statutory body, supervisory board and registered capital from the public register.
Use it when you need: the registry record of known Czech companies by IČO; companies whose name contains a word; or the companies of a city by NACE branch, by legal form or by both — measured from 144 matches (a.s. companies in Olomouc that list a wholesale code) to 7,329 (every s.r.o. in Olomouc; 7,254 of them were delivered). "IT" on this page means: lists a code of NACE division 62.
Use something else when: you need e-mail addresses, phone numbers or websites — this Actor returns none — or a complete list of a very large search in one run: ARES holds 35,387 IT s.r.o. companies for Praha, and no run of that size was measured (see "The 1,000 limit").
🤖 Use with AI agents
Already on the Apify MCP server? Ask for this Actor by name: foxlabs/czech-company-data. Checked on 2026-10-08: the server lists it as the tool foxlabs--czech-company-data.
Your agent can pay for its own runs. For an agent with a wallet and no human to sign in, Apify sells a prepaid, spend-capped API token over x402 at agi.apify.com; such a token runs any Actor that uses limited permissions, as this one does (the terms of that path are Apify's own — see apify.com/agents.md). The Actor also meets Apify's conditions for per-request agentic payments — pay-per-event only, limited permissions, no Standby — and Apify Store lists it as eligible for them (read from the Store on 2026-10-08). The Actor charges the same events either way: one per company delivered, plus the run start.
Otherwise paste this into Claude, ChatGPT, Cursor or any MCP-enabled assistant:
I want Czech company records from the Apify Actor `foxlabs/czech-company-data`.Input, one of three ways: `icoList` is a list of IČO numbers (while it holds one, the other search fields are not used); `searchQuery` is one or more whole words of the company name (a part of a word finds nothing; several words must all be in the name); or discover companies with `naceActivity` (a CZ-NACE 2025 code that stands for its whole branch: "62" is all of division 62; a 2008 code such as "6201" finds nothing), `city` and `legalForm` ("112" = s.r.o., "121" = a.s., "100" = sole traders); `city` alone fails the run — it is not offered as a search; give a sector, a legal form or a name with it. `onlyActive` leaves out companies that have ended, are in liquidation or have an insolvency entry. `includeDirectors` adds the statutory body, the supervisory board and the registered capital. `maxResults` caps the rows (default 1,000); every row delivered is charged. The run's status message says how many companies were delivered and what was left out — read it and tell me.Start with: {"icoList":["00177041","45274649"],"includeDirectors":true}Ask me which companies or which sector and city I want, run the Actor, then show the companies as a table with name, IČO, tax ID, city and directors.
The Actor's machine-readable page is apify.com/foxlabs/czech-company-data.md: API examples, the MCP config, the input texts and a link to the OpenAPI definition (read on 2026-10-08).
📋 Overview
Why teams pick this Actor:
- ✅ The official register, read live — every run queries the ARES API.
- 🧭 Discovery, not only lookup — list the companies of a city that list a code of a NACE branch, without knowing a single name. A search over ARES's limit of 1,000 results is read in smaller searches: one run delivered 3,929 of the 3,931 IT s.r.o. companies ARES holds for Brno.
- 👤 The people behind the company — with
includeDirectors, 1,202 of 1,219 measured companies came back with at least one entry in the statutory body. - 💰 Pay only for companies delivered — a run that delivers nothing costs only the run start.
- 🤖 Agent-ready — MCP tool + agentic payments.
✨ Features
- 🔢 IČO lookup — exact company numbers, as many as
maxResultsallows. - 🔎 Name search — companies whose name has your word, as a whole word (several words: all of them); accents and case do not matter.
- 🧭 Discovery — a CZ-NACE branch, a legal form and a city, combined.
- 👥 Statutory body, supervisory board and capital — entries in force only.
- 🚦 Status on every row —
isActive,inLiquidationandinsolvencyRecord;onlyActivefilters on them. - 🧹 Clean schema — 21 camelCase fields, 28 with
includeDirectors.
🎬 Quick Start
curl -X POST "https://api.apify.com/v2/acts/foxlabs~czech-company-data/runs?token=YOUR_TOKEN" \-H "Content-Type: application/json" \-d '{"icoList":["00177041","45274649"],"includeDirectors":true}'
The call starts a run and returns it; the rows are in the run's default dataset. On 2026-10-08 this input returned Škoda Auto a.s. and ČEZ, a. s. with their boards and capital, in 4 seconds at 512 MB of memory; the run ended with the status message "Delivered 2 companies for 2 IČO numbers."
🚀 Getting Started (3 steps)
- Choose a way in — IČO numbers, a name, or a NACE code with a city and a legal form.
- Decide on directors — switch
includeDirectorson if you want the people and the capital; it adds one lookup per company. - Run and read the status message — it says how many companies were delivered and what was left out.
In the Console form icoList comes pre-filled with two examples; empty it to search another way.
📥 Input
{"icoList":["00177041","45274649"],"includeDirectors":true}
A run needs at least one of icoList, searchQuery, naceActivity or legalForm; without one it fails and says so. city alone fails the run too: it is not offered as a search, and the message says so and names what to add. The reason is not ARES — it answers such a search with the count, like any other over its limit (32,138 entities for Olomouc in October 2026) — but that a city can hold far more than a run reads: a test version of this Actor that read Olomouc alone in slices (one run from our own machine, not on the platform) delivered 11,189 of the 32,138, every one a natural person in business and not one company. Give legalForm, naceActivity or searchQuery with the city: s.r.o. + Olomouc returned 7,254 of 7,329.
"The previous test build" on this page is build 0.1.17, measured on the platform on 2026-10-09. This build was made from it. It differs in what a run does when it is started a second time, in the rules for a public register that does not answer, in two rules for capital written as free text and in how a few rare answers of ARES are read (see the changelog). Each of these was then run on the platform on 2026-10-09 (build 0.1.18): where a sentence below says "measured on this build", the number comes from those runs.
| Field | Type | Description |
|---|---|---|
icoList | array | IČO numbers; one entry may hold several, separated by commas. While the list holds a number, the name and discovery fields are not used. Lost leading zeros are restored (177041 → 00177041) and a number given twice is looked up once. The status message names the numbers ARES does not know (record NOT_FOUND), separately those it did not answer for (NO_ANSWER), and the entries that cannot be an IČO. A list longer than maxResults is looked up only that far. Under a maximum charge the run looks up only as many numbers as the charge still covers, so every company it finds is delivered; the status message says how many numbers were not looked up and why, and the record NOT_DELIVERED lists them for a later run. Measured on the previous test build and again on this one: 120 numbers at a maximum charge of $0.06 ended after 19 lookups and 19 rows, with "101 more numbers were not looked up: the run's maximum charge covers no further company." and the 101 numbers in NOT_DELIVERED. |
searchQuery | string | A whole word of the company name; case and accents do not matter (skoda finds Škoda). A part of a word finds nothing: asked in Olomouc on 2026-10-08, servis returned 97 companies, serv and servi none, and autoservis 10 others (none of them among the 97). With several words every one must be in the name, in any order and not side by side: auto servis and servis auto returned the same single company, AUTO MOTO SERVIS ANDĚL s.r.o. (auto alone: 29). Of 1,935 names returned for servis, 4 do not contain it: sole traders listed under the person's name. |
naceActivity | string | A CZ-NACE 2025 code, digits only, standing for its whole branch: ARES matches a code only when a company lists exactly that code, so the Actor searches every code of ARES's list that starts with these digits — 62 (computer programming and consultancy) is 11 codes, 47 (retail) 82. 46 (wholesale), with 106, is read as two searches, and such a run's status message carries no total. A code outside the list (6201, from the 2008 classification) and a value with no digit (J) read nothing; the status message says why. |
legalForm | string | One legal form by ARES code: 112 s.r.o., 121 a.s., 111 v.o.s., 113 k.s., 205 cooperative, 100 sole trader (searched as the codes 100–108), 421 branch of a foreign company, 141 public benefit company (o.p.s.), 301 state enterprise, 706 association. It also works with a city and no sector. Without it every legal form comes back, natural persons included. |
city | string | Text ARES matches against the registered address: a municipality (Olomouc, Brno), or a district, city part or street to narrow a large search. Accents do not matter: Plzen and Plzeň each counted 345 a.s. companies, and the first 100 rows of the two answers were the same (the other 245 were not compared). Not exact — 45 of the 7,254 rows for s.r.o. + Olomouc have an address without the word. |
addressQuery | string | Extra filter on what ARES returned, also on IČO lookups: keep companies whose address contains this text; case and accents do not matter (plzen keeps Plzeň). The accents are new: the released build compared in lower case only. Measured on the previous test build: with Plzen, the 10 rows a run returned all spell Plzeň. Horní kept 3 of the 247 IT s.r.o. companies of Olomouc. |
onlyActive | boolean | Leave out a company that has ended (isActive is false), is in liquidation (inLiquidation) or has a live insolvency or bankruptcy entry (insolvencyRecord) — also on IČO lookups. |
includeDirectors | boolean | Add the statutory body, the supervisory board and the registered capital. Off by default in the API; ticked in the Console form. If the public register does not answer, see "directors is null" under Troubleshooting. |
maxResults | integer | Most companies to deliver. Default 1,000; 1 to 100,000. In a search it is counted after onlyActive and addressQuery: the run reads on until that many are left. A list of IČO numbers is cut to its first maxResults numbers before any lookup, so with a filter fewer rows can come back. The rows of one search came in ascending IČO order in every measured run, so a low number returns the lowest IČO numbers, not a sample. |
The 1,000 limit
ARES lists at most 1,000 companies per search; a larger search gets the count and no rows. The Actor then reads it in smaller searches, each company once: it cuts by legal form, then by tax office, then by NACE code (every division when you gave no sector) and last by city part — the parts met in the rows already read for the same tax office.
Measured on 2026-10-08 at 512 MB of memory:
| Search | ARES holds | Delivered |
|---|---|---|
62 + Brno + s.r.o. | 3,931 | 3,929, in 39 smaller searches (21 of them held rows) and 37 seconds |
s.r.o. + Olomouc, no sector | 7,329 | 7,254, in 444 smaller searches (315 held rows) and 216 seconds |
62 + Brno, no legal form, maxResults 3000 | 7,705 | the first 3,000, from 17 smaller searches (5 held rows) |
name servis, maxResults 1500 | 6,369 | the first 1,500, from 11 smaller searches (all held rows) |
62 + Praha + s.r.o., maxResults 1000 | 35,387 | the first 1,000, from 21 smaller searches (all held rows) |
"Smaller searches" is the number the status message gives: the searches ARES answered with a list, an empty list included; the answers that were over the limit again are not in it. The first search is {"naceActivity":"62","legalForm":"112","city":"Brno","maxResults":100000}; without maxResults a run stops at 1,000.
- A few companies stay out of reach — 2 of 3,931 in the Brno run, 75 of 7,329 in the Olomouc run. The status message counts them: a company with no tax office on record, with no NACE code or with no city part in its address falls through the cuts.
- A cap delivers the first slices, not a sample. With no legal form the cut starts with form 101: the first 3,000 of the 7,705 entities for
62+Brno(3,931 of them s.r.o.) were all sole traders. Tax offices are asked in the order of ARES's list: a run for s.r.o. +Olomoucthat its maximum charge stopped at 19 companies never reached Olomouc's own office, and 17 of the 19 have an address elsewhere. - A much larger search without a legal form is cut short by the budget below, and unevenly. The one measurement is the test of
Olomoucalone described under Input (32,138 entities; that search is not offered): the budget of 40 over-limit answers ran out while the run was still cutting form 101, and 11,189 rows came back, not one of them a company. By the code, and in a simulated register, a sector or name search of that size is cut in the same order — form 101 first — and its status message names the legal forms it did not read;legalFormgives one form the whole budget. Between that size and the 7,329 of s.r.o. +Olomouc, read to 99 %, no run was measured. - The run stops cutting after 40 over-limit answers or 1,500 smaller searches asked (every one it asks counts, whatever the answer): ARES answers an over-limit search with an input error, and its operating conditions name repeated wrongly filled queries (see "How fast is it?"). The largest measured platform run (s.r.o. +
Olomouc) used 27 of the 40 and 470 of the 1,500: of those 470, ARES answered 26 with "over the limit" again, 315 with rows and 129 with an empty list. All of Praha's 35,387 in one run was not measured — the capped run had spent 16 over-limit answers by its 1,000th row. Narrow such a search incity: asked on ARES directly that day,Praha Chodovheld 574 IT s.r.o. companies;Praha 4(6,079) was still over the limit. - What stopped the reading is in the run's
OVER_LIMITrecord (stopped), with the smaller searches that were asked and still held more than 1,000 (notListed) and those a budget stop or an outage left unasked (notAskednames the first 300 of them,slicesNotAskedcounts them all). What a stop atmaxResultsor at the maximum charge left unread is not listed anywhere: a new run starts from the beginning.
📤 Output
One row per company, saved to the dataset.
{"name": "Škoda Auto a.s.","ico": "00177041","vat": "CZ00177041","legalForm": "Joint-stock company (a.s.)","legalFormCode": "121","address": "tř. Václava Klementa 869, Mladá Boleslav II, 29301 Mladá Boleslav","city": "Mladá Boleslav","region": "Středočeský kraj","postalCode": "29301","nace": ["70200", "471", "77110"],"primaryNace": "70200","foundingDate": "1990-11-20","endDate": null,"isActive": true,"inLiquidation": false,"insolvencyRecord": false,"activeRegisters": ["Ros", "Vr", "Res", "Rzp", "Nrpzs", "Dph", "Rs", "Red"],"aresUrl": "https://ares.gov.cz/ekonomicke-subjekty?ico=00177041","source": "ARES — Administrative Register of Economic Entities (Czech Republic)","license": "Open data — Ministry of Finance of the Czech Republic","scrapedAt": "2026-10-08T20:27:16.696Z","directors": [{ "name": "ANDREAS DICK", "role": "Prokura", "type": "person", "from": null, "addressCountry": "CZ" }],"directorsCount": 7,"directorsTruncated": false,"supervisoryBoard": [{ "name": "THOMAS SCHÄFER", "role": "předseda dozorčí rady", "type": "person", "from": "2026-07-01", "addressCountry": "DE" }],"supervisoryBoardCount": 9,"supervisoryBoardTruncated": false,"capital": { "amount": 16708850000, "currency": "CZK" }}
The example is a real row, with nace cut to three codes and each board to its first entry. "Filled" counts the 17,429 different entities the measured runs of 2026-10-08 delivered; the last four lines count the 1,219 companies read with includeDirectors: 219 IT s.r.o. in Olomouc (with onlyActive) and the first 1,000 a.s. in Brno — those 1,000 from a run of an earlier test build of this version, whose lists of people are built by the same code.
| Field | What it is | Filled |
|---|---|---|
name | Registered name | 17,429 |
ico / aresUrl | The company number (IČO) and the company's page on ares.gov.cz. Both are null for an entity ARES knows from the trade register only: 13 rows, all from name searches | 17,416 |
vat | Tax identification number (DIČ) — not proof of VAT payment: a VAT payer has Dph in activeRegisters (8,271 rows) or, as member of a VAT group, SkDph (89) | 10,017 |
legalForm / legalFormCode | Legal form in English for 29 ARES codes, otherwise the code itself (707) | 17,429 |
address | Registered address as one line | 17,426 |
city / region / postalCode | Municipality, region and postal code | 17,220 |
nace / primaryNace | Every CZ-NACE code the company lists — 1 to 28 in the Olomouc IT run, two to five digits deep, with section letters such as G — and the first of them, which is not the main activity: Škoda Auto's list starts with 70200 and has 29100 (motor vehicles) in tenth place | 17,412 |
foundingDate / endDate | Date of formation; date the entity ended, when ARES gives one — in none of these rows | 17,416 / 0 |
isActive | The entity exists: active in the register of persons (or, with no entry there, in any source register) and no end date. A company in liquidation still exists | false on 8 |
inLiquidation | The name carries "v likvidaci" or one of two rarer spellings | true on 1,052 |
insolvencyRecord | A live entry in the insolvency register or in the older register of bankrupts (Ir or Ceu in activeRegisters) | true on 138 |
activeRegisters | The source registers that list the entity as active: Ros register of persons, Vr public register, Rzp trade-licence register, Dph VAT payers … | 17,429 |
source / license / scrapedAt | Two fixed labels — license is the Actor's own wording, not a licence text of ARES — and the time the record was read from ARES (UTC) | 17,429 |
directors | Entries in force in the statutory body, each with name, role, type (person or entity), from and addressCountry. An empty list: the public register has no entry in force, or no record. null: it did not answer for this company, asked twice, or answered with an error; the status message counts such rows (none in the measured runs) | 1,202 with at least one; 1,160 with someone other than a liquidator |
directorsCount / directorsTruncated | Number of different people; true when the list had more than 30 entries and was cut (never in these rows) | 1,219 |
supervisoryBoard (+ count, truncated) | Entries in force in the other bodies | s.r.o.: 1 of 219; a.s.: 483 of 1,000 |
capital | Registered capital: amount and currency (CZK or EUR; any other currency word of the register would come through as written). Where the register holds the capital as free text, the amount is the number in front only when nothing but a currency follows it (110000,- Kč → 110000; 2 mil. Kč → null) and the number has no comma before exactly three digits (100,000 Kč → null: thousands to one writer, decimals to another); the currency is the one the text names as a word (Kč, CZK, korun českých; EUR, euro, €), and null when it names none or both. Six such texts were met, read again on the previous test build: 110000,- Kč → 110000 CZK; 2000000 → 2000000, no currency; 100 Kč → 100 CZK; sto tisíc korun českých and jedna koruna česká, written in words → no amount, CZK; and one whose text was not saved → 500000 CZK | 1,215; 9 of them (6 free texts, 3 amounts in euro) come from the first test build, which read them differently — see the changelog |
About the people: the 1,219 companies carry 2,040 entries in directors — all with a role, 1,891 with a start date, 2,038 with an address country (CZ in 1,906). Roles come in Czech as registered, in 57 spellings (jednatel, Jednatel, Prokura); liquidators (68 entries) and holders of procuration (55) are listed too. addressCountry is the country of the registered address, not a citizenship: the public register's answer held no citizenship field on 2026-10-08, and ARES's API description lists one for the trade register only.
💼 Use cases
1. Companies of a city that list a NACE branch — names you do not know yet, with the people who run them.
Input: {"naceActivity":"62","city":"Olomouc","legalForm":"112","onlyActive":true,"includeDirectors":true,"maxResults":300}. Output: 219 companies on 2026-10-08, each with at least one entry in its statutory body and a capital amount; onlyActive left out 28 more. Read it critically: all 219 list a code of division 62 — 188 the code 62, 31 only a longer one (62200, 6210, 62900) — but for 183 the first listed code belongs to another branch, and 2 have an address outside Olomouc. A company that lists no code of the division is not in the list, whatever it does.
2. Verify known companies — the registry record behind an IČO.
Input: {"icoList":["00177041","45274649"],"includeDirectors":true}. Output: the two companies with tax ID, address, boards and capital. Use: KYB checks and CRM enrichment.
3. Find companies by a word in the name
Input: {"searchQuery":"servis","city":"Brno","maxResults":100000}. Output: 436 companies on 2026-10-08, all ARES held for the search, every name containing the word. 29 are flagged — 24 inLiquidation, 6 insolvencyRecord, one of them both — the rows onlyActive leaves out; 2 have no IČO. Use: map a niche by how companies name themselves.
🔗 Integration
JavaScript / Node.js
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: 'YOUR_TOKEN' });const run = await client.actor('foxlabs/czech-company-data').call({"icoList":["00177041","45274649"],"includeDirectors":true});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items[0]);
Python
from apify_client import ApifyClientclient = ApifyClient('YOUR_TOKEN')run = client.actor('foxlabs/czech-company-data').call(run_input={"icoList":["00177041","45274649"],"includeDirectors":True})for item in client.dataset(run.default_dataset_id).iterate_items():print(item)
Written for apify-client 3 for Python, where call() returns a run object; with version 1 or 2 it returns a dict — write run['defaultDatasetId'] there.
Automation (n8n / Zapier / Make): send the IČO numbers from your CRM → read the JSON dataset → write tax ID, address and directors back.
📊 Pricing
Pay-per-event. Read from the Store on 2026-10-08: $0.003 per company written to the dataset ($3 per 1,000) plus Apify's run-start event, counted per GB of run memory: one event at 512 MB and at 1 GB, two at the default 2 GB (counted in the measured runs). Each delivered row is one event (in every measured run), also a row whose register lookup got no answer (directors: null). An IČO that ARES does not know writes no row and costs nothing. A run that delivers nothing costs only the run start: measured with a NACE code outside ARES's list and with a search whose 129 matches onlyActive all left out. With a maximum charge a search stops reading at the number of companies it covers: at $0.06 a search that holds 7,329 companies ended after 19, in 9 seconds, and said so. A list of IČO numbers is looked up only as far as the charge covers: 120 numbers at $0.06 ended after 19 lookups and 19 rows (measured on the previous test build and again on this one). A run that starts a second time — the platform moved it to another server, or you resurrected it — writes, and so charges, no row its dataset already holds (measured on this build: a search restarted at 400 rows ended with 1,200 rows, none twice, 1,200 charged; see the FAQ). View current pricing.
🚧 What it does not do
- No e-mail, phone or website.
- Not every company of a search over ARES's 1,000 limit — a few stay out of reach and a search of Praha's size was not run in full; see "The 1,000 limit".
- No search by
cityalone — such a run fails with a message; a city needs a sector, a legal form or a name beside it (see Input). - No continuing in a new run. A search that ends at a cap, at the maximum charge, at its time limit or at an outage starts from the beginning in a new run and delivers — and charges — the same first rows again. Only a list of IČO numbers can be continued in a new run, from the run's
NOT_DELIVEREDrecord (written when the run finishes). The same run started again is another matter: see "What if the platform restarts my run, or I resurrect it?" in the FAQ. onlyActiveis a register test, not proof of trading. It leaves out what the registers and the name show — 1,174 of the 17,429 entities measured. A company with none of these marks stays in, whatever its business does.- No sector ranking. A NACE search finds every company that lists a code of the branch, whatever its main business (see use case 1).
- People are names, roles, start dates and the country of the address — no date of birth, street address or citizenship. An entry of type
entitycan be an individual: 24 of the 77 measured are liquidators entered under a business name. - No financial statements and no shareholders.
❓ FAQ
Do I need an account, login or API key for ARES? No. The Actor reads the public ARES API.
How current is the data? Every run queries ARES live.
How fast is it? Measured at 512 MB of memory: two companies by IČO with directors took 4 seconds; 436 companies by name 5 seconds; "The 1,000 limit" times two large searches. includeDirectors adds one request per company: 219 companies took 35 seconds (the released build: 216 in 18 — requests are now spaced). These runs were made on test builds that wrote every row at the end. This build writes rows while it reads — every 200 companies, or after a minute when fewer are waiting — and sets the status message Delivered … so far; still reading. after each write. A run that is aborted or cut off by its time limit ends without a closing message: it keeps the rows it has written (they are charged) and that last progress line. Measured on the previous test build, which wrote the same way: the searches above took the same time to within 6 seconds, the log shows a progress line after every 200 rows, and a run with a time limit of 90 seconds ended TIMED-OUT with 400 rows, 400 of them charged, no closing message and the status "Delivered 400 companies so far; still reading." Not measured on the platform: the write after a minute (no measured search kept fewer than 200 rows for that long; in a simulated register a narrow search wrote its first 99 rows after 60 seconds) and an abort. A list of IČO numbers is paced like every other request: 1,000 numbers are about 2.4 minutes of lookups, 4.8 with includeDirectors — computed from the pace; the longest list measured was 19 lookups. The Actor spaces its requests 143 ms apart — about seven a second, 420 a minute: in ARES's operating conditions, which its API is offered under (read on 2026-10-08), the Ministry of Finance reserves the right to restrict or block access to the ARES web application for users who send more than 500 queries a minute or repeatedly send wrongly filled queries.
Are former directors included? No. The Actor keeps the entries the register has not struck out and, per person and role, the newest one.
What does each row represent? One economic subject in ARES, once per run — also when the run is started a second time (next question). It can be a natural person: a sole trader's row holds the person's name and registered address.
What if the platform restarts my run, or I resurrect it? Apify can move a running Actor to another server; the run then starts again from the top, with the same input, the same dataset and what was already charged. Resurrecting a run — for example with a longer time limit or a higher maximum charge — does the same. This build first reads which rows its dataset already holds (by IČO; by name and address for the few entities without one). It then reads ARES from the beginning again — for a list of IČO numbers, only the numbers that have no row yet — and writes just the rows that are missing, so no row is written or charged twice. The rows that were there count as delivered: maxResults, the maximum charge, the closing message, OUTPUT and NOT_DELIVERED are those of the whole run, and a record an earlier start left behind is replaced or removed. The log says "This run was started again by the platform: its dataset already holds … rows; continuing." Three limits. When the dataset already holds everything the run may deliver, the new start reads nothing: its closing message is shorter than one uninterrupted run's, and for a list of IČO numbers NOT_DELIVERED then holds every number without a row — also the numbers ARES does not know or a filter would leave out. When ARES or the public register does not answer the new start, the run ends with a message that counts the rows already there instead of failing; a start that still fails — a sector search whose code list ARES does not return, for one — adds how many rows the dataset holds, and a start that cannot read its dataset fails before it asks ARES anything. And the Actor relies on the dataset listing every row that was written before the restart. Measured on the platform on this build (2026-10-09): a sector search of 1,200 companies with directors, restarted at 400 rows, ended with 1,200 rows, none twice, 1,200 charged, and the log line above; the same search under a maximum charge covering 619 rows, restarted at 400, ended with 619, none twice; three finished runs resurrected (19, 10 and 219 rows) kept their rows and charged none again — Apify counts its run-start event once more for a resurrected run. Before that, 36 runs against a simulated register and five with the real Apify SDK and a local dataset ended the same way.
Can I export to CSV / Excel / JSON? The rows are JSON in the Apify dataset. CSV and Excel are Apify's dataset exports and were not tested for this Actor; nace, directors and supervisoryBoard are lists.
🐛 Troubleshooting
- The run succeeded but the dataset is empty — the status message says why: no company matched (check how the city and the name are written), a filter removed every match ("129 matched in ARES and were left out by onlyActive."), or the sector cannot be searched ("No company read: "6201" is not a code of CZ-NACE 2025, the classification ARES searches." — it goes on to name the codes of the division).
- Fewer companies than ARES holds — the status message names the reason: a filter, the cap ("(stopped at maxResults 200)"), the charge limit ("The run stopped at its maximum charge; a new run starts from the beginning again.") or companies no smaller search could reach. Read from the code, in no measured run: a smaller search ARES does not answer in three tries is left out and the message says so; after five in a row the run stops asking; an error answer part-way through a search is reported as that, with ARES's own words. How long giving up takes depends on how ARES fails (computed from the Actor's waits): a request that is refused or answered with a server error has had its three tries within about 8 seconds, so five in a row are over in under a minute; a request that hangs is given 60 seconds a try, so a search stops asking after about 15 minutes of hanging requests, and a list of IČO numbers — which first finishes the lookups it has started, up to 50, five at a time — after up to 30.
directorsisnull, or the run stopped at the public register — a company the public register does not answer for (or answers with an error) is asked once more after the others. If it still has no answer, the run asks the register for a company known to have a record: the last company of the run it returned a record for or, before the first one, Škoda Auto (00177041) and then ČEZ (45274649). A record comes back: the register is alive, and the company's row is delivered withdirectors,supervisoryBoardandcapitalset tonull, charged like any row and counted in the status message. No record comes back: the register is down — the run writes the rows of that batch that have their answer, holds the others back, asks and writes nothing further and ends with "The public register stopped answering, so the run stopped there: …", whether the batch is one company or 200. A "no record" answer is an answer for the entity it was asked about — empty lists — but it never counts as proof that the register is alive. (Measured on 2026-10-09: for three sole traders without a record the register answered HTTP 404 with the code NENALEZENO, and a run of 40 sole traders withincludeDirectorsread 40 such answers.) A second stop limits the rows without what you asked for: once 25 companies of a run have been left withnulland they are more than half of the companies asked so far, the run ends the same way ("The public register answered for fewer than half of the … companies the run asked it about"); a register that answers for half of them or more is not stopped. If the register has returned no record for any company of the run when it stops, no row of that batch is written — none without an IČO either — and a run whose dataset is still empty fails. Run again later, or withoutincludeDirectors. Measured on this build: 40 sole traders asked withincludeDirectorscame as 40 rows with empty boards and nonull, and the run did not stop. A register that does not answer was met in no measured run: that path was run against a simulated register only. Not recognised: a register that answers "no record" for companies that have one — their rows would come with empty lists. When register requests hang instead of failing, giving up takes about 12 minutes for a run of up to five companies, about 18 for a larger one, and up to about 15 when the register stops in the middle of a run (computed from the waits: three tries of 60 seconds for each request, five requests at a time).- An IČO is missing from the result — the status message names it. The entries
00177041, 45274649,177041,99999999,abcand1234567890123ended with "Delivered 2 companies for 3 IČO numbers. Not in ARES: 99999999." and "Not an IČO (one to eight digits): abc, 1234567890123." - My name search returned Škoda Auto and ČEZ — the pre-filled
icoListwas still there; the status message says "searchQuery was not used: with IČO numbers in icoList the run is a lookup of those numbers. Empty icoList to search." - The run failed — the input had none of
icoList,searchQuery,naceActivityandlegalForm(cityalone is not offered as a search; the message names what to add); no entry oficoListwas an IČO; ARES gave no answer in three tries — to the search itself, to every IČO lookup, or for the CZ-NACE code list a sector search needs; or, withincludeDirectors, the public register returned a record for none of the companies it was asked about. No row is written; start the run again. Measured on the previous test build, and{"city":"Olomouc"}again on this one: both failed with their messages and were charged the start event only. The other failures are read from the code and were run against a simulated register only; there, a search address that answers HTTP 404 counts as "no answer", not as "No company matched". A request that hangs is given 60 seconds a try: a search whose first request hangs fails after about 3 minutes.
⚖️ Is it legal to use this data?
The Actor reads a public register published by the Czech Ministry of Finance. The rows contain personal data: the names of company officers and the country of their address and, for sole traders, the person's name (with an academic title such as Ing., Mgr. or Bc. in 1,438 of 3,206 measured rows), registered address and tax ID. A sole trader's tax ID is not CZ + IČO as a company's is: the 902 measured values are CZ followed by 9 or 10 digits, the first six reading as a date in 875. Personal data is protected by the GDPR and similar laws, so only process it with a legitimate basis. The license column is the Actor's own label — read ARES's conditions yourself before you republish the data. foXLabs is not affiliated with the Czech Ministry of Finance.
🤝 Support & contact
- 🌐 Website: data.foxlabs.com.tr
- 📧 Email: info@foxlabs.com.tr
- 🐛 Issues: open a ticket in the Actor’s Issues tab
- 🧰 More clean B2B data actors: Fox Labs on Apify
Changelog
0.1.18 — 2026-10-09 — a NACE code covers its whole branch, searches over ARES's 1,000 limit are read in slices, onlyActive works; README rewritten
- A NACE code now stands for its whole branch. ARES matches a code only when a company lists exactly that code, so
62missed every company that lists62200and not62. The Actor now searches every CZ-NACE 2025 code that starts with the one you give (62→ 11 codes,47→ 82). Measured on 2026-10-08 for s.r.o. in Olomouc: code62alone 216 companies, the whole division 247. A code of the older 2008 classification (6201) still reads no company, but the status message now says so and names the codes of its division. - A search that holds more than 1,000 companies no longer comes back empty. ARES lists at most 1,000 per search and answers a larger one with the count and no rows. The Actor now reads such a search in smaller ones — by legal form, then tax office, then NACE code, then city part — and its status message says how many of ARES's total it delivered and how many it could not list. The legal-form split uses ARES's complete list of forms; it used 17 hand-picked ones and lost the others without a word. A request ARES does not answer costs one of the smaller searches, not the run: what the others returned is delivered and the message says what is missing; after five unanswered requests in a row the run stops asking.
onlyActivenow removes something. It keeps a company that exists, is not in liquidation and has no live entry in the insolvency register or in the older register of bankrupts. The earlier test was true on every row measured from the earlier build (1,008 of 1,008) and removed nothing. New fieldsinLiquidation,insolvencyRecordandendDate;isActivenow means "exists": active in the register of persons and no end date.citizenshipis gone,addressCountryis new. The public register does not publish citizenship — the field the Actor read is absent from its answers on 2026-10-08, and ARES's API description lists it for the trade register only — socitizenshipwas empty in every row: all 1,047 entries (1,033 persons and 14 entities) in the measured runs of the earlier build. Each person indirectorsandsupervisoryBoardnow carriesaddressCountry, the country code of the registered address.- Unknown is
null, not "none". When the public register does not answer for a company,directors,supervisoryBoardand their counts arenull(they were empty lists, the same as a company with no board) and the status message counts those rows. Such a company is asked once more after the others first, so a blip of a few seconds leaves no gap. If it still has no answer, the run asks the register for a company known to have a record — the last one it returned a record for, or Škoda Auto and ČEZ. A record comes back: the register is alive and the row is delivered withnull. None comes back: the register is down, and the run writes the rows that have their answer, nothing after them, and says so — whatever the number of companies waiting. It stops the same way once 25 companies have been left withnulland they are more than half of those asked. When the register has returned no record at all and the dataset is empty, the run fails — before, every row came without directors and was charged. A "no record" answer never counts as proof that the register is alive, and an error the register answers for a company is no answer (null), not an empty board. (Measured on this build: 40 sole traders asked withincludeDirectorscame as 40 rows with empty boards, nonull, and the run did not stop — the register answered "no record" for each. A register that is down was met in no measured run: that path was run against a simulated register only.) IČO numbers ARES does not know are named there too, and so is an entry that cannot be an IČO. Leading zeros lost in a spreadsheet are restored (177041→00177041), one entry may hold several numbers, and a list longer thanmaxResultsis cut with a word about it. When ARES answers none of the lookups the run fails instead of ending as an empty result. - Share capital with a decimal comma is read.
42700000,00used to becomenull(2 of the 1,217 companies with a capital entry in the measured runs). Capital the register holds as free text (6 of those companies) is read as the number in front when nothing but a currency follows it, with the currency the text names as a word — otherwisenull: read again on the previous test build and on this one,110000,- Kčgave 110000CZK,2000000gave 2000000 with the currencynull,100 Kčgave 100CZK, one whose text was not saved gave 500000CZK, and the two written in words (sto tisíc korun českých,jedna koruna česká) gave no amount andCZK. A text such as2 mil. Kčgives no amount rather than 2. Two rules are newer than those runs and were run on the reading code alone: a number with a comma before exactly three digits is not read (100,000 Kčcould be a hundred thousand or a hundred), and a text that names both currencies gets none. None of the five texts that are known is of either kind. The register's currency wordEURAis delivered asEUR(3 companies: 120000, 100000 and 80000EURon the previous test build and on this one). - Legal-form labels corrected. Code 141 is a public benefit company (it was labelled "Institution"), 145 a unit owners' association (it was "Branch"), 751 an interest association of legal entities (it was "Association"). Twelve codes that delivered the bare code now carry a label (102–108 sole traders and farmers, 117, 118, 161, 501, 736). "Sole trader" in the input now covers codes 100–108; it sent code 100, which holds almost nobody.
- The form described two searches wrongly. It said ARES refuses a search by city alone. ARES does not: it answers with the count, like any search over its limit (32,138 entities for
Olomoucin October 2026). The Actor still does not offer that search, for another reason — a city can hold far more than a run reads: a test version that readOlomoucalone in slices (one run from our own machine, not on the platform) delivered 11,189 of the 32,138, all of them natural persons in business and not one company. Such an input fails as before, now with a message that gives this reason and asks for a sector, a legal form or a name beside the city. The form also said a name search finds names that "contain" the text; ARES matches whole words (servis97 companies in Olomouc,servnone) and, with several words, every one of them; the form now says so. - Input that cannot be searched says so. A sector with no digit (
J) used to be dropped, and the run delivered the companies of the other filters alone; it now reads nothing and says why. A name, sector, form or city typed next to IČO numbers is not used, and the status message says so. A sector search needs ARES's CZ-NACE code list: when ARES does not return it the run fails instead of searching the one code as typed. - Requests are spaced 143 ms apart — about seven a second, and a rate-limit answer makes the whole run wait. In ARES's operating conditions the Ministry of Finance reserves the right to restrict access for users who send more than 500 queries a minute; a run with
includeDirectorssent its register lookups as fast as they returned. Such a run now takes about twice as long: the same Olomouc search returned 216 companies in 18 seconds before and 219 in 35 now. A list of IČO numbers is paced the same way — it was looked up five numbers at a time with no pause — so 1,000 numbers are now about 2.4 minutes of lookups (computed from the pace; the longest list measured was 19 lookups). Rows are written while the run is still reading — every 200 companies, or after a minute when fewer are waiting — so a run that is aborted or reaches its time limit keeps what it has written and its last progress line (Delivered … so far; still reading.); every row used to be written at the very end, and such a run delivered nothing. It still ends without a closing message. A run with a maximum charge stops reading at the number of companies that charge covers; it used to read the whole search, and every company's public-register record, before writing a fraction. A list of IČO numbers is looked up only as far as the charge covers, and the numbers left are in the run'sNOT_DELIVEREDrecord. (Measured on the previous test build: a progress line after every 200 rows; a run cut off by a time limit of 90 seconds kept its 400 rows — charged — and its progress line; 120 numbers at a maximum charge of $0.06 ended after 19 lookups, with 101 numbers inNOT_DELIVERED. The write after a minute and an abort were run against a simulated register only.) - A run that is started again writes and charges no row twice. Apify can move a running Actor to another server, and a run can be resurrected: it then starts from the top with the same input, dataset and charges. Now that rows are written while the run reads, such a start would write the rows of the earlier one a second time and charge them again. So every start first reads which rows its dataset already holds (by IČO; by name and address for the few entities without one), reads ARES again — a list of IČO numbers only for the numbers without a row — and writes just what is missing. The rows already there count as delivered:
maxResults, the maximum charge, the closing message,OUTPUTandNOT_DELIVEREDare those of the whole run, and the log says that the run was started again and with how many rows. When the dataset already holds everything the run may deliver, the new start reads nothing and its message is shorter (for a list,NOT_DELIVEREDthen holds every number without a row). (Measured on the platform on this build, 2026-10-09: a sector search of 1,200 companies with directors, restarted at 400 rows, ended with 1,200 rows, none twice, 1,200 charged; the same search under a maximum charge covering 619 rows, restarted at 400, ended with 619, none twice; three finished runs resurrected kept their 19, 10 and 219 rows and charged no row again. Before that, 36 runs against a simulated register and five with the real Apify SDK and a local dataset ended the same way.) - Smaller corrections.
addressQueryignores accents as well as case. An error ARES answers part-way through a search is reported as an error, in ARES's words (the released build set no status message at all). When a budget ends a search that had no legal form, the status message names the legal forms it did not read. The run'sOUTPUTrecord says why the run stopped (stopped— alsomaxResultsfor a list that was cut at it) and how many companies it read and did not write (notWritten);OVER_LIMITnames the smaller searches left unasked (notAsked, the first 300;slicesNotAskedcounts them all) and those answered with an error (errors). An HTTP 404 from ARES's search address is a request without an answer — tried three times, then the run fails — where the run used to end as an empty result. An IČO lookup ARES answers with an error other than "not found" or "wrong input" is reported as unanswered (NO_ANSWER), not as a number ARES does not know. (The last two were run against a simulated register only; no measured run met such an answer.) - The README's examples did not match this Actor. They used input keys it does not have (
queries,maxResultsPerQuery, with a literalundefinedvalue) and the input table listed phantom fields (maxConcurrency,includeRaw). Every example now uses the real input and was run on the platform during the measurements of 2026-10-08, on test builds of this version; the output table says how often each field was filled in measured runs. - The Python example works with the current Apify client. It read the results with
run['defaultDatasetId']; withapify-client3 for Pythoncall()returns a run object and that line raisedTypeError: 'Run' object is not subscriptableafter the run had finished. It now readsrun.default_dataset_id; with client version 1 or 2, keeprun['defaultDatasetId']. - No pricing change. Output changes:
citizenshipremoved;addressCountry,inLiquidation,insolvencyRecord,endDateadded;directorsandsupervisoryBoardcan benull;legalFormhas a label for twelve more codes and a corrected one for 141, 145 and 751;scrapedAtis the moment the entity's record was read from ARES (it was the moment the row was built);capital.currencyisEURwhere it wasEURA, andCZK,EURornullwhere it wasTEXT;capital.amountis read from free text and from amounts with a decimal comma, where it wasnull. Behaviour changes for inputs that already exist: a NACE search returns more companies (the whole branch); a search over the limit returns rows;onlyActiveremoves companies;isActiveisfalsefor an entity the register of persons no longer lists as active, or that has an end date; in a searchmaxResultscounts the companies left afteronlyActiveandaddressQuery(the search was cut before the filters); a list of IČO numbers longer thanmaxResultsis cut to its firstmaxResultsnumbers before the lookups, and the numbers beyond are named (the whole list was looked up, filtered and then cut, without a word); an IČO given twice is returned once; a NACE code outside the classification, or with no digit, reads nothing;addressQueryalso keeps addresses that differ from the text only in accents; a run that is aborted or reaches its time limit keeps the rows it had written, and they are charged — it used to deliver none; withincludeDirectors, a run stops when the public register stops answering and fails when it returns no record for any company — it used to deliver every row without directors; a run withincludeDirectorstakes about twice as long, and a list of IČO numbers takes longer too (its requests are spaced now).
0.1 — 2026-09-07
- The README was regenerated from a template shared by many Actors; the entry of that day read "Enabled AI-agent payments (x402) + rebuilt the README to the full standard". The label is the generator's: the builds of that day were numbered like the others of this Actor. That README is the one the entry above corrects — its examples and parts of its text did not describe this Actor.
0.1.2 — 2026-07-28
directors[]/supervisoryBoard[]return the entries in force. The earlier filter relied on end dates that ARES leaves blank on most historical rows, so departed officers were listed as current. The Actor now drops every entry the register has struck out.- Appointments without a start date are no longer discarded; they appear with
from: null. - New
directorsCount/supervisoryBoardCount(different people, not rows) anddirectorsTruncated/supervisoryBoardTruncated(the 30-entry cap reports when it bites).
0.1.1 — 2026-07-28
- "Include directors & capital" is ticked in the Console form, so the pre-filled run on Škoda Auto and ČEZ returns the statutory body, the supervisory board and the registered capital. The API default is unchanged (
false).
0.0
- Initial release, 2026-07-09 (the Actor's first changelog called it 0.1): Czech companies from the ARES registry — IČO, tax ID (DIČ), legal form, NACE codes, registered address and founding date, with opt-in statutory body, supervisory board and registered capital.