DEV Community

Cizze R
Cizze R

Posted on

How to Access Swedish Company Data via API

How to Access Swedish Company Data via API

If you're doing business in Sweden — compliance checks, supplier verification, market research — you need Bolagsverket, the official company registry. They have a search interface, but no public API.

The Swedish Company Registry scrapes Bolagsverket's Next.js frontend and returns structured JSON. Search by company name or organization number and get back everything in one call.

What you get

{
  "org_number": "556703-7482",
  "name": "Spotify AB",
  "legal_form": "Aktiebolag",
  "status": "Registrerat",
  "address": "Regeringsgatan 19, 111 53 Stockholm",
  "county": "Stockholms län",
  "registration_date": "2006-02-23",
  "officers": [
    {"name": "Daniel Ek", "role": "Verkställande direktör"}
  ]
}
Enter fullscreen mode Exit fullscreen mode

Using it

import requests, time

API_TOKEN = "YOUR_APIFY_TOKEN"
ACTOR_ID = "weeknds~swedish-company-registry"

def search_company(query):
    resp = requests.post(
        f"https://api.apify.com/v2/acts/{ACTOR_ID}/runs",
        headers={"Authorization": f"Bearer {API_TOKEN}"},
        json={"searchQuery": query, "maxResults": 10}
    )
    run_id = resp.json()["data"]["id"]
    time.sleep(10)

    items = requests.get(
        f"https://api.apify.com/v2/acts/{ACTOR_ID}/runs/{run_id}/dataset/items",
        headers={"Authorization": f"Bearer {API_TOKEN}"}
    ).json()
    return items

results = search_company("Spotify")
for company in results:
    print(f"{company['name']} ({company['org_number']})")
    print(f"  {company['address']}")
Enter fullscreen mode Exit fullscreen mode

Supplier verification

Check if a supplier is actually registered:

def verify_supplier(org_number):
    results = search_company(org_number)

    if not results:
        return {"valid": False, "reason": "Not found in Bolagsverket"}

    company = results[0]

    if company["status"] != "Registrerat":
        return {"valid": False, "reason": f"Status: {company['status']}"}

    return {
        "valid": True,
        "name": company["name"],
        "org_number": company["org_number"],
        "registered_since": company["registration_date"],
        "address": company["address"]
    }
Enter fullscreen mode Exit fullscreen mode

Market research

Find all companies matching a keyword and see their distribution across counties and legal forms:

def analyze_industry(keyword):
    results = search_company(keyword)

    stats = {
        "total_found": len(results),
        "by_county": {},
        "by_legal_form": {}
    }

    for company in results:
        county = company.get("county", "Unknown")
        stats["by_county"][county] = stats["by_county"].get(county, 0) + 1

        form = company.get("legal_form", "Unknown")
        stats["by_legal_form"][form] = stats["by_legal_form"].get(form, 0) + 1

    return stats
Enter fullscreen mode Exit fullscreen mode

Compliance checks

Flag companies that might need a closer look — recently registered entities or ones with non-standard status:

from datetime import datetime, timedelta

def check_compliance(org_number):
    results = search_company(org_number)
    if not results:
        return {"error": "Company not found"}

    company = results[0]
    flags = []

    reg_date = datetime.strptime(company["registration_date"], "%Y-%m-%d")
    if reg_date > datetime.now() - timedelta(days=90):
        flags.append("Recently registered (< 90 days)")

    if company["status"] != "Registrerat":
        flags.append(f"Non-standard status: {company['status']}")

    return {
        "org_number": org_number,
        "name": company["name"],
        "flags": flags,
        "risk_level": "high" if len(flags) > 1 else "low" if not flags else "medium"
    }
Enter fullscreen mode Exit fullscreen mode

What to know

Two inputs: searchQuery (company name or org number) and maxResults (defaults to 10).

Bolagsverket rate-limits requests. The actor handles this automatically, but bulk queries will be slower than single lookups. Search quality depends on Bolagsverket's own indexing, and data reflects whatever they currently show — usually updated within 24 hours of official changes.

$0.003 per search. Checking 100 suppliers costs $0.30. Manual lookups on Bolagsverket's site take two to three minutes each. The actor does the same work in seconds.

Top comments (0)