DEV Community

Devil Scrapes
Devil Scrapes

Posted on

The Czech company register hands you an ID that is not an ID

Quick answer

The Czech ARES company register returns two different identifier fields on search results, and only one of them is a real IČO. ico is the eight-digit Czech company number you can look up. icoId is ARES's own internal record id — and for some entities it is not a number at all but a synthetic string like ARES_00363445, while ico on that same record is null. If you treat icoId as an IČO and feed it back to the detail endpoint, you get a 404 for a company that demonstrably exists. Any integration that joins search results to detail records by identifier has to handle the null-ico case explicitly, because ARES will hand you a real, named, operating company with no usable company number attached.

Does every ARES search result have an IČO? 🔍

No — and the exception is not rare enough to ignore. Search the register for Asseco and ARES reports six matches. Here is what the identifier fields actually look like across the first five:

ico=None         icoId=ARES_00363445   Asseco CE Cloud, a.s.
ico=19352212     icoId=19352212        Asseco CE Cloud, a.s., odštěpný závod
ico=27074358     icoId=27074358        Asseco Central Europe, a.s.
ico=27123707     icoId=27123707        Asseco Central Europe,a.s., organizační složka
ico=29162670     icoId=29162670        Asseco CEIT CZ, s.r.o.
Enter fullscreen mode Exit fullscreen mode

Four of the five agree with themselves: ico and icoId hold the same eight digits, and either field works. The first one does not. Asseco CE Cloud, a.s. is a named entity that ARES is happy to return from a search, but it carries no plain IČO — only the internal ARES_-prefixed handle. The obvious defensive move, "if ico is missing, fall back to icoId", is exactly the wrong one here: it produces a lookup key that the detail endpoint has never heard of.

This is the kind of shape that only appears once you run a search against real names rather than a handful of known-good IČOs. Test with three company numbers you picked yourself and every record looks uniform.

What does ARES return for an IČO that does not exist?

A clean, structured 404 rather than an empty 200:

{
  "kod": "NENALEZENO",
  "popis": "Nebyl nalezen žádný subjekt, který by odpovídal zadaným hodnotám...",
  "subKod": "VYSTUP_SUBJEKT_NENALEZEN"
}
Enter fullscreen mode Exit fullscreen mode

That is a genuinely good API decision and worth building on. Because the not-found case is a typed response — kod: "NENALEZENO" — you can tell it apart from a timeout, a proxy failure, or a malformed request without guessing from an HTTP status alone. A negative existence check is a real answer to a real question: "is this IČO registered in Czechia?" deserves the answer "no", delivered as a row, not swallowed as an error.

That distinction matters more than it sounds. The most common failure mode we see across company-registry integrations is a single recoverable error taking down an entire batch: one bad identifier in a list of 500 raises, the run dies, and the 499 good lookups are lost. Not-found is the most frequent "error" in any registry workload, so treating it as data rather than as an exception removes the largest single cause of batch loss before you write any retry logic.

The Czech ARES Company Registry Scraper emits a row either way:

ico: str | None
found: bool                 # False for a registered-nowhere IČO
name: str | None
warning: str | None         # e.g. no plain IČO, only an icoId
Enter fullscreen mode Exit fullscreen mode

A found: false row still costs you a result, because it still answered your question — you now know that number is not in the Czech register, which is frequently the whole point of the lookup.

How fast can you actually pull from ARES?

The Czech Ministry of Finance documents a rate limit of 500 requests per minute on the ARES open-data interface, published at data.mf.gov.cz/api/ares.html. No API key, no registration, no IP whitelisting — it is a genuine government open-data service rather than a third-party mirror that can disappear when someone stops paying for it.

That distinction is worth checking before you build on any registry API. We shelved a Danish company-registry integration precisely because the reachable endpoint turned out to be a community wrapper rather than the authority's own system: fine for a demo, not something to put a compliance workflow on top of. ARES is the authority's own system, which is why a documented 500 req/min is a number you can plan capacity around instead of a number you discover by getting blocked.

FAQ

Is ARES free to query?
Yes. It is Czech open data, no key required. The cost of a scraper on top of it is compute and engineering, not access.

Can I search by company name instead of IČO?
Yes — ARES exposes a POST search endpoint that takes obchodniJmeno and paginates with start (offset) and pocet (page size). The Asseco search above reported pocetCelkem: 6. Just remember that name-search results are the ones that can come back without a usable IČO.

Why would a company have no IČO in the register?
The ARES_-prefixed records are ARES's own internal handles for entities that exist in its data but do not carry a standard eight-digit Czech company number in that particular view — foreign entities and certain organisational units among them. They are real records; they are just not addressable the way the rest are.

What is odštěpný závod?
A branch establishment. Czech search results routinely mix parent companies with their branches and organisational units, and each carries its own IČO. If you are deduplicating for a CRM, decide deliberately whether a branch is a separate company for your purposes — the register will not decide it for you.

The short version

Two identifier fields, one of which lies about being an identifier; a typed 404 that is more useful than most APIs' success responses; and a documented 500 req/min from the ministry itself. Handle the null-ico case, treat not-found as a row rather than an exception, and ARES is one of the more pleasant company registries in Europe to build against.

Data in this post was pulled live from ares.gov.cz on 2026-09-09.

Top comments (0)