# Swedish Company Register Lookup (`thesjostrandproject/se-company-lookup`) Actor

Look up Swedish companies by organisation number, or search one postal town by name, legal form or SNI code, in Bolagsverket's and SCB's weekly bulk files. Organisations only: no sole traders, no street addresses. Includes the reklamspärr flag. Pay per record.

- **URL**: https://apify.com/thesjostrandproject/se-company-lookup.md
- **Developed by:** [The Sjöstrand Project](https://apify.com/thesjostrandproject) (community)
- **Categories:** Business, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 company records

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Swedish Company Register Lookup

### What this Actor returns

Look up Swedish companies by organisation number, or search one postal town (postort) by company name, legal form or SNI activity code, and get one clean record per company register entry. Every record has the same 17 fields, with every value as Bolagsverket and Statistics Sweden (SCB) published it. Every record carries the dates of the two files it was built from.

- `orgnr`, `company_title`, `other_titles`, `legal_form`, `registered`: the organisation number, the registered company name and any other registered names, the legal form code (like `AB-ORGFO` for an aktiebolag) and the registration date
- `proceedings`: ongoing winding-up or restructuring proceedings as Bolagsverket lists them, or null
- `postcode`, `town`: the postcode and postal town of the company's postal address
- `sni`, `scb_company_status`, `scb_legal_unit_status`, `scb_legal_form`: SCB's activity codes (SNI 2007) and status and legal form codes
- `marketing_opt_out`: SCB's reklamspärr flag, `true`, `false` or `null` (see "Limits and honest notes")
- `source`, `bolagsverket_file_date`, `scb_file_date`, `index_built_at`: the two registers and the dates of the bulk files the record comes from, and when the index was built

The Actor reads a filtered copy of the two registers' weekly bulk files, rebuilt from the files themselves. It does not scrape any website, and there is no login.

### Who it helps

- **Analysts and sales teams** who want a tidy list of the companies of one activity or legal form in one postal town, ready for a spreadsheet, with the reklamspärr flag beside each one.
- **Developers** who want to check or enrich organisation numbers inside their own workflow, through the Apify API, without downloading and joining the weekly bulk files themselves.

### Quick start

1. Open the Input tab and leave the defaults as they are. They look up one large company, so a first run returns one record.
2. Press Start. Try it on one record first; it costs a fraction of a cent.
3. Open the Output tab, check the record, then use your own organisation numbers, or set "Search by" to place and name a postal town.

### Input

| Field | What it does | Default |
|---|---|---|
| Search by | `orgnr` looks up the number list; `place` searches one postal town, and the number list is then not used. | `orgnr` |
| Organisation numbers | Up to 100 numbers per run, 10 digits each, written `NNNNNN-NNNN` or without the dash. A number shaped like a personal identity number (personnummer) is refused, see below. | one example company |
| Postal town (postort) | For a place search: the postal town of the postal address. Capitals and spacing do not matter; å, ä and ö do, so Malmö is not Malmo. | empty |
| Company name contains | For a place search: only companies whose registered name, or one of their other registered names, contains this text. Capitals and spacing do not matter. | empty |
| Legal form | For a place search: only this Bolagsverket legal form code, like `AB` (aktiebolag), `HB` (handelsbolag) or `EK` (ekonomisk förening). | empty |
| SNI code starts with | For a place search: only companies with an SNI 2007 code starting with these 2 to 5 digits, like `62` or `62.010`. Any of a company's up to five codes counts. | empty |
| Reklamspärr | For a place search: `true` returns only companies with reklamspärr set; `false` returns only companies SCB records as without it, so null records are left out; empty returns all. | empty |
| Maximum records | How many records to return at most, from 1 to 1000. | 10 |

### Output

One record per company register entry; an organisation registered under a name-protection serial number can have more than one, and each is its own record with the same `orgnr`. The record below is an illustration with invented values, in the exact shape every record has.

```json
{
  "orgnr": "5561000018",
  "company_title": "Syntet Exempel AB",
  "other_titles": [{"title": "Exempel Bageri", "type": "SARS_FORNAMN-ORGNAM", "date": "2002-02-02"}],
  "legal_form": "AB-ORGFO",
  "registered": "2001-02-03",
  "proceedings": null,
  "postcode": "11122",
  "town": "STOCKHOLM",
  "sni": ["62010", "47110"],
  "scb_company_status": "1",
  "scb_legal_unit_status": "1",
  "scb_legal_form": "49",
  "marketing_opt_out": false,
  "source": "Bolagsverket, Värdefulla datamängder (bulk file dated 2026-10-12); Statistiska centralbyrån, Företagsregistret (bulk file dated 2026-10-12)",
  "bolagsverket_file_date": "2026-10-12",
  "scb_file_date": "2026-10-12",
  "index_built_at": "2026-10-12T15:00:00Z"
}
```

Values are kept as published: codes stay as the registers write them, dates are `YYYY-MM-DD`, and town names keep their spelling and capitals. A value the registers do not have is `null`.

### What it costs

You pay for up to three events, and only for what you ask:

- **Company record**, $0.003 per record returned. Records the Actor leaves out (see below) are never charged.
- **Place search**, $0.02 once per place search, charged as soon as the first part of the town's index has been read, so a search that cannot reach the index costs nothing. A lookup by organisation number never pays it.
- **Organisation number not found**, $0.001 for each number in your list that returns no record: not in the data, or left out by the companies-only rules. It is charged as soon as the part of the index that would hold it has been read. A number that returns a record pays only for its records.

Apify also adds its standard run-start event, $0.00005 per start for an Actor run with up to 1 GB of memory; it is the platform's own event, not ours.

For example, a place search that returns 200 records costs $0.02 + $0.60 = $0.62, and a list of 50 numbers of which 45 are found costs 45 × $0.003 + 5 × $0.001 = $0.14. If your Apify plan includes monthly credit, a small run draws on that credit.

Why a search and a miss cost something: every part of the index the Actor reads costs us storage reads, data transfer and compute, whether or not anything matches.

If the company index cannot be reached, the run stops with a clear status message before any record is returned, so nothing is charged. If part of the index fails mid-run, only what was already charged stands: the search (for a place search, once its first part was read), the records already returned and the numbers already found missing.

If you set a maximum charge per run, a place search needs it to cover the search and one record ($0.023) and a lookup needs it to cover one not-found charge ($0.001); below that the Actor reads nothing, charges nothing and its status message names the least maximum charge to set. Once running, the Actor stops reading as soon as the next charge would not fit, and its status message says "stopped at the run's maximum charge" and how much of the index it searched. Numbers in parts it did not read are not charged as not found.

### Limits and honest notes

- **Organisations only.** Sole traders (enskild näringsverksamhet), estates of deceased persons and every other natural-person entry are left out, and so are organisations that are deregistered. Organisations that are only in SCB's file (such as many associations) are not included.
- **Personal identity numbers are refused.** A number shaped like a personal identity number (12 digits, or 10 digits whose third digit is 0 or 1) is refused before anything is read, with the message "this looks like a personal identity number; this tool holds companies only"; nothing is charged, and the Actor never repeats the number in its status message, log, dataset or charges. Apify keeps the run's INPUT record as you typed it, so the number stays in that record of your own run; delete the run if you entered one by mistake.
- **Postcode and town only, no street.** The data returned has no street address, no c/o line, no phones, no emails and no business descriptions: postcode and town are the finest place.
- **Names can still be personal.** A company's registered name is free text, and the name of an aktiebolag or a partnership can be its owner's or partners' personal names.
- **Reklamspärr is three-state.** `true` means SCB records reklamspärr (an objection to direct marketing) for the company, `false` means SCB records that it is not set, and `null` means SCB has no record for the company, not "no objection". Companies are never left out for it; filtering on `false` leaves the null records out.
- **Your duties.** A record can concern a one-person company, such as an aktiebolag whose name is its owner's, and then GDPR applies to how you use it. Respect reklamspärr: check the flag before any direct marketing, and treat `null` as unknown.
- **Freshness.** Both registers publish their bulk files weekly, and the index is rebuilt once both files of a week have appeared, so a record can be up to about two weeks old. Every record names the dates of the files it comes from (`bolagsverket_file_date`, `scb_file_date`).
- **A place search covers one postal town (postort).** A postal town is the town of the postcode line, not a municipality (kommun) or county (län): one municipality can span several postal towns. There is no nationwide or county-wide search. Companies without a postal town are found by organisation number only. Filters such as a name or an SNI code narrow what comes back, not what is read.
- **A read limit per run.** One place search reads at most 12 parts of the index and 8 MiB; one lookup takes up to 100 numbers and reads at most 100 parts and 40 MiB. If a run reaches its limit, it stops cleanly and its status message says "searched N of M index parts"; numbers in parts it did not read are not charged as not found.
- **Order.** Records come in organisation number order; in a place search, within the town.

### Questions

**Why did my run return fewer records than I asked for?**
Fewer companies matched, the number is not in the data (a sole trader, a deregistered company, or a number that does not exist), or the run reached its read limit (its status message then says how much it searched). Records are charged only when returned; a number that returns no record is charged as not found.

**What does the run say when something is wrong?**
It says what it found and what to try. "Its check digit does not match" means a digit is mistyped; the message names the entry's position in your list, never the number. "No postal town by that name" means the spelling is off; remember that Malmö is not Malmo. "Is left out of this dataset" means that legal form is a sole trader's. "The company index could not be read" means the data is briefly unavailable; wait a few minutes and run again.

**Can I give the 12-digit form with the 16 prefix?**
No. Give the 10-digit organisation number; 12-digit numbers are refused as personal identity numbers.

**Does it return the people behind a company?**
No. Board members, owners and signatories are not in the data.

**Can I run it on a schedule?**
Yes, with the Apify scheduler or the API. Each run is independent and charged for what it returns and searches, as above.

### Data source and AI note

Data source: Bolagsverket, Värdefulla datamängder (the Swedish Companies Registration Office's weekly bulk file), and Statistiska centralbyrån, Företagsregistret (Statistics Sweden's business register bulk file), both downloaded from Bolagsverket's bulk-file service. No licence is stated: neither file carries a licence, and the source page states that the files are free of charge, with no agreement required and no restrictions stated, so this tool makes no licence claim. Every record names both registers and the dates of their bulk files in its `source` field. This tool returns selected records and fields without modification: it does not correct, translate, re-case or re-format any value, and the two files are joined only on the organisation number; the data has no per-record source_updated_at date, so each record's bolagsverket_file_date and scb_file_date give the dates of the files it was read from.

This tool is not affiliated with, endorsed by or sponsored by Bolagsverket, Statistics Sweden or the Swedish government.

This tool was built with the help of AI coding assistants.

### Help

Questions, a record that looks wrong, or an idea for a field: please open an issue on the Issues tab. Thank you for the report; every one is read.

# Actor input Schema

## `searchBy` (type: `string`):

orgnr looks up the organisation numbers below. place searches one postal town (postort), with optional filters; the number list is then not used.

## `orgnrs` (type: `array`):

Swedish organisation numbers, 10 digits, written NNNNNN-NNNN or without the dash. Up to 100 per run. A personal identity number is refused: this tool holds companies only. The default is one large company; replace it with your own.

## `town` (type: `string`):

For a place search: the postal town of the company's postal address, as in the postcode line (capitals and spacing do not matter; å, ä and ö do, so Malmö is not Malmo). A postal town is not a municipality or county.

## `nameContains` (type: `string`):

For a place search: only companies whose registered name, or one of their other registered names, contains this text. Capitals and spacing do not matter. Leave empty for any name.

## `legalForm` (type: `string`):

For a place search: only this Bolagsverket legal form code, like AB (aktiebolag), HB (handelsbolag), KB (kommanditbolag) or EK (ekonomisk förening); AB and AB-ORGFO are the same. Leave empty for any.

## `sniPrefix` (type: `string`):

For a place search: only companies with an SNI 2007 activity code (any of their up to five) starting with these 2 to 5 digits, like 62 or 62.010. Dots are ignored. Leave empty for any activity.

## `marketingOptOut` (type: `string`):

For a place search: true returns only companies with SCB's reklamspärr set; false returns only companies SCB records as without it (records with no SCB flag are left out). Empty returns all.

## `maxItems` (type: `integer`):

How many company records to return at most (1 to 1000). You pay only for records returned, so a first run stays cheap.

## Actor input object example

```json
{
  "searchBy": "orgnr",
  "orgnrs": [
    "5560125790"
  ],
  "town": "Malmö",
  "nameContains": "bygg",
  "legalForm": "AB",
  "sniPrefix": "62",
  "marketingOptOut": "",
  "maxItems": 10
}
```

# Actor output Schema

## `results` (type: `string`):

The company records of this run, with the 17 fields described in the dataset schema (organisation number, names, legal form, registration, proceedings, postcode and town, SNI codes, SCB codes, reklamspärr, source and file dates).

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "searchBy": "orgnr",
    "orgnrs": [
        "5560125790"
    ],
    "town": "",
    "nameContains": "",
    "legalForm": "",
    "sniPrefix": "",
    "marketingOptOut": "",
    "maxItems": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("thesjostrandproject/se-company-lookup").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "searchBy": "orgnr",
    "orgnrs": ["5560125790"],
    "town": "",
    "nameContains": "",
    "legalForm": "",
    "sniPrefix": "",
    "marketingOptOut": "",
    "maxItems": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("thesjostrandproject/se-company-lookup").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchBy": "orgnr",
  "orgnrs": [
    "5560125790"
  ],
  "town": "",
  "nameContains": "",
  "legalForm": "",
  "sniPrefix": "",
  "marketingOptOut": "",
  "maxItems": 10
}' |
apify call thesjostrandproject/se-company-lookup --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,thesjostrandproject/se-company-lookup"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/qnJ83A0MYg1q5aDKf/builds/a80WIAEJWK64MwCZJ/openapi.json
