Documentation and API Reference
6 HTTP endpoints returning JSON. No API key required. The database covers 3 million Swedish companies.
Quick start
Name search with CORS (callable from any domain):
const res = await fetch('https://mackan.eu/tools/bolagsverket/search_name.php?q=IKEA');
const { results } = await res.json();
console.log(results[0]);
// { orgnr: "5560747551", name: "IKEA Aktiebolag", form: "AB",
// active: true, city: "Älmhult", reg_year: 1958 }
Address search with industry and legal form filters:
const url = new URL('https://mackan.eu/tools/bolagsverket/search_address.php');
url.searchParams.set('addr', 'Drottninggatan Stockholm');
url.searchParams.set('branch', 'mode');
url.searchParams.set('form', 'AB');
url.searchParams.set('limit', '100');
const { results, total } = await fetch(url).then(r => r.json());
console.log(`${total} companies found, showing ${results.length}`);
Registration waves: see when an industry took off:
const res = await fetch(
'https://mackan.eu/tools/bolagsverket/reg_waves.php'
+ '?q=restaurang&min_year=1990&max_year=2024'
);
const { years, counts, anomalies } = await res.json();
// Peak years (statistical anomaly, mean + 2σ):
const peaks = years.filter((_, i) => anomalies[i]);
console.log(peaks); // e.g. [1999, 2000, 2021]
Address network: which companies share an address with a given company?
const res = await fetch(
'https://mackan.eu/tools/bolagsverket/address_network.php?orgnr=5560747551'
);
const { nodes, total, address } = await res.json();
console.log(`${total} companies at ${address}`);
const active = nodes.filter(n => n.active).length;
console.log(`${active} active, ${total - active} dissolved`);
Feature guide
Quick search
- Enter an organisation number (10 digits, dashes optional) and click Search.
- Type a company name instead to see suggestions in real time. Click a suggestion to auto-fill the org number.
- "Did you mean?" appears when there is no exact match; similar companies are suggested.
- Results show name, address, SNI codes, registration date, business description and annual reports.
- The JSON, CSV and Copy buttons export the current result.
Deep link:
Link directly to a company using ?orgnr=5560747551 in the URL. The search starts automatically.
Batch search
- Paste organisation numbers into the text box (one per line) or upload a CSV/TXT file.
- Click Search all: the tool fetches all companies in sequence.
- Results appear in a table with status per row (OK, Not found, Error).
- Export the full result as CSV, JSON or Excel using the buttons above the table.
- Select companies in the table and click Show on map to view addresses in the map tab.
Tip: Add a company from Quick search to Batch using the + Add to batch button in the result view.
Watchlist
- Click Watch in a search result to save the company to the watchlist.
- The list is stored in browser localStorage. It persists between sessions but is tied to the device.
- Click a company in the watchlist to look it up directly in Quick search.
- Remove individual companies or clear the entire list with the buttons in the tab.
Note: The watchlist is local and not server-synced. Clearing browser localStorage removes the list.
Address search
- Enter an address, street, city or postal code in the top field.
- Add an industry keyword in the second field (or click a chip) to filter by business type.
- Filter by legal form (AB, HB, Brf ...) and choose whether to show active companies only.
- Click a company row to open the company drawer with four quick actions.
- Sort the table by name, form, city or registration year using the column headers.
- Export all fetches up to 500 matching companies and downloads them as CSV.
Combined search: Try "Drottninggatan Stockholm" as address and "fashion clothing" as industry to find clothing stores on that specific street.
Analysis tab
Contains two separate OSINT tools:
Address network
- Enter an organisation number and click Show address network.
- The diagram shows the searched company in the centre (hub) and all companies at the same registered address around it (spokes).
- Green nodes are active companies, grey ones are dissolved.
- Click a node to look up that company in Quick search.
Registration waves
- Enter a keyword (industry or activity) and optionally choose legal form and time range.
- The bar chart shows how many companies were registered each year.
- Orange bars are statistical anomalies (more than 2 standard deviations from the mean). Boom years stand out clearly.
Difference from the Network tab: Address network in Analysis starts from a single company. The Network tab draws connections between companies in a batch search.
Network tab
- Run a batch search with several organisation numbers.
- The Network tab automatically draws a graph where lines connect companies sharing a registered address.
- Node size reflects the number of address connections. Isolated nodes share no address with others in the batch.
- Export the graph as SVG, JSON or CSV using the buttons below the graph.
- Share image generates a PNG of the graph for articles and reports.
Note: A shared address does not imply ownership or legal connection. It may simply reflect a shared office or business centre.
API Reference
Base URL: https://mackan.eu/tools/bolagsverket/ — all responses: JSON, UTF-8.
get_data.php
Fetches complete company information directly from the Bolagsverket official API and returns the response unprocessed.
Parameters
| Name | Type | Description |
|---|---|---|
| orgnr | req string | 10 digits, dash allowed |
Example
const res = await fetch(
'https://mackan.eu/tools/bolagsverket/get_data.php?orgnr=556074-7551'
);
const data = await res.json();
// data.namn, data.juridiskForm, data.adress.gatuadress,
// data.sniKoder, data.registreringsDatum, data.beskrivning, ...
console.log(data.namn); // "IKEA Aktiebolag"
curl
curl "https://mackan.eu/tools/bolagsverket/get_data.php?orgnr=5560747551"
The call is proxied server-side to the Bolagsverket API (OAuth2 Client Credentials). Rate limit: 60 requests/minute. No key needed from the client.
search_name.php
Full-text search on company names in the local database (3 million companies). Returns up to 8 results. Falls back to LIKE search if FULLTEXT returns zero results.
CORS: Access-Control-Allow-Origin: * — callable from any domain.
Parameters
| Name | Type | Description |
|---|---|---|
| q | req string | Company name (min 2 chars) |
Response
{
"results": [
{
"orgnr": "5560747551",
"name": "IKEA Aktiebolag",
"extra_names": ["INGKA Holding"], // former or alternative names
"form": "AB",
"active": true,
"city": "Älmhult",
"reg_year": 1958
}
],
"mode": "exact" // "exact" | "menade_du" | "empty"
}
Example
const res = await fetch(
'https://mackan.eu/tools/bolagsverket/search_name.php?q=Spotify'
);
const { results, mode } = await res.json();
if (mode === 'menade_du') {
console.log('No exact match, suggestions:', results.map(r => r.name));
} else {
results.forEach(r => console.log(r.orgnr, r.name, r.city));
}
search_address.php
Search companies by address, street, city or postal code using FULLTEXT. Combine with industry keyword search against the business description. Filter by legal form and status.
Parameters
| Name | Type | Description |
|---|---|---|
| addr | opt string | Address, street, city or postal code (min 2 chars) |
| branch | opt string | Industry or activity keyword against the description field (min 2 chars) |
| form | opt string | Legal form: AB, HB, KB, EK, E, I, BRF, S, FL |
| active | opt int | 1 = active only (default), 0 = all |
| limit | opt int | 1–500, default 20 |
Response
{
"results": [
{
"orgnr": "5566012345",
"name": "Modebutiken AB",
"form": "AB",
"active": true,
"city": "Stockholm",
"zip": "11122",
"address": "Drottninggatan 42 11122 Stockholm",
"description": "Detaljhandel med kläder och accessoarer",
"reg_year": 2012
}
],
"total": 47, // total matching companies in the database
"shown": 20 // count in this response
}
Examples
// Active ABs on Storgatan in Malmö
const { results, total } = await fetch(
'https://mackan.eu/tools/bolagsverket/search_address.php'
+ '?addr=Storgatan+Malmö&form=AB&limit=100'
).then(r => r.json());
console.log(total, 'total');
// All companies (active + dissolved) at a postal code
const { results } = await fetch(
'https://mackan.eu/tools/bolagsverket/search_address.php'
+ '?addr=11122&active=0&limit=500'
).then(r => r.json());
address_network.php
Returns all companies sharing the same registered address as a given company. Useful for mapping co-located businesses and company structures. Max 50 companies per response.
Parameters
| Name | Type | Description |
|---|---|---|
| orgnr | req string | 10 digits |
Response
{
"address": "Storgatan 10",
"city": "Stockholm",
"root_orgnr": "5560747551",
"root_name": "IKEA Aktiebolag",
"total": 12, // total matching companies (may exceed nodes)
"nodes": [
{
"orgnr": "5566012345",
"name": "Grannbolaget AB",
"form": "AB",
"active": true,
"city": "Stockholm",
"reg_year": 2018
}
]
}
Example
const res = await fetch(
'https://mackan.eu/tools/bolagsverket/address_network.php?orgnr=5560747551'
);
const { nodes, total, address } = await res.json();
console.log(`${total} companies at "${address}"`);
const dissolved = nodes.filter(n => !n.active);
if (dissolved.length > 0) {
console.log(`${dissolved.length} dissolved:`, dissolved.map(n => n.name));
}
reg_waves.php
Registration waves: number of newly registered companies per year for a search query. Includes anomaly detection using mean + 2σ to flag statistically significant years.
Parameters
| Name | Type | Description |
|---|---|---|
| q | opt string | Name or activity keyword (min 3 chars per word) |
| form | opt string | Legal form: AB, HB, KB, EK, E, I, BRF, S, FL |
| min_year | opt int | Start year (default 1970) |
| max_year | opt int | End year (default: current year) |
Response
{
"years": [1990, 1991, ..., 2024],
"counts": [14, 18, ..., 312], // registered companies per year
"active": [8, 11, ..., 240], // of these still active
"anomalies": [false, false, ..., true], // true = statistical anomaly
"total": 4821,
"mean": 178.6,
"stddev": 89.2,
"threshold": 356.9, // anomaly threshold (mean + 2σ)
"query": "restaurang"
}
Examples
// IT booms in Sweden: find peak years for tech companies
const { years, counts, anomalies, threshold } = await fetch(
'https://mackan.eu/tools/bolagsverket/reg_waves.php'
+ '?q=teknik&form=AB&min_year=1995&max_year=2024'
).then(r => r.json());
const peaks = years
.map((y, i) => ({ year: y, count: counts[i], anomaly: anomalies[i] }))
.filter(d => d.anomaly);
console.log('Peak years:', peaks);
// [{year: 1999, count: 487, anomaly: true}, {year: 2000, ...}]
// All AB registrations without filtering (historical overview)
const data = await fetch(
'https://mackan.eu/tools/bolagsverket/reg_waves.php?form=AB&min_year=1900'
).then(r => r.json());
bv_sync_info.php
Returns the timestamp of the latest database synchronisation and the approximate company count. Response is cached for 1 hour.
Response
{
"last_updated": "2026-05-12 03:00:00",
"approx_rows": 3014820
}
Example
const { last_updated, approx_rows } = await fetch(
'https://mackan.eu/tools/bolagsverket/bv_sync_info.php'
).then(r => r.json());
const date = new Intl.DateTimeFormat('en-GB').format(new Date(last_updated));
console.log(`${approx_rows.toLocaleString()} companies, last synced ${date}`);
Features
| Feature | Description | Tab |
|---|---|---|
| Quick search (org.nr) | Fetches full registry data directly from the Bolagsverket API | Snabbsök |
| Name search with autocomplete | Full-text search against the local database, suggestions appear as you type. Handles spelling variants and alternative names. | Snabbsök |
| Watchlist | Save companies locally in the browser for quick re-access | Snabbsök |
| Annual reports | View and link directly to submitted annual reports | Snabbsök |
| Activity indicator | Based on regularity of the annual reporting history | Snabbsök |
| Batch search | Import CSV/TXT with org numbers, search all and export results | Batch |
| Address search | Search by address, street, city or postal code. Combine with industry and legal form filters. | Adress |
| Sortable address table | Click column header to sort by name, legal form, city or registration year | Adress |
| Company drawer | Click a company in address results for a quick-view panel. Actions: To Batch, Show on map, Address network, Fetch full info. | Adress |
| Export all (up to 500) | Fetches up to 500 address search results and downloads as CSV in one step | Adress |
| Map view | Visualises company addresses on an interactive Leaflet/OpenStreetMap map | Karta |
| Network graph | Draws connections between companies in a batch search sharing the same address | Nätverk |
| Address network (hub-and-spoke) | SVG visualisation of all companies at the same address as a single company. Green = active, grey = dissolved. | Analys |
| Registration waves | Bar chart of new registrations per year. Orange bars mark statistical anomalies (mean + 2σ). | Analys |
| Export: CSV / JSON / Excel | Export search results in any format. Copy button for clipboard. | All |
| Deep link | Link directly to a search: ?orgnr=5560747551 or ?orgnr=5560747551&lang=en |
– |
| Validation (checksum) | Separate page that verifies organisation numbers using the Luhn algorithm, step by step | validera/ |
| Bilingual (SV/EN) | The entire interface and documentation is available in Swedish and English | – |
Technical information
Bolagsverket open data register (Värdefulla datamängder v1) + official API
Automatic weekly sync, approx 3 million companies
search_name.php: Access-Control-Allow-Origin: *
Other endpoints: same-origin
OAuth2 handled server-side. No key required from the client.
get_data.php: 60 req/min, 5000/day per IP
Local endpoints: no limit
JSON, UTF-8. HTTP 400 on invalid input, 503 on db error.
MySQL FULLTEXT (InnoDB, boolean mode). Min token length: 3 chars.
Leaflet + OpenStreetMap + Nominatim (geocoding)
Error codes
| Response | HTTP | Meaning |
|---|---|---|
| {"error":"invalid_orgnr"} | 400 | Invalid organisation number |
| {"error":"db_unavailable"} | 503 | Database unreachable |
| {"error":"no_address"} | 200 | Company has no street address in the database (address_network.php) |
| {"error":"too_short"} | 200 | Search term too short (reg_waves.php) |
| {"results":[],"mode":"empty"} | 200 | No results (search_name.php) |
Deep link to search
Link directly to an org number search via URL parameter. The search starts automatically.
https://mackan.eu/tools/bolagsverket/?orgnr=5560747551
https://mackan.eu/tools/bolagsverket/?orgnr=5560747551&lang=en