# Zefix Company Register Scraper (Switzerland: Zefix, SHAB) (`swissalpinedata/swiss-company-register-scraper`) Actor

Search the Zefix federal commercial register by company name, or pull newly published SHAB commercial register notices (new registrations, mutations, deletions) from amtsblattportal.ch.

- **URL**: https://apify.com/swissalpinedata/swiss-company-register-scraper.md
- **Developed by:** [WebAlpine Studio](https://apify.com/swissalpinedata) (community)
- **Categories:** Business, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$5.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

## Zefix Company Register Scraper (Switzerland: Zefix, SHAB)

Look up Swiss companies in the federal commercial register index (Zefix) by name, or pull the latest commercial register notices (new registrations, mutations, deletions) from the Swiss Official Gazette of Commerce (SHAB, via amtsblattportal.ch). Both sources are official, public and free. The Actor turns them into clean, flat JSON records with UID, legal form, seat, canton, address, purpose, capital and registered persons.

### Why this actor

- Official sources only: the public Zefix REST API of the Federal Office of Justice and the SHAB publications on amtsblattportal.ch, the Swiss Official Gazette of Commerce.
- No login, no account and no browser. Public JSON and XML endpoints with polite delays and retries.
- Structured fields: UID, company name, legal form, seat, canton, address, purpose, capital and registered persons, parsed from the official publication XML.

### What it does

The Actor has two modes, chosen with the `mode` input.

**search**: queries Zefix (zefix.ch) for companies whose name contains the search term. Optional filters for canton, legal form and active companies only. Each hit comes with UID, legal form, seat, canton, status and the link to the cantonal register excerpt. With `fetchDetails` on, the Actor also fetches the registered address and the company purpose. Zefix returns at most 2000 hits per search, so narrow the name or use the filters for common terms.

**new-companies**: lists SHAB commercial register publications for a date range (default: the last 7 days), filtered by publication type and optionally by canton. The three types are HR01 (new registration), HR02 (mutation, for example a change of name, seat, capital or board) and HR03 (deletion). With `fetchDetails` on, the Actor parses the structured publication XML for every notice and returns the company name, UID, seat, legal form, address, purpose, nominal capital, the registered persons named in the notice and the full publication text.

### Why use it

Zefix is the searchable index of all Swiss commercial registers; SHAB is the daily, append-only feed of everything that changes in them. Together they cover the two typical jobs: looking up a company and monitoring a canton or the whole country for new companies. Use cases include lead generation on newly founded companies, KYC and supplier checks, tracking competitors' register changes, and enriching CRM data with UID, legal form and address. No login or browser is needed; the Actor talks to the public JSON and XML endpoints with polite delays and retries. The default Apify datacenter proxy is enough for both sources.

### Input

| Field | Type | Mode | Description |
| --- | --- | --- | --- |
| `mode` | string | both | `new-companies` (default) or `search`. |
| `name` | string | search | Company name or part of it. Required in search mode. |
| `legalForms` | array | search | Optional legal form filter (Zefix ids as strings, for example `"3"` for Aktiengesellschaft, `"4"` for GmbH, `"6"` for Verein, `"7"` for Stiftung). |
| `activeOnly` | boolean | search | Only companies that still exist. Default `true`. Set to `false` to include deleted companies. |
| `subRubrics` | array | new-companies | Publication types to return: `HR01`, `HR02`, `HR03`. Default `["HR01"]`. |
| `cantons` | array | both | 2-letter canton codes such as `ZH`, `BE`, `GE`. Empty means all of Switzerland. |
| `dateFrom`, `dateTo` | string | new-companies | Publication date range as `YYYY-MM-DD`. Default: last 7 days up to today. |
| `fetchDetails` | boolean | both | Fetch the Zefix detail record or the SHAB publication XML for each result. Default `true`. |
| `maxItems` | integer | both | Maximum number of records to output. Default `100`, maximum `5000`. |
| `proxyConfiguration` | object | both | Proxy settings. Default: Apify datacenter proxy. Required for new-companies mode on the platform because amtsblattportal.ch blocks direct connections from Apify's IP range. Search mode works without a proxy. |

Example, new companies in Zurich and Bern over three days:

```json
{
  "mode": "new-companies",
  "subRubrics": ["HR01"],
  "cantons": ["ZH", "BE"],
  "dateFrom": "2026-09-19",
  "dateTo": "2026-09-22",
  "maxItems": 100
}
```

Example, all active Aktiengesellschaften in Zurich whose name contains "Coop":

```json
{
  "mode": "search",
  "name": "Coop",
  "cantons": ["ZH"],
  "legalForms": ["3"],
  "maxItems": 100
}
```

### Output example

Every record has the same flat set of fields in both modes. Fields that the source does not provide are `null`. Legal forms are returned as their German register label so that they are consistent across the four national languages.

Record from `new-companies` mode (HR01, details fetched):

```json
{
  "source": "shab",
  "uid": "CHE-437.038.849",
  "name": "Soul&Science GmbH",
  "legal_form": "Gesellschaft mit beschränkter Haftung",
  "legal_form_code": "0107",
  "seat": "Sigriswil",
  "canton": "BE",
  "status": null,
  "url": "https://www.shab.ch/#!/gazette/publication/75c8e047-49aa-48ec-b9da-389c766cea59",
  "publication_id": "75c8e047-49aa-48ec-b9da-389c766cea59",
  "publication_number": "HR01-1006762303",
  "publication_date": "2026-09-22",
  "sub_rubric": "HR01",
  "language": "de",
  "address": "c/o Sabine Tilmann, Bäreneggweg 8, 3658 Merligen",
  "purpose": "Die Gesellschaft bezweckt das Anbieten und die Durchführung von Aus- und Weiterbildungen, Kursen, Seminaren und Coachings in verschiedenen Lebensbereichen, online und in Präsenz. Ferner bezweckt sie die Entwicklung und den Vertrieb von physischen und digitalen Produkten, die Herausgabe und den Vertrieb von Publikationen sowie den Handel mit Waren aller Art. (...)",
  "capital": 20000.0,
  "capital_currency": "CHF",
  "persons": [
    "Tilmann, Sabine Charlotte Caroline Elisabeth, von Sissach, in Merligen (Sigriswil), Gesellschafterin und Geschäftsführerin, mit Einzelunterschrift, mit 20 Stammanteilen zu je CHF 1'000.00",
    "Tilmann, Elisabeth, von Sissach, in Merligen (Sigriswil), mit Einzelunterschrift"
  ],
  "raw_text": "Soul&Science GmbH, in Sigriswil, CHE-437.038.849, c/o Sabine Tilmann, Bäreneggweg 8, 3658 Merligen, Gesellschaft mit beschränkter Haftung (Neueintragung). Statutendatum: 14.09.2026. Zweck: (...)",
  "scraped_at": "2026-09-22T20:43:14.251379+00:00"
}
```

Record from `search` mode (details fetched):

```json
{
  "source": "zefix",
  "uid": "CHE-238.945.329",
  "name": "Anlagestiftung der Migros-Pensionskasse",
  "legal_form": "Stiftung",
  "legal_form_code": "7",
  "seat": "Schlieren",
  "canton": "ZH",
  "status": "existierend",
  "url": "https://zh.chregister.ch/cr-portal/auszug/auszug.xhtml?uid=CHE-238.945.329",
  "publication_id": null,
  "publication_number": null,
  "publication_date": "2025-03-14",
  "sub_rubric": null,
  "language": null,
  "address": "Wiesenstrasse 15, 8952 Schlieren",
  "purpose": "Die Stiftung bezweckt die Anlage und die Verwaltung von Vermögen, welches ausschliesslich der Personalvorsorge dient.",
  "capital": null,
  "capital_currency": null,
  "persons": [],
  "raw_text": null,
  "scraped_at": "2026-09-22T20:42:43.931552+00:00"
}
```

Field notes:

- `legal_form_code` is the Zefix legal form id in search mode and the eCH-0097 code from the publication XML in new-companies mode (0101 Einzelunternehmen, 0103 Kollektivgesellschaft, 0104 Kommanditgesellschaft, 0106 Aktiengesellschaft, 0107 GmbH, 0108 Genossenschaft, 0109 Verein, 0110 Stiftung, 0111 branch of a foreign company, 0115 SICAV, 0117 public law institution, 0151 branch of a Swiss company).
- `publication_date` is the publication date of the notice in new-companies mode, and the date of the company's most recent SHAB publication in search mode.
- `capital` is the nominal capital as a number, `capital_currency` its currency. Both are only available from SHAB publications that state a capital (AG, GmbH, some cooperatives).
- `persons` are the registered persons exactly as printed in the notice, one string per person, including function and signing authority.

### Pricing

This Actor uses pay per result. You pay **USD 0.005 per company or register notice**, which is **USD 5.00 per 1,000 results**. There is no charge per run or per request, and a run that returns no results produces no result charges.

| Results | Price |
| --- | --- |
| 100 | USD 0.50 |
| 1,000 | USD 5.00 |
| 10,000 | USD 50.00 |

A weekly run that collects 300 new registrations in one canton costs USD 1.50. Set `maxItems` to cap the cost of a run.

### Legal

The Actor only reads publicly available data from zefix.ch and amtsblattportal.ch, which are operated by the Swiss federal administration. No login, paywall, CAPTCHA or rate limit is bypassed, and requests are spaced out politely.

SHAB publications contain the names of natural persons (board members, managing directors, owners). Publishing them is required by Swiss law, but what you do with the data afterwards is your own responsibility. Check the Swiss Federal Act on Data Protection (FADP) and the GDPR where applicable before storing or reusing personal data at scale.

### Limitations

- amtsblattportal.ch drops direct connections from the Apify platform's IP range, so new-companies mode needs the proxy setting left on. The default (Apify datacenter proxy) has been verified to work; residential Swiss exits work too.
- Zefix returns at most 2000 hits per search and does not support paging beyond that. Narrow the name or add a canton or legal form filter for common terms.
- Zefix's public detail endpoint has no capital field, so `capital` is always `null` in search mode.
- The registered persons are extracted from the free-text notice, not from a structured field, because the SHAB XML does not model them separately. Deletion notices (HR03) name no persons, and a few unusual notice layouts may yield an empty list.
- The company `purpose` is returned in the language of the notice (German, French or Italian), not translated.
- Legal form codes that never occurred in verified publications (for example Kommanditaktiengesellschaft, code 0105) fall back to a guess from the company name suffix, or `null`.
- `status` is only available from Zefix. SHAB records always have `status: null`; use `sub_rubric` (HR03 means the company was deleted).

### FAQ

**How do I monitor new companies every day?**
Schedule the Actor with `mode: "new-companies"`, leave `dateFrom` and `dateTo` empty (last 7 days) and deduplicate on `publication_id` or `uid` downstream. Publication numbers are strictly increasing, so you can also stop at the last number you have seen.

**Can I search Zefix by UID?**
Not in this version; search is by name only. To find a company by UID, search for its name and match the `uid` field.

**Why does the same company appear twice in new-companies mode?**
Each record is one publication, not one company. A company that was registered and then mutated within the date range produces one HR01 and one HR02 record with the same `uid`. Within one run there are never two records with the same `publication_id`.

**Can I combine both modes in one run?**
No, pick one mode per run. Run the Actor twice, or create two Tasks, if you need both.

### Changelog

- 0.2.x (2026-09-25): README with concrete pricing, `maxItems` now capped at 5000 per run.
- 0.2: proxy support (default Apify datacenter proxy) so that amtsblattportal.ch is reachable from the platform, server-side publication type and canton filters on amtsblattportal.ch, deterministic paging without duplicates, company name and legal form taken from the publication XML, numeric `capital` with `capital_currency`, new `language` and `legal_form_code` fields, Zefix canton and legal form filters, `activeOnly` option, input date validation, results pushed in batches while the run is in progress.
- 0.1: initial release, Zefix search and SHAB new-companies modes.

# Actor input Schema

## `mode` (type: `string`):

Search Zefix (the federal commercial register index) by company name, or list commercial register notices (new registrations, mutations, deletions) published in SHAB via amtsblattportal.ch for a date range.

## `name` (type: `string`):

Company name or part of it to look up in Zefix. Required in search mode, ignored in new-companies mode. Zefix returns at most 2000 matches per search.

## `legalForms` (type: `array`):

Optional legal form filter for the Zefix search. Leave empty for all legal forms.

## `activeOnly` (type: `boolean`):

Only return companies that still exist in the register. Untick to include deleted companies (status geloescht).

## `subRubrics` (type: `array`):

Which SHAB commercial register notices to return. HR01 = new registration, HR02 = mutation (change), HR03 = deletion.

## `cantons` (type: `array`):

Optional list of 2-letter canton codes (ZH, BE, GE, VD, ...). Applies to both modes. Leave empty for all of Switzerland.

## `dateFrom` (type: `string`):

Start of the publication date range, format YYYY-MM-DD. Defaults to 7 days before today.

## `dateTo` (type: `string`):

End of the publication date range, format YYYY-MM-DD. Defaults to today.

## `fetchDetails` (type: `boolean`):

Search mode: fetch the Zefix detail record for each company (address, purpose). New-companies mode: fetch and parse the publication XML for each notice (company name, UID, seat, legal form, address, purpose, capital, persons, full text). One extra request per record, so slower but much richer.

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

Maximum number of records to output, at most 5000 per run. You pay per record, so this also caps the cost of a run.

## `proxyConfiguration` (type: `object`):

amtsblattportal.ch (new-companies mode) blocks direct connections from the Apify platform's IP range, so a proxy is needed there; the default Apify datacenter proxy works. Zefix (search mode) works with or without a proxy.

## Actor input object example

```json
{
  "mode": "new-companies",
  "name": "Migros",
  "legalForms": [],
  "activeOnly": true,
  "subRubrics": [
    "HR01"
  ],
  "cantons": [],
  "fetchDetails": true,
  "maxItems": 100,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

All records returned by this run, as JSON.

# 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 = {
    "mode": "new-companies",
    "name": "Migros",
    "legalForms": [],
    "activeOnly": true,
    "subRubrics": [
        "HR01"
    ],
    "cantons": [],
    "fetchDetails": true,
    "maxItems": 100,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("swissalpinedata/swiss-company-register-scraper").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 = {
    "mode": "new-companies",
    "name": "Migros",
    "legalForms": [],
    "activeOnly": True,
    "subRubrics": ["HR01"],
    "cantons": [],
    "fetchDetails": True,
    "maxItems": 100,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("swissalpinedata/swiss-company-register-scraper").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 '{
  "mode": "new-companies",
  "name": "Migros",
  "legalForms": [],
  "activeOnly": true,
  "subRubrics": [
    "HR01"
  ],
  "cantons": [],
  "fetchDetails": true,
  "maxItems": 100,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call swissalpinedata/swiss-company-register-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,swissalpinedata/swiss-company-register-scraper"
        }
    }
}
```

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/CC42V1aCJYxn2Eixu/builds/e5KXhOBOKMOn4lwJr/openapi.json
