orakel
Docs navigation

Canonical

Danmarks Statistik (Denmark)

Danish public statistics — six metric blocks (population, wages, enterprise counts, household income, 4-yr survival, ICT specialists) surfaced via ?include=context for DK companies.

Updated 2026-04-27

Source: Danmarks Statistik (Statistics Denmark) — StatBank API Data: Aggregate municipality + industry statistics, the DK twin of SSB for Norway License: Free public-sector data; attribution to "Danmarks Statistik" required when redistributed Link: https://api.statbank.dk (data API), https://www.statbank.dk (web) Update cadence: dst cron runs monthly on the 2nd at 06:00 UTC (one day after ssb); HTTP trigger POST /api/sync/dst for manual re-syncs.

What it is

Danmarks Statistik is Denmark's national statistics office. The StatBank API (api.statbank.dk/v1) exposes their full public-data catalog as REST endpoints — no auth, no documented rate limit. Orakel uses it to populate the same ssb_municipality_stats and ssb_industry_stats tables that hold Norwegian SSB rows, scoped via the country column. The naming is a historical SSB-first artifact; the schema is country-agnostic.

DST predates JSON-stat 2.0 — only v1 ({"dataset": ...}) is supported, which our parser doesn't speak. We use the BULK CSV format instead with valuePresentation=Code so dimension columns return registry codes (A, 101, 2024) rather than Danish labels (Landbrug, skovbrug og fiskeri, København, 2024). Code-form is required for clean joins to our other tables.

Tables ingested

Metric DST table Mirrors SSB Notes
Population by municipality FOLK1A 07459 Quarterly publication; we keep the latest TID per municipality. 3-digit DK kommune codes.
Average monthly wage by NACE section LONS40 11419 Annual; latest published lags ~9 months behind year-end (2024 live as of 2026-04). DKK / month, standardized.
Enterprise count by NACE section GF13 14000 Annual ("Generel firmastatistik"); active firms (ENHED=AFI), all sizes (FIRMSTR=TOT). NACE letter sections directly via BRANCHEDB0738. Latest 2023.
Median household income by municipality IFOR32 12558 Annual; OECD-equivalised disposable income, decile-5 row (DECILGEN=5DC) as the median proxy. DKK / year. Latest 2023.
4-year enterprise survival by NACE section DEMO16 13759 (5-yr) Sliding 5-year cohort window — current max age = 4 years (cohort 2019 → observed 2023). Stored under metric fourYrSurvivalRate to avoid implying 5-year parity.
ICT-specialist employment by NACE section ITAV3 10965 EU-Eurostat ICT survey; topic EMNER=3210 ("Beskæftiger it-specialister"). Coverage limited to private-sector 10+ employee firms; sections A, B, K, O-S out of scope. Suppressed years skipped.

Schema already supports all six metrics via the country column on ssb_municipality_stats and ssb_industry_stats; no further DB changes are needed.

How LONS40 maps to NACE sections

LONS40's BRANCHE07 dimension exposes the DB07 industry classification, which carries NACE letter sections (A–S) directly as dimension codes. No division-to-section mapping is required, unlike SSB table 11419 which uses range codes (01-03, 05-09, ...) that we have to map manually. Orakel queries the 19 letter codes A–S, skipping the numbered tier-1 aggregates (1, 2, ..., 10) and the grand total (TOT).

We pin all other dimensions to their broadest aggregation:

  • SEKTOR=1000 — "Sektorer i alt" (all sectors, public + private)
  • AFLOEN=TIFA — "Time- og fastlønnede i alt" (hourly + salaried combined)
  • LONGRP=LTOT — "Lønmodtagergrupper i alt" (all employee groups)
  • LØNMÅL=MDRSNIT — "STANDARDBEREGNET MÅNEDSFORTJENESTE" (standardized monthly earnings)
  • KØN=MOK — "Mænd og kvinder i alt" (both sexes)

This produces a single representative monthly wage figure per NACE section, in DKK. SSB rows for NO are stored in NOK; cross-country comparisons must currency-convert at read time.

How GF13 maps to NACE sections

GF13's BRANCHEDB0738 exposes NACE letter sections (A–S) directly — same shape as LONS40. We pin ENHED=AFI (count of firms) and FIRMSTR=TOT (all size bands) and skip the TOT and X (Uoplyst) aggregates.

How DEMO16 maps to NACE sections

