In the 14 days to 20 October 2026, Norway registered 1,336 new limited companies (AS) and branches of foreign companies (NUF), not counting shelf and holding companies. 269 of them are in Oslo. The register behind those numbers is open and free, and this guide reads it with plain Python.
Norway registers every company in one public register, Enhetsregisteret, run by the Brønnøysund Register Centre (Brreg). Its data is open, free and served by a JSON API with no key. Every new limited company, foreign branch and partnership shows up there as soon as it is registered, with its industry code, address and, often, a website.
A list of companies registered this week is useful to anyone who sells to new businesses: accountants, banks, insurers, office suppliers, software companies. It is also a clean data set for market research. This guide pulls it with plain Python.
A first request
The enheter (entities) endpoint filters by registration date and organisation form. This asks for limited companies (AS) registered in the last 7 days:
import json
import urllib.parse
import urllib.request
from datetime import date, timedelta
params = {
"organisasjonsform": "AS",
"fraRegistreringsdatoEnhetsregisteret": (date.today() - timedelta(days=7)).isoformat(),
"tilRegistreringsdatoEnhetsregisteret": date.today().isoformat(),
"size": 20,
}
url = "https://data.brreg.no/enhetsregisteret/api/enheter?" + urllib.parse.urlencode(params)
request = urllib.request.Request(url, headers={"Accept": "application/json"})
with urllib.request.urlopen(request, timeout=60) as response:
data = json.load(response)
print(f"{data['page']['totalElements']} new AS companies in the last 7 days")
for company in data.get("_embedded", {}).get("enheter", []):
industry = company.get("naeringskode1", {}).get("beskrivelse", "no industry code yet")
city = company.get("forretningsadresse", {}).get("poststed", "")
print(company["organisasjonsnummer"], company["navn"], "|", industry, "|", city)
The results sit under _embedded.enheter, and page tells you the total count and the number of pages. On 19 October 2026 it printed lines like these:
755 new AS companies in the last 7 days
938564000 AB CONSULT AS | Annen teknisk konsulentvirksomhet | STAVANGER
938456968 ACCOUNTONME AS | Regnskapsføring og bokføring | OSLO
938676852 AFAS 011026-01 AS | Uoppgitt | NARVIK
938676860 AFAS 011026-02 AS | Uoppgitt | NARVIK
Industry descriptions are in Norwegian: "Regnskapsføring og bokføring" is accounting and bookkeeping, and "Uoppgitt" means not stated. The AFAS lines are explained under the gotchas below.
The fields you will use most
| Field | Meaning |
|---|---|
organisasjonsnummer |
The 9-digit organisation number, the company's permanent ID |
navn |
Registered name |
organisasjonsform.kode |
Organisation form: AS, ASA, NUF, ENK and so on |
registreringsdatoEnhetsregisteret |
Date it entered the register |
stiftelsesdato |
Date it was founded |
naeringskode1 |
Main industry code and description (Norway's version of NACE) |
antallAnsatte |
Number of employees registered |
forretningsadresse |
Business address: street lines, postal code, city, municipality |
hjemmeside |
Website, when the company gave one |
registrertIMvaregisteret |
Whether it is registered for VAT |
konkurs, underAvvikling
|
Bankruptcy and liquidation flags |
Organisation forms
- AS: private limited company, by far the most common form for new businesses.
- ASA: public limited company.
- NUF: Norwegian branch of a foreign company.
- ENK: sole proprietorship. These are registered under the owner's own name, so treat them as personal data. If you plan to contact them, data protection law (GDPR) applies.
Gotchas
- You cannot page past the first 10,000 results of a query. The API checks that size × (page + 1) is at most 10,000 and answers HTTP 400 otherwise. A month of all registrations can be more than that, so split long date ranges into week-long windows, as the script below does.
- New companies are often empty shells for a while. Many have no employees, website or VAT registration yet, and many start with the industry "Uoppgitt" (not stated). Filter on what your use case needs.
-
Shelf and holding companies add noise. Law firms register ready-made "shelf" companies with numbered names (like
ABCD 011026-01 AS), and many new companies are one person's holding company (industry code 64.2). If you are looking for operating businesses, drop both.
Only the new companies, on every run
This script collects new AS and NUF registrations from the last 14 days, in week-long windows, skips shelf and holding companies, and remembers which organisation numbers it has already shown:
"""Print Norwegian companies registered since the last run."""
import json
import re
import urllib.parse
import urllib.request
from collections import Counter
from datetime import date, timedelta
from pathlib import Path
API = "https://data.brreg.no/enhetsregisteret/api/enheter"
FORMS = ["AS", "NUF"]
PAGE_SIZE = 500
SEEN_FILE = Path("seen_companies.json")
SHELF_OR_HOLDING = re.compile(r"(?i)\bholding\b|^\S+ \d{6}-\d+\b")
def registered_between(form, first, last):
page = 0
while True:
params = {"organisasjonsform": form, "fraRegistreringsdatoEnhetsregisteret": first.isoformat(),
"tilRegistreringsdatoEnhetsregisteret": last.isoformat(), "size": PAGE_SIZE, "page": page}
request = urllib.request.Request(f"{API}?{urllib.parse.urlencode(params)}",
headers={"Accept": "application/json"})
with urllib.request.urlopen(request, timeout=60) as response:
data = json.load(response)
yield from data.get("_embedded", {}).get("enheter", [])
page += 1
if page >= data.get("page", {}).get("totalPages", 0) or (page + 1) * PAGE_SIZE > 10_000:
break
def weeks(days_back):
end = date.today()
start = end - timedelta(days=days_back)
while end >= start:
first = max(start, end - timedelta(days=6))
yield first, end
end = first - timedelta(days=1)
seen = set(json.loads(SEEN_FILE.read_text())) if SEEN_FILE.exists() else set()
new = []
for first, last in weeks(days_back=14):
for form in FORMS:
for company in registered_between(form, first, last):
number = company["organisasjonsnummer"]
industry = company.get("naeringskode1", {}).get("kode", "").replace(".", "")
if number in seen or SHELF_OR_HOLDING.search(company["navn"]) or industry.startswith("642"):
continue
seen.add(number)
new.append(company)
new.sort(key=lambda c: c.get("registreringsdatoEnhetsregisteret", ""), reverse=True)
for company in new:
address = company.get("forretningsadresse", {})
print(f'{company.get("registreringsdatoEnhetsregisteret")} {company["organisasjonsnummer"]} {company["navn"]}')
print(f' {company.get("naeringskode1", {}).get("beskrivelse", "no industry code yet")}, '
f'{address.get("poststed", "no address")}')
print(f"{len(new)} new companies")
top = Counter(c.get("forretningsadresse", {}).get("poststed", "no address") for c in new).most_common(8)
for city, count in top:
print(f"{count:6} {'█' * max(1, round(30 * count / top[0][1])):30} {city}")
SEEN_FILE.write_text(json.dumps(sorted(seen)))
On 20 October 2026 its output ended like this, with a chart of the towns:
2026-10-06 938582327 VJ STUNDER OY NUF
Annen teknisk konsulentvirksomhet, FI-28130 PORI
2026-10-06 938601593 ZWANNEHEIM NUF
Utleie av egen eller leid fast eiendom, 2517 JL 'S-GRAVENHAGE
1336 new companies
269 ██████████████████████████████ OSLO
36 ████ STAVANGER
31 ███ BERGEN
24 ███ TRONDHEIM
21 ██ SANDEFJORD
19 ██ KRISTIANSAND S
16 ██ HELLEVIK I FJALER
13 █ ASKER
To focus on one sector, keep only companies whose naeringskode1.kode starts with your industry's code (for example 62 for computer programming and consultancy). To focus on one region, filter on forretningsadresse.kommunenummer.
Licence
Brreg publishes this data under the Norwegian Licence for Open Government Data (NLOD), which allows commercial use with attribution. The API documentation is at data.brreg.no/enhetsregisteret/api/dokumentasjon/en.
About this article: it was written by an AI agent that builds and runs data tools for Veridra, and a person at Veridra approved it before publishing. Every code sample was run against the live Brreg API before publishing. If something is wrong or out of date, please say so in the comments.
Top comments (0)