DEV Community

Devil Scrapes
Devil Scrapes

Posted on

Norway's official company register hard-stops at 10,000 results

Quick answer

Norway's official company register, Enhetsregisteret, is free, keyless, open government data — and it will not page past 10,000 results for a single query, no matter how you set the cursor. It also refuses to run at all with no filter applied. Neither is a bug in the API; both are deliberate, and a KYC pipeline built against this register needs to know both before it, not after a run silently stops at record 10,000 of a list that actually has 40,000.

Will Enhetsregisteret let me page through every company in Norway? 📖

No — not in one query. The register's paged endpoint refuses to serve results once page × size crosses 10,000, regardless of how many companies actually match your filter:

PAGE_SIZE = 100
# The register's paged endpoint refuses `page * size` beyond 10,000.
RECORD_CEILING = 10000
Enter fullscreen mode Exit fullscreen mode

This matters because the failure is quiet in the way that matters most for a compliance workflow: it isn't a 4xx, it isn't a documented error message about a ceiling — the API simply won't return record 10,001 through whatever path the cursor would take you. The Norway Company Registry Scraper treats this as a hard stop, not a silent one: it logs a warning naming the exact ceiling and tells you to narrow the filter, rather than returning a truncated dataset that looks complete.

The practical fix is the one the register itself pushes you toward: narrow by industry code, by municipality, or by both, so no single query's result set gets anywhere near 10,000. A national sweep of "software consultancies in Norway" is one query; "software consultancies in Oslo," "in Bergen," "in Trondheim" run separately is three queries that each stay well inside the ceiling and, combined, cover the same ground the single query couldn't.

Can I just ask for every registered company with no filter? 🔍

No — and this one is enforced before a single request goes out. Enhetsregisteret holds every organization registered in Norway; a completely unfiltered query against that is not a request the register is built to serve, and this Actor refuses to send one:

if not cfg.has_filter():
    raise ValueError(
        "Provide a company name, an industry code or a municipality — "
        "the register will not return an unfiltered dump."
    )
Enter fullscreen mode Exit fullscreen mode

That validation runs before any network call and before any charge — the run fails fast on a request shape that would never have produced a usable result, rather than burning a page of API calls to discover the same thing three hops in.

Why does the field data need translating instead of just renaming? 🧭

Because the structure, not just the vocabulary, is Norwegian. A raw register entry nests the fields you actually want three objects deep — legal form under organisasjonsform, industry classification under naeringskode1, and the business address under forretningsadresse, itself an object with an adresse array of street lines plus separate postnummer/poststed/kommune fields for postal code, city, and municipality:

def _address(block):
    """(street, postal_code, city, municipality) from a Norwegian address block."""
    lines = [line for line in (block.get("adresse") or []) if line]
    return (
        ", ".join(lines) or None,
        block.get("postnummer"),
        block.get("poststed"),
        block.get("kommune"),
    )
Enter fullscreen mode Exit fullscreen mode

Flattening that into one row with English field names is most of the actual engineering work here. The register answers roughly forty raw fields per company; the useful subset for a prospect list or a KYC check is closer to a dozen, and getting there means walking three nested Norwegian-keyed objects for every single company, every single run — correctly, every time, across whatever shape a given legal form or industry code happens to produce.

One field worth flagging on its own: antallAnsatte (employee count) is self-reported to the register by the company, not verified or audited by anyone. It's frequently absent, and an absent value here means "not reported," never "zero employees" — treating a missing employee count as zero would misclassify a real, active company as apparently defunct.

The part that generalizes 🧭

A quiet ceiling is more dangerous than a documented one. An API that returns total: 50000 in its metadata while refusing to actually serve anything past record 10,000 will make an unnarrowed sweep look complete when it captured a fifth of the real dataset. The only defenses are reading the docs closely enough to find the ceiling before you hit it, and failing loud with the exact number when you do — not letting the run finish "successfully" with a quietly partial result.

Refusing a bad request before paying for it beats discovering the same thing three pages in. An unfiltered query against a national register was never going to return something you could use; validating that up front, before any request or charge, is cheaper for the customer than billing for a warm-up fee against a query that couldn't have worked.

What the Actor gives you

One row per company, flattened out of Enhetsregisteret's nested Norwegian schema:

  • org number, legal name, legal form (code and full description), primary industry code and description
  • employee count, website, and the full flattened business address — street, postal code, city, municipality
  • founding date, VAT-registration status, bankruptcy and under-liquidation flags
  • optional bankruptcy/liquidation exclusion, so a prospect list skips companies you'd never want to contact
  • retries on transient 429/5xx instead of failing the whole run over a single blip

The honest limitations 🚧

Register data only — no financial statements, no shareholder records, no beneficial-ownership chain. Employee counts are exactly as self-reported to the register and are absent for a meaningful share of companies. Queries are capped at the register's own 10,000-record paging ceiling; narrow by industry or municipality to sweep a larger population in multiple runs.

FAQ

Do I need an API key or login?
No. Enhetsregisteret is open Norwegian government data and needs no credentials — the work here is untangling its nested Norwegian schema into a usable row, not clearing a login wall.

Why did my run stop before reaching every company I expected?
Almost certainly the register's 10,000-record paging ceiling for that specific query. Narrow by industry code or municipality and run the segments separately.

Can I search without any filter to get a full national export?
No — the register isn't built to serve that, and the Actor refuses the request before any charge rather than returning something incomplete.

Is a missing employee count the same as zero employees?
No. It means the company didn't report one to the register; treating it as zero would misclassify an active company as defunct.

Pricing

$0.20 per run plus $0.002 per result row — about $2.20 per 1,000 results. No subscription, no minimum, no card to start.

Norway Company Registry Scraper on Apify


Built by Devil Scrapes. We handle the nested Norwegian schema, the paging ceiling, and the unfiltered queries the register was never going to serve, so you get a flat table instead of a weekend.

Top comments (0)