DEMO16's BRANCHEDB0710 uses the DB07 10-group classification, not letter sections. Each numbered group (1..10) covers between 1 and 4 NACE sections — see lib/dst/db07-groups.ts for the mapping. We project each group's value to all of its constituent sections, so e.g. group 4 (Handel og transport mv.) yields the same survival rate for sections G, H, and I. This is honest about resolution: DST does not publish section-level survival.

How IFOR32 maps to municipalities

IFOR32 uses KOMMUNEDK for the region dimension — 99 entries: 000 ("Hele landet") for the country aggregate plus 98 three-digit kommune codes. We skip 000 and emit one row per municipality. The metric stored is decile-5 OECD-equivalised disposable income, which is the median by definition.

How ITAV3 maps to NACE sections

ITAV3's BRANCHEREV2 reports six coarse industry aggregates rather than every NACE section:

  • ITAC (10-39 industri mv.) → C, D, E
  • ITAF (41-43 bygge og anlæg) → F
  • ITAGHI (45-56 handel/transport mv.) → G, H, I
  • ITAJ (58-63 information og kommunikation) → J
  • ITALMN / ITALMN2 (Erhvervsservice, pre-/post-2020 split) → L, M, N

Sections A, B, K, O, P, Q, R, S are NOT in the ITAV3 universe — the EU-Eurostat ICT survey targets only private-sector enterprises with 10+ employees, so agriculture, mining, finance, and public-sector industries are excluded. ITAV3 also has known gap years where individual aggregates return suppressed (..); the sync orchestrator falls back to the most recent year with data.

Endpoints that surface this data

  • GET /api/companies/:orgNumber?country=DK&include=context — DK company response embeds the full context block: context.municipality (population, medianHouseholdIncome) and context.industry (avgMonthlyWage in DKK, enterpriseCount, fourYrSurvivalRate, digitalMaturityIndex). The fiveYrSurvivalRate field is null for DK rows — DST publishes a 4-year cohort window, not 5-year.
  • GET /api/companies?country=DK&include=context — same context block on every list row, batch-loaded.
  • MCP get_market_context — wraps the single-company path for agent workflows. Returns DKK wages for DK companies, NOK wages for NO.

Verbatim attribution credit

When redistributing DST data, include the credit string from content/docs/attribution.md:

Contains data from CVR / Erhvervsstyrelsen (Danish Business Authority) and Danmarks Statistik (Statistics Denmark).

Limitations

  • Quarterly population, latest snapshot only. Population history isn't tracked — a re-sync overwrites the previous value with the latest TID. If you need historical population trend, query DST directly for that table's full TID range.
  • Annual tables lag 9-12 months. LONS40 (wages) lags ~9 months, GF13 (enterprises) lags ~12 months, IFOR32 (income) lags ~12 months. Year-fallback ladders in lib/dst/sync.ts automatically descend to the most recent published year.
  • DK survival is 4-year, not 5-year. DEMO16 publishes a sliding 5-year window of cohorts, so the maximum observable cohort age is 4. NO (SSB 13759) publishes 5-year survival. The context.industry.fourYrSurvivalRate field is populated for DK rows; fiveYrSurvivalRate is populated for NO rows. Cross-country comparison requires choosing a common age — neither field is null-filled for the other country.
  • DK survival is 10-group, not letter-section. DEMO16's BRANCHEDB0710 only resolves to 10 industry groups; we project each group's value to all of its NACE sections. Section H and section I will show the same value (both are in group 4 "Handel og transport mv.").
  • DK ICT excludes agriculture, finance, and public sector. ITAV3 covers only private-sector market industries with 10+ employees. digitalMaturityIndex is null for sections A, B, K, O, P, Q, R, S on DK rows.
  • DK enterprise count uses NACE letters; NO uses range codes. Both extractors emit one row per NACE section, so consumers don't need to know — but the sourceTable field tells you which DST/SSB table the row came from.
  • No FI/SE statistics yet. Only NO (SSB) and DK (DST) populate the context block. FI's Tilastokeskus and SE's SCB are unintegrated — include=context returns null for those countries.
  • Wages are DKK; SSB wages are NOK. Cross-country wage comparisons must currency-convert at read time. Orakel does not auto-convert — the source currency is implicit in the company's country.
  • Some dimension codes contain Danish characters (KØN, LØNMÅL). Build URL params with URLSearchParams so they URL-encode correctly — manual concat will break.

Implementation references