Denmark New Companies - CVR New Registrations & Leads
Pricing
$0.90 / 1,000 per company row returneds
Denmark New Companies - CVR New Registrations & Leads
From $0.90 per 1,000 companies, no start fee. Newly registered Danish companies from the official CVR register, any date window: CVR number, name, start date, address, industry code, email, phone - plus the reklamebeskyttelse advertising-protection flag, so you can drop rows you may not market to.
Pricing
$0.90 / 1,000 per company row returneds
Rating
0.0
(0)
Developer
Scrapers Delight
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Denmark New Companies — CVR New Registrations & Leads
Every company registered in Denmark in a date window you choose, straight from CVR (Det Centrale Virksomhedsregister), the official business register run by Erhvervsstyrelsen. Name, CVR number, registration date, legal form, status, full address, six-digit industry code, email, phone — and the reklamebeskyttelse advertising-protection flag, which decides whether you are allowed to market to the row at all.
$0.90 per 1,000 companies. No run-start fee. Rows your filters remove are never delivered and never charged.
What the data actually looks like
Counted on a complete two-week census of every new Danish company registered 2026-09-01 to
2026-09-14 — 2,544 distinct companies, not a sample — and re-confirmed on a live full-month run
of August 2026 (5,570 companies). Empty string, null and literal "N/A" all count as not
filled.
| field | fill, 2-week census (n=2,544) | fill, August 2026 (n=5,570) |
|---|---|---|
cvr, companyName, startDate | 100% | 100% |
postalCode, city, fullAddress | 100% | 100% |
companyForm, status, unitNumber | 100% | 100% |
industryCode + industryText | 100% | 100% |
streetAddress | 100% | 99.87% |
advertisingProtected | 100% (a real boolean on every row) | 100% |
email | 57.78% | 54.99% |
phone | 46.38% | 47.63% |
| email or phone | 67.73% | 67.58% |
careOfName | 37.46% | 37.06% |
ceasedDate | 1.10% | 2.05% |
streetAddress is null on 7 of the 5,570 August rows. They are Greenlandic addresses that publish
only a postcode and a town — there is no street to parse, so the field is null rather than
fabricated. fixtures/region_greenland_2026-08.json holds them.
Read this before you buy: the contact numbers above are an average of two very different things
Contact fill is almost entirely determined by company form. Counted on the 2026-09-08..14 week:
| company form | share of new companies | phone | advertising-protected | marketable | |
|---|---|---|---|---|---|
| Anpartsselskab (ApS, private limited) | 472 of 1,015 | 12.3% | 28.4% | 78.4% | 0.6% |
| Aktieselskab (A/S, public limited) | 10 | 10.0% | 10.0% | 80.0% | 0.0% |
| Enkeltmandsvirksomhed (sole trader) | 270 | 92.6% | 54.4% | 78.1% | 21.5% |
| Personligt ejet Mindre Virksomhed | 135 | 90.4% | 58.5% | 73.3% | 23.0% |
| Frivillig forening (association) | 89 | 96.6% | 62.9% | 69.7% | 30.3% |
| Interessentskab (I/S) | 21 | 95.2% | 90.5% | 66.7% | 33.3% |
So: if you filter to limited companies (ApS / A/S) you get ~12% email and almost no marketable rows. A verified live run over all of August, filtered to unprotected ApS and A/S with a contact requirement, delivered 43 rows out of 5,570 registrations. That is the honest shape of this lane. If your buyer is "any newly registered Danish business", the numbers in the first table apply; if your buyer is specifically "new limited companies with an email", this source cannot give you volume, and no amount of engineering changes that — CVR simply does not publish one.
Advertising protection is the thing that matters, and it is not a minority
77.48% of new Danish companies carry reklamebeskyttelse — a registration under the Danish
CVR act asking that their register entry not be used for unsolicited marketing.
It is a legal marker, not data suppression. Protected companies publish an email at essentially the same rate as unprotected ones (54.04% vs 52.54% on the measured week), so a raw export looks like a perfectly good lead list and mostly is not one. Counted:
- 2,544 new companies over two weeks
- 1,971 (77.48%) advertising-protected
- 573 (22.52%) not protected
- of those 573, 331 publish an email or a phone
- → 13.01% of all new Danish companies are both lawfully marketable and reachable — roughly 26 a day, about 9,500 a year
Set Advertising-protected companies → Exclude and the register itself filters them out: they
are never fetched, never delivered and never charged. That filter was verified exact — on
2026-09-01 it returned 147 rows against a day total of 681, and exactly 147 of those 681 rows
carry reklameBeskyttet: false.
How much data is there
Measured from the register's own counts on 2026-09-16:
| window | new companies |
|---|---|
| a weekday | 142 – 226 |
| a weekend day | 43 – 54 |
| the 1st of a month | 661 – 681 |
| 1 January 2026 | 1,716 |
| one week | 1,015 – 1,600 |
| August 2026 | 5,570 |
| 2026 year to date (to 16 Sept) | 50,943 |
The whole register holds 2,269,054 companies; this Actor is scoped to new registrations in a date window, which is the part with a buyer.
The two traps this Actor exists to survive
1. A single query silently returns at most 3,000 rows
Ask the gateway for August 2026 and it answers HTTP 200, an envelope reading total: 5570,
and exactly 3,000 rows. No error, no flag, no short-page signal. 2,570 companies are simply
not there. Pinned to the exact row (fixtures/cap_month_offset*.json):
offset 0 -> 1 row, total 5570offset 2999 -> 1 row, total 5570offset 3000 -> 0 rows, total 0 <- HTTP 200; past the ceiling even `total` lies
This Actor slices the window until every query sits under the ceiling, fetches each slice in one request, and floor-asserts the rows it got against the register's own count for that same response. Verified end to end on the exact window that breaks: August 2026 came back as 2,760 + 2,810 = 5,570 rows, 5,570 distinct CVRs, in 6 requests and 41 seconds.
If a single day ever exceeds 3,000 (the busiest measured was 1 January at 1,716), it is partitioned by company form and then by region — both verified to be exact partitions, summing to the day's own total with nothing double-counted and nothing missing.
2. Paging this gateway loses rows
The obvious escape from the ceiling is to page. It does not work. Two size=1000 pages of the same
1,015-row week, captured seconds apart, returned 1,000 + 15 = 1,015 raw rows — apparently complete —
but only 1,009 distinct CVRs. Six rows are byte-identical duplicates across the page boundary,
so by pigeonhole six other companies never came back at all. At HTTP 200, with total still reading
1,015.
This Actor never pages. Every slice is sized to come back whole in one request.
And a third: the order the register returns rows in is not random
The gateway returns company-registry entities (ApS, A/S, branches) first and personally-owned ones (sole traders, associations) after. Because contact fill differs so sharply between those groups, "the first N rows" is a systematically contact-poor sample — measured on the 1,015-row week, rows 0-250 carry 16.8% email against the week's own 53.69%. A local run capped at 50 rows delivered 3 emails where the week's rate predicts 27.
So every slice is sorted by registration date, then CVR, before the cap is applied. A capped run is a chronological prefix of your window, not an arbitrary stratum — and two runs of the same window return rows in the same order, so a diff between them means something. After the fix the same 50-row run delivered 35 contactable rows.
Access: this Actor requires the Apify UNBLOCKER proxy group
datacvr.virk.dk sits behind a Cloudflare managed challenge. Measured 2026-09-16, every one of
these got HTTP 403 with zero cookies ever issued:
- plain HTTP with a real Chrome user agent
- Playwright Chromium, headed, three navigations
- a real installed Chrome on a persistent profile, headed, 3 × 75 s of waiting
- Apify RESIDENTIAL, two distinct genuine Danish IPs
- Apify datacenter IPs
Apify Proxy with groups=UNBLOCKER returns HTTP 200 and issues the session cookie. That is the
only route found, and the input schema pins it as the default. Good news for cost: a plain HTTP
client works through it — no browser is needed — so this Actor runs on the small Node image at
512 MB rather than a 4 GB Chromium one.
UNBLOCKER usage is billed to your Apify account separately from this Actor's per-row price. A full month of 5,570 companies cost 6 requests and 3.43 MB.
robots.txt at datacvr.virk.dk declares Crawl-delay: 10 and does not disallow /gateway or
/soegeresultater. This Actor runs at most 4 requests in flight; ten back-to-back calls with no
delay at all returned 200 every time, with no throttling observed, but the crawl-delay is the site's
stated preference and heavy use should respect it.
Fields
| field | notes |
|---|---|
cvr | the 8-digit CVR number, the Danish company identifier |
companyName | current registered name |
startDate | official registration date, ISO |
startDateInRequestedWindow | see below — the date filter is not perfectly exact |
companyForm | legal form, verbatim Danish (Anpartsselskab, Enkeltmandsvirksomhed, …) |
status | verbatim from the register — see the caveat below |
ceasedDate, isCeased | set for companies already closed again; 1-2% of a new-company window |
careOfName | the c/o line, when there is one |
streetAddress, postalCode, city | parsed out of the register's single multi-line address string |
fullAddress | the whole address on ONE line, commas not newlines, so CSV/XLSX stay one row per company |
addressLineCount | how many lines the source address had (2, 3 or 4) |
industryCode, industryText | six-digit Danish DB07/NACE code and its Danish description |
email, phone, hasContact | exactly what the company filed; verbatim, never normalised |
advertisingProtected | true = reklamebeskyttelse registered. Never guessed: a missing flag stays null |
marketableLead | advertisingProtected === false && hasContact |
unitNumber | the register's internal enhedsnummer |
cvrUrl | link to the company's page on datacvr.virk.dk |
scrapedAt | run timestamp, ISO |
Fields that are NOT here, and why
- There is no website field. The source does not publish one anywhere, and there is no way to derive it honestly. It is not offered.
- No extra contact data from the company detail page. The obvious enrichment — fetch
/gateway/virksomhed/hentVirksomhedper company — was tested on 42 companies (30 + 12). Itsstamdataobject has noemailand notelefonkey at all: 0/30 and 0/12, including for companies whose search row carried both. Contact data lives only in the search row. That is also why this Actor is cheap: one request returns up to 3,000 complete lead rows with no per-company follow-up. reg(null on all 2,544 rows),harPseudoCvr(false on all), the threehighlight*search-UI flags andvisNavnPostfixare dropped — they are empty or constant, not data.
Two honest caveats about individual fields
status mixes two vocabularies inside a single response. One 1,015-row payload contained 492
rows reading NORMAL and 514 reading Aktiv, both meaning an active company, plus Ophørt,
UDENRETSVIRKNING and OPLØSTEFTERSPALTNING. It is passed through verbatim rather than
normalised into a guess. For "is this company still alive", use isCeased / ceasedDate: on the
measured week ophoersDato was filled for exactly the 8 rows whose status read Ophørt.
The date filter is not perfectly exact. Querying 2026-01-02 returned 253 rows, 3 of which carry
a startDato in a different month (June, August and April 2026). It is rare — zero exceptions on
the September week, 2 of 5,570 across August — but it is real, so every row carries
startDateInRequestedWindow and RUN_SUMMARY counts them. Filter on it if you need a strict feed.
Input
Everything is optional. With an empty input the Actor returns the last 7 days, capped at 1,000 rows.
- Last N days — a rolling window counted back from today in Denmark, including today. This is the setting for a scheduled daily or weekly feed: nothing to edit. Fill it in and it wins; clear it to use exact dates.
- Registered from / to — exact ISO dates, inclusive. Any length of window: the Actor slices it.
- Advertising-protected companies —
include(default, every row flagged) /exclude(marketing-safe rows only, filtered by the register itself) /only. - Only companies with… — any / email or phone / email / phone.
- Company form, Region, Municipality, Industry code, Company status — all optional, all validated against the register's own live vocabulary before the run starts.
- Maximum companies — default 1,000. 0 means no cap.
- Proxy — leave on Apify Proxy + UNBLOCKER.
Why the filters are validated before the run
Because on this gateway a wrong filter value does not produce an error:
| mistake | what the gateway does |
|---|---|
virksomhedsform: ["Aktieselskab"] (the name, not the kode) | HTTP 200, 0 rows |
kommune: ["København"] (the name, not the kode) | HTTP 200, the UNFILTERED result — the filter silently vanishes and you are charged for rows you asked to exclude |
branchekode: "6421" (a prefix of a 6-digit code) | HTTP 200, 0 rows — a prefix is not treated as a prefix |
virksomhedsstatus: ["NORMAL"] (a value rows actually contain) | HTTP 200, 0 rows |
dates as 01/09/2026 | HTTP 200, 0 rows |
Every one of those is byte-for-byte identical to a genuine "nothing was registered". The Actor refuses them up front with a message naming the valid values, and nothing is charged.
Output: RUN_SUMMARY
Written to the key-value store on every run. It reconciles the register's own count for each slice against the rows actually read and delivered, reports contact fill counted on that run, and keeps three kinds of nothing apart, because merging them is how a blocked run gets mistaken for a quiet week:
emptySlices— dates the register itself says hold no registrations. A real answer.excluded— rows your filters removed. Fetched, never delivered, never charged.unreachableSlices— slices that could not be read. The companies in them are missing. If a quarter or more of the planned slices land here, the run fails rather than reporting a short dataset as complete.
delivered always equals charged.
Billing
Pay per event, one event: company-scraped, $0.0009 per company row delivered.
- No run-start fee. A run that matches nothing costs nothing.
- Excluding advertising-protected companies is applied by the register, so those rows are never fetched and never charged.
- A contact requirement drops rows before delivery, so they are never charged.
- Rows are pushed with the charge event attached, so what is delivered is exactly what is billed and your own charge cap is respected row by row.
Measured cost to run: a 7-day, 669-row window is 1 request and 11 seconds; all of August — 5,570 companies — is 6 requests, 3.43 MB and 41 seconds at 512 MB.
Source and licence
Det Centrale Virksomhedsregister (CVR), Erhvervsstyrelsen, via
https://datacvr.virk.dk/gateway/soeg/fritekst. CVR is public data published by the Danish
Business Authority. Advertising protection is a legal restriction on how a row may be used, not a
restriction on access — which is exactly why it ships as a first-class field with a filter rather
than being quietly dropped. If you are marketing into Denmark, filter on it.
A cleaner long-term route exists and is not used here: Erhvervsstyrelsen's official CVR
distribution API at distribution.virk.dk/cvr-permanent/_search sits behind plain HTTP Basic auth
with no Cloudflare in front of it, and credentials are issued free on application. Moving to it
would remove the UNBLOCKER dependency entirely.
Validate the parser against the captured bytes with node offline_validate.mjs — 249 assertions,
no network, no node_modules.