Skip to content

Country Coverage & Field Availability

FirmaDB indexes 36.2M+ company records across 19 European countries — but not every field is available in every country. Some registries don't publish NACE codes. Some don't publish employee counts. A few don't publish dissolution dates. Always check coverage before you build a workflow that depends on a specific field.

The 19 countries

Country Code Records Registry Notable fields
France FR 16.8M INSEE Sirene SIREN (9 digits), NACE rev. 2
United Kingdom GB 5.7M Companies House CRN (8 chars, leading zeros)
Sweden SE 1.8M Bolagsverket 10-digit organisationsnummer
Belgium BE 1.8M Crossroads Bank for Enterprises Dotted VAT (0xxx.xxx.xxx), daily diffs
Czechia CZ 1.3M ARES 8-digit IČO, NACE rev. 2 (czNace2008)
Norway NO 1.2M Brønnøysundregistrene 9-digit organisasjonsnummer
Slovakia SK 1.17M OR SR 8-digit IČO
Poland PL 928K KRS / REGON Dual identifier (KRS or 9/14-digit REGON)
Switzerland CH 783K Zefix UID (CHE-xxx.xxx.xxx)
Ireland IE 811K CRO Numeric, no leading zeros
Bulgaria BG 765K Trade Register EIK (9 digits)
Lithuania LT 539K Registrų centras 9-digit code
Cyprus CY 489K Department of Registrar of Companies HE-prefixed
Latvia LV 483K Lursoft / UR 11-digit code
Finland FI 457K PRH Y-tunnus (xxxxxxx-x)
Estonia EE 369K RIK 8-digit code
Slovenia SI 291K AJPES 7-digit matična številka
Moldova MD 281K ASP 13-digit IDNO
Serbia RS 136K APR 8-digit MB

Total: 36.2M records. Counts refresh weekly.

Check coverage at runtime

Don't hard-code these counts — they grow. Always read the live values from the coverage endpoints (which are anonymous and free to call).

List all countries

curl https://api.firmadb.com/v1/countries
import httpx
countries = httpx.get("https://api.firmadb.com/v1/countries").json()["countries"]
for c in countries:
    print(c["code"], c["record_count"], c["freshness_class"])
const { countries } = await fetch(
  "https://api.firmadb.com/v1/countries"
).then(r => r.json());

for (const c of countries) {
  console.log(c.code, c.record_count, c.freshness_class);
}

Inspect one country in detail

GET /v1/countries/{code} returns the full capability manifest: per-field availability percentages, supported filters, registry URLs, refresh cadence, the regex used to validate registry_id, and any known limitations.

curl https://api.firmadb.com/v1/countries/FR
{
  "code": "FR",
  "name": "France",
  "record_count": 16834219,
  "registry": {
    "name": "INSEE Sirene",
    "url": "https://www.sirene.fr/",
    "license": "Open Licence 2.0"
  },
  "registry_id_format": {
    "pattern": "^[0-9]{9}$",
    "example": "552120222",
    "label": "SIREN"
  },
  "field_coverage": {
    "name": 1.00,
    "status": 1.00,
    "address": 0.99,
    "nace_code": 0.97,
    "employee_count": 0.42,
    "website": 0.18
  },
  "supported_filters": ["q", "country", "nace", "status"],
  "refresh_cadence": "weekly",
  "last_loaded_at": "2026-05-04T03:14:22Z"
}

Field availability matrix

A condensed view of what's reliably populated across the largest countries. Percentages are approximate; call /v1/countries/{code} for current values.

Field FR GB SE BE CZ NO PL IE
name 100% 100% 100% 100% 100% 100% 100% 100%
status 100% 100% 100% 100% 100% 100% 100% 100%
address 99% 99% 100% 100% 99% 100% 98% 99%
nace_code 97% 99% 95% 96% 98% 90%
employee_count 42% 71% 65%
website 18% 12% 8%
dissolution_date 99% 100% 99% 100% 99% 100% 92% 99%

Legend: = not collected for this country, either because the registry does not publish the field or because FirmaDB has not yet ingested it.

Country-specific notes

  • France (FR). SIREN is 9 digits; SIRET is 14 (SIREN + 5-digit establishment suffix). FirmaDB indexes the legal unit (SIREN). For establishment-level data, drop the last 5 digits before lookup.
  • United Kingdom (GB). CRN is 8 characters with significant leading zeros. 00445790 is not the same as 445790.
  • Belgium (BE). Identifier format is dotted VAT (0403.227.515). Pass the dots — stripping them returns 400 invalid_registry_id.
  • Sweden (SE). Organisationsnummer is 10 digits, no separator. Don't confuse with personnummer (also 10 digits) — only company numbers are indexed.
  • Norway (NO). Organisasjonsnummer is 9 digits. Clean format, no leading zeros.
  • Czechia (CZ). NACE classification is exposed as nace_code in the response, but the source field at the registry is czNace2008. Validation regex: ^[0-9]{8}$ with leading zeros.
  • Poland (PL). Two identifier systems coexist (KRS and REGON). registry_id accepts either; FirmaDB stores both internally.
  • Switzerland (CH). UID format CHE-xxx.xxx.xxx. The CHE- prefix and dots are required.
  • Finland (FI). Y-tunnus has a check digit separated by a hyphen: 1234567-8.

Field meta — explain why a field is empty

When you request ?include=field_meta, every field carries a state explaining its presence (or absence):

"field_meta": {
  "employee_count": {
    "state": "not_published_by_registry",
    "country": "BG",
    "source_url": null
  },
  "nace_code": {
    "state": "available",
    "source_url": "https://annuaire-entreprises.data.gouv.fr/etablissement/55212022200016",
    "confidence": "registry"
  }
}

State enum:

State Meaning
available Value present, sourced from registry
unknown Country collects this field, but this record has no value
not_published_by_registry The registry doesn't publish this field at all
not_collected FirmaDB hasn't ingested this field for this country yet
stale Value exists but is older than the freshness threshold

This is the difference between "no data" (registry gap) and "no coverage" (FirmaDB gap). Surface the right message to your users.

Suppressing nulls

By default, fields without values are returned as null. To slim the response, pass include_nulls=false:

curl "https://api.firmadb.com/v1/companies/BG/123456789?include_nulls=false" \
  -H "Authorization: Bearer $FIRMADB_API_KEY"

When combined with ?include=field_meta, you get a compact response plus a per-field explanation of every omitted field. This is the recommended pattern for agent integrations.

What's next