Brønnøysund Company Lookup: Norway Business Registry API avatar

Brønnøysund Company Lookup: Norway Business Registry API

Pricing

from $2.00 / 1,000 successful lookups

Go to Apify Store
Brønnøysund Company Lookup: Norway Business Registry API

Brønnøysund Company Lookup: Norway Business Registry API

Look up Norwegian companies by organization number against Brønnøysund Register Centre's official, free registry. Get legal form, NACE industry code, address, employee count, VAT status, and bankruptcy flags. Pay only for numbers that resolve.

Pricing

from $2.00 / 1,000 successful lookups

Rating

0.0

(0)

Developer

Adrian Voss

Adrian Voss

Maintained by Community

Actor stats

1

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Share

Brønnøysund Company Lookup

You give this actor a list of Norwegian organization numbers. It looks each one up against the Brønnøysund Register Centre's official, free Enhetsregisteret (Central Coordinating Register for Legal Entities) API and returns one flat row per number — legal name, legal form, NACE industry code, registered address, employee count, VAT registration, and bankruptcy/liquidation status. No API key, no scraping: this calls the Norwegian government's own registry endpoint directly, for every input, every run.

Who it's for

The accountable_eel catalogue sells company intelligence columns for outbound. Each actor takes a list of domains or company identifiers and returns one flat, stably-named row per input — firmographics, registry IDs, tech stack, email route, hiring activity — the shape a Clay table, an n8n workflow, or an AI agent can consume without post-processing. Pricing is pay-per-event and per-domain: a few tenths of a cent for a row that was actually found, and nothing for a miss, so a list that doesn't enrich costs you next to nothing. Where an official source exists — VIES, GLEIF, SEC EDGAR, Brønnøysund, PRH, RDAP — it is queried directly instead of scraped. No seat licence, no monthly minimum, no credit system to decode. For Norway specifically, that official source is Brønnøysund's Enhetsregisteret — the same register a Norwegian bank or notary would check.

Why this one

  • Official registry, not a scrape. src/target.js hits data.brreg.no/enhetsregisteret/api/enheter/<orgnr> directly — the same JSON the Brønnøysund website itself is built on.
  • Compliance flags in the same row as firmographics. Bankruptcy and under-liquidation status come back alongside legal form, industry code, and employee count — you don't make a second call to ask "is this company still solvent."
  • 9-digit organization numbers only, and it says so. No name-matching, no fuzzy search — this is a deterministic lookup, so a wrong or malformed number fails cleanly as BAD_FORMAT instead of guessing.
  • Misses are still rows, and rows are still free. A number that doesn't resolve comes back with "found": false" and a plain-English reason, but is never billed.
  • Built for a list, not a lookup. Concurrency, keyword filtering, and column selection are all configurable inputs — feed in a few numbers or a few thousand.

Use cases

  • KYB / vendor onboarding. Confirm a Norwegian counterparty is registered, solvent, and not under liquidation before you sign a contract or set up a payment relationship with them.
  • Sales and lead enrichment. Attach legal form, industry code, and employee count to a list of Norwegian prospect organization numbers you already have from a CRM export or a scrape.
  • Credit and risk screening. Batch-check bankruptcy and under-liquidation flags across a portfolio of Norwegian entities on a schedule, instead of checking them one at a time on the Brønnøysund website.
  • Compliance data refresh. Re-verify VAT registration status and registered address for entities already sitting in your CRM, so stale records get caught before an audit does.

What you get

Every input produces exactly one row. These fields are always present:

FieldTypeDescription
querytextThe organization number you submitted, unmodified
foundbooleantrue if a matching entity was found (and billed), false if not
statustextOK, NOT_FOUND, or BAD_FORMAT
messagetextPlain-English reason for a miss (omitted when found is true)
scrapedAtISO 8601 timestampWhen this row was fetched

When found is true, these fields are also populated:

FieldTypeDescription
organizationNumbertextThe 9-digit Brønnøysund organization number, normalized
nametextRegistered legal name
organizationFormCodetextLegal form code, e.g. AS, ASA, ENK
organizationFormDescriptiontextLegal form spelled out, e.g. "Aksjeselskap"
industryCodetextPrimary NACE industry code
industryDescriptiontextIndustry description matching that code
registrationDatedateDate the entity was registered in Enhetsregisteret
employeeCountnumberEmployee count on file (can be null if not reported)
vatRegisteredbooleanWhether the entity is registered in the VAT (MVA) register
bankruptbooleanBankruptcy flag
underLiquidationbooleanUnder-liquidation flag
addressobject{ street, postalCode, city, municipality } — registered business address, falling back to postal address when no business address is on file
websitetextCompany website, when Brønnøysund has one on file (often null)

Field names are stable across runs — this is what lets an AI agent or a Clay HTTP column read the schema once and keep working.

Price

$4 per 1,000 organization numbers, plus a $0.00005 start fee. Misses (found:false) are never charged.

That works out to $0.004 per found row on the FREE tier, dropping to $0.002 per found row on Apify's GOLD tier — the actor-start fee is flat regardless of tier. 1,000 organization numbers through this actor: ~$4 if every one is found, less if some aren't. The same 1,000 rows through a credit-based enrichment platform: $80–$400. A miss — a number that isn't registered, or one you typed wrong — still comes back as a dataset row with found: false, but you're never billed for it.

How to use

  1. In the Apify Console. Open the actor page and click Start — the organizationNumbers field is already pre-filled with a working example. Results land in the run's dataset as soon as each item is found.
  2. Via the API. Call it directly with a POST request — no Console needed once you have an API token:
    curl "https://api.apify.com/v2/acts/accountable_eel~brreg-company-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
    -X POST \
    -H "Content-Type: application/json" \
    -d '{"organizationNumbers":["923609016","984851006"]}'
  3. On a schedule. Save this actor as an Apify Task with the input you want, then add a Schedule (hourly, daily, weekly) so it runs on its own — no server of your own required.
  1. Paste one 9-digit organization number per line into organizationNumbers, or pass an array of them via the API.
  2. Turn on testRun for your first attempt — it caps the run at the first 5 numbers so you can check the shape of the output before spending on the full list.
  3. Run the actor. One row comes back per number, in the same order you submitted them.
  4. If you only want rows that resolved, turn on onlyFound — misses are dropped from the dataset entirely (and were never billed regardless).
  5. Use columns to narrow the output to just the fields you need, and includeKeywords / excludeKeywords to filter rows by content (e.g. exclude anything with underLiquidation in the text, or keep only a specific industry code).

Input

{
"organizationNumbers": [
"923609016",
"984851006"
]
}

One 9-digit Brønnøysund organization number per line. Accepted formats: 923609016, spaces and dashes are removed automatically.

{
"organizationNumbers": ["923609016", "984851006"],
"testRun": false,
"onlyFound": false,
"maxConcurrency": 5
}

organizationNumbers is a list of 9-digit Norwegian organization numbers — spaces and dashes are removed automatically. One dataset row is returned per number; rows with "found": false are never charged. Turn on testRun to try your list against just the first 5 numbers before running the full batch. Optional includeKeywords / excludeKeywords filter rows by content, maxResults caps the run early, and columns lets you pick which fields to return.

Sample output

queryfoundstatusorganizationNumbernameorganizationFormCodeorganizationFormDescriptionindustryCodeindustryDescriptionregistrationDateemployeeCountvatRegisteredbankruptunderLiquidationaddresswebsitescrapedAt
923609016trueOK923609016EQUINOR ASAASAAllmennaksjeselskap06.100Utvinning av råolje1995-03-1221239truefalsefalse{"street":"Forusbeen 50","postalCode":"4035","city":"STAVANGER","municipality":"STAVANGER"}www.equinor.com2026-08-31T06:10:16.580Z

One row per organization number, for example:

{
"query": "923609016",
"found": true,
"status": "OK",
"organizationNumber": "923609016",
"name": "EQUINOR ASA",
"organizationFormCode": "ASA",
"organizationFormDescription": "Allmennaksjeselskap",
"industryCode": "06.100",
"industryDescription": "Utvinning av råolje",
"registrationDate": "1995-03-15",
"employeeCount": 21500,
"vatRegistered": true,
"bankrupt": false,
"underLiquidation": false,
"address": {
"street": "Forusbeen 50",
"postalCode": "4035",
"city": "STAVANGER",
"municipality": "STAVANGER"
},
"website": "www.equinor.com",
"scrapedAt": "2026-08-21T10:00:00.000Z"
}

Numbers that don't resolve still get a row ("found": false, "status": "NOT_FOUND" or "BAD_FORMAT", with a plain-English message), so you always get one row per input — but you're never charged for those.

Use it from Clay, n8n, Make, or an AI agent

This actor runs synchronously over plain HTTP — call it directly from a script, a workflow tool, or an AI agent, no Apify Console needed once you have an API token.

curl "https://api.apify.com/v2/acts/accountable_eel~brreg-company-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
-X POST \
-H "Content-Type: application/json" \
-d '{"organizationNumbers":["923609016","984851006"]}'

n8n. Add an HTTP Request node: Method POST, URL https://api.apify.com/v2/acts/accountable_eel~brreg-company-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>, Body Content Type JSON, JSON Body {"organizationNumbers":["923609016","984851006"]} (swap in an expression from an earlier node for a real value).

Clay. Add an "HTTP API" column: Method POST, URL https://api.apify.com/v2/acts/accountable_eel~brreg-company-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>, Body {"organizationNumbers":["{{organization number}}"]}, mapping the row's organization number into the organizationNumbers array.

MCP. In Claude, Cursor, or any MCP client with the Apify MCP server, ask for "Norway Company Registry Lookup | Apify" — the agent will find and run this actor.

Tips

  • Run testRun: true on a new list first — it's free-ish (5 numbers) and confirms your input format before you commit a large batch.
  • Turn on onlyFound when you're feeding results straight into a CRM or Clay table and don't want NOT_FOUND rows cluttering the import.
  • bankrupt and underLiquidation are separate flags — a company can be underLiquidation: true and bankrupt: false (voluntary winding-up is not the same as insolvency).
  • employeeCount and website are both frequently null — not every entity reports employees to Brønnøysund, and many small entities have no website on file. Don't treat a null as an error.
  • If you already have organization numbers from another source (a CRM field, a scrape, an earlier actor run), strip anything that isn't 9 digits before you submit — BAD_FORMAT rows are free but they're still a row you have to filter out downstream.
  • industryCode follows Norway's NACE classification, not NAICS or SIC — if you're filtering or joining against a US-sourced dataset, map the code rather than string-matching the description.
  • The address object falls back from business address to postal address automatically, but a small number of entities (shell companies, some foundations) file neither — expect an occasional null there even on an otherwise fully populated row.

vs. alternatives

What it costsWhat you getTrade-off
This actor (brreg-company-lookup)$0.004 per found row (FREE tier, less on paid tiers), $0.00005 actor start, nothing for a missOne row per organization number — legal form, NACE industry code, registered address, employee count, VAT status, bankruptcy/liquidation flagsNorwegian organization numbers only, exact match — no company-name search, and it won't resolve a number that's typed wrong or belongs to a different country
Brønnøysund directlyFreeThe same data, from the same sourceIt's the same source — this actor exists for the batch: thousands of numbers in, thousands of rows out, retries and rate limits handled, in the format your table already reads. One number, once? Use the portal.
Clay$0.08–$0.40 per enriched row in credits, on top of a seatA whole enrichment workspace — waterfalls across dozens of providers, plus the table and the sequencing around itIf you want one place that does everything and you're not counting rows, that's Clay. This is one column, priced per column, callable from Clay via its HTTP step.
Doing it yourselfYour time + handling Brønnøysund's response shapes (address falls back between two different fields, 404s serve no Content-Type header) and rate limits across a listThe same dataThis actor absorbs the edge cases already found in src/target.js — the missing-header 404, the address fallback — so you don't rediscover them one failed request at a time

Prices for third-party tools are their published list prices as of August 2026 and are not tracked here — check the vendor before relying on the comparison.

FAQ

What happens when an organization number isn't found? You get a row with "found": false, "status": "NOT_FOUND", and a plain-English message. It counts toward your dataset but not toward your bill — only rows with found: true are charged.

What if I submit something that isn't a valid organization number? It's rejected before any request is made, returned as "status": "BAD_FORMAT", and not charged. Spaces and dashes are stripped automatically (923 609 016 and 923-609-016 both normalize to 923609016), but anything that isn't 9 digits after that fails as BAD_FORMAT.

Are there rate limits? maxConcurrency controls how many requests run in parallel (default 5) — set it lower if you want to be gentler on Brønnøysund's API, or raise it for a large batch. The actor doesn't impose its own cap beyond that; Brønnøysund's public API doesn't publish a documented rate limit, but very high concurrency on a very large list is the thing most likely to trigger throttling on their end. If you're running thousands of numbers and see failed requests climb, dropping maxConcurrency to 2 or 3 usually clears it up.

How fresh is the data? Each row reflects what Enhetsregisteret returned at the moment the actor ran (scrapedAt records that timestamp). Nothing is cached or stored between runs — if a company's status changes in Brønnøysund's register, whether that's a new bankruptcy filing, an address change, or a VAT deregistration, the next run picks it up. There's no lag between what the actor returns and what the register currently shows.

Does this need proxies? No. Brønnøysund's API is public, unauthenticated, and not behind bot protection — the actor calls it directly.

Is this personal data, and does GDPR apply? The fields returned are entity-level — legal name, registered address, industry code, employee count, compliance flags — not data about named individuals. This actor doesn't return board members, signatories, or any other named-person fields, so there's no personal-data question to navigate on that front. It's public Norwegian company-register data either way, not scraped from a third-party site — the same records a Norwegian bank, landlord, or notary would pull to check a counterparty before signing anything with them.

What's the difference between organizationFormCode values I might see? The most common are AS (private limited company), ASA (public limited company, like the Equinor example above), ENK (sole proprietorship), and STI (foundation) — but Enhetsregisteret covers dozens of legal forms, including associations and public-sector entities. organizationFormDescription spells out whichever code comes back, so you don't need to memorize the list.

Can I schedule this to re-run on a list I already have? Yes — set it up as an Apify scheduled task with a saved input, and each run re-checks your list against the live register. There's no delta or "changed since last run" mode built in; every run re-fetches every number.

Can an AI agent call this directly? Yes, via the Apify MCP server — an agent asks for "Norway Company Registry Lookup | Apify" and can run it with a list of organization numbers, no separate integration code needed.

Does this cover anything outside Norway? No. It only resolves entities registered in Norway's Enhetsregisteret. For Finnish entities, see prh-company-lookup; for a single call that checks several national registries at once, see company-registry-unified-lookup